本帖最后由 taijing33 于 2020-11-16 15:17 编辑
问题描述:使用了串口1和2,接受都是中断高优先级,发送没用中断。串口1连接的485设备,实际外部没用连接使用。串口2通过232连接的串口屏。问题出在串口2上。现在的问题是客户反应屏幕不能设置,显示正常,经判断就是串口2不能进入接受中断了,但是发送是正常的,就是假死了、。网上百度了有关信息。程序中也做了帧错误和数据溢出处理。我在办公室连续测了2天,各种乱按摔打,。就是不能重现客户遇到的问题。很是郁闷。但是客户反应的真真切切。以前在程序操作内部ee的时候关闭了中断,串口屏操作稍快就会,造成串口假死,但是我现在已经处理了。本以为解决了这个问题,没想到 到客户哪里,还是有这种情况。这种情况在客户哪里 也是几天有可能出现。但是一定会出现。
串口屏操作一次发给单片机的数据 一般不超过20个。
我的串口2接受处理逻辑。
大体意思是 串口有数据中断时,赋值Comdelay =2;一股脑的吧所有数据都接受进数组 Usart1_rbuff[100];数据一直有的话 Comdelay一直等于2; 然后再定时器中断中Comdelay --;定时器是10ms进一次中断。当Comdelay ==0认为没有数据了,这时候在接收到的数据中 找出 振头和帧尾 并进行CRC运算确认数据的正确。
下面是代码:
串口2和1的初始化代码
void config_uart1(void)
{
PMD1bits.RTCCMD = 1;
TRISCbits.TRISC7 = 1;
TRISCbits.TRISC6 = 0;
TXSTA1bits.TXEN = 1;
PIE1bits.TX1IE=0; //????TX
PIE1bits.RC1IE=1; //RX
//INITIALIZING EUART, 9 bits, 9600 baud rate
PIR1bits.TX1IF = 0; //Clear EUSART Transmit Interrupt Flag bit
PIR1bits.RC1IF = 0; //Clear EUSART Receive Interrupt Flag bit
TXSTA1 = 0x24; //Synchronous mode:Selects 9-bit transmission, High speed BRGH=1, Transmit enabled
RCSTA1 = 0x90; //Synchronous mode:Selects 9-bit reception, Continuous Receive Enable,
//Serial port enabled(configures RX/DT and TX/CK pins as serial port pins)
// SPBRG1 = BAUD9600; //11.0592MHz, BRGH=1, 9600bps
SPBRG1 = 51; //8MHz, BRGH=1, 9600bps
ODCON1 = 0;
ODCON2 = 0;
ODCON3 = 0;
PIE1 = 0x20; //Peripheral interrupt disable
PIE2 = 0; //Peripheral interrupt disable
PIE3 = 0x20; //enable RC2IE/TX2IE/RTCCIE
PIE4 = 0; //enable RC2IE/TX2IE/RTCCIE
PIE5 = 0; //enable RC2IE/TX2IE/RTCCIE
PIE6 = 0; //enable RC2IE/TX2IE/RTCCIE
IPR1 = 0x20; //All peripheral interrupt /time interrupt low priority
IPR2 = 0; //All peripheral interrupt /time interrupt low priority
IPR3 = 0x20; //All peripheral interrupt /time interrupt low priority
IPR4 = 0; //All peripheral interrupt /time interrupt low priority
IPR5 = 0; //All peripheral interrupt /time interrupt low priority
IPR6 = 0; //All peripheral interrupt /time interrupt low priority
IPR1bits.RC1IP = 1;
MAX485_EN = 0;
}
void config_uart2(void)
{
//??2
// PMD3=0xff; //外设模块禁止
// PMD2=0xff;//外设模块禁止
// PMD1=0x78;//外设模块禁止
// PMD0=0xc0;//外设模块禁止
//EECON2 = 0x55;
//EECON2 = 0xaa;
PMD1bits.RTCCMD = 1;
TRISGbits.TRISG2 = 1;
TRISGbits.TRISG1 = 0;
TXSTA2bits.TXEN = 1;
PIE3bits.TX2IE=0; //??TX
//INITIALIZING EUART, 9 bits, 9600 baud rate
PIR3bits.TX2IF = 0; //Clear EUSART Transmit Interrupt Flag bit
PIR3bits.RC2IF = 0; //Clear EUSART Receive Interrupt Flag bit
TXSTA2 = 0x24; //Synchronous mode:Selects 9-bit transmission, High speed BRGH=1, Transmit enabled
RCSTA2 = 0x90; //Synchronous mode:Selects 9-bit reception, Continuous Receive Enable,
//Serial port enabled(configures RX/DT and TX/CK pins as serial port pins)
// SPBRG2 = BAUD9600; //11.0592MHz, BRGH=1, 9600bps
SPBRG2 = 51; //8MHz, BRGH=1, 9600bps
ODCON1 = 0;
ODCON2 = 0;
ODCON3 = 0;
PIE1 = 0x20; //Peripheral interrupt disable
PIE2 = 0; //Peripheral interrupt disable
PIE3 = 0x20; //enable RC2IE/TX2IE/RTCCIE
PIE4 = 0; //enable RC2IE/TX2IE/RTCCIE
PIE5 = 0; //enable RC2IE/TX2IE/RTCCIE
PIE6 = 0; //enable RC2IE/TX2IE/RTCCIE
IPR1 = 0x20; //All peripheral interrupt /time interrupt low priority
IPR2 = 0; //All peripheral interrupt /time interrupt low priority
IPR3 = 0x20; //All peripheral interrupt /time interrupt low priority
IPR4 = 0; //All peripheral interrupt /time interrupt low priority
IPR5 = 0; //All peripheral interrupt /time interrupt low priority
IPR6 = 0; //All peripheral interrupt /time interrupt low priority
MAX485_EN2 = 0;
}
中断中的数据接受处理
void interrupt my_isr(void){
static u8 rdata = 0;
if(PIR3bits.RC2IF &&PIE3bits.RC2IE )
{
rdata = RCREG2;
if(Rx_en && RxCounter1 < USART1_R_LEN)
{
Usart1_rbuff[RxCounter1++] = RCREG2;
if(RxCounter1>=USART1_R_LEN)
{
Rx_en = 0;
Usart1_r_finish = 1;
}
}
Comdelay = 2; //20ms?????????????????
}
if(PIR1bits.RC1IF &&PIE1bits.RC1IE)
{
rdata = RCREG;
if(Rx_en0 && RxCounter < USART_R_LEN)
{
Usart_rbuff[RxCounter++] = RCREG;
if(RxCounter>=USART_R_LEN)
{
Usart_r_finish = 1;
//RxCounter = 0;
//Rx_en0 = 0;
}
}
Comdelay0 = 2; //20ms?????????????????
}
//下面这部分代码是以前别的功能忘了删除了,但是我觉得应该没有对串口假死有影响。
//下面这部分代码是以前别的功能忘了删除了,但是我觉得应该没有对串口假死有影响。
//下面这部分代码是以前别的功能忘了删除了,但是我觉得应该没有对串口假死有影响。
if(INTCONbits.INT0IF)
{
INTCONbits.INT0IF = 0;
// if(WATER)
{
// Water_pulse = 0;
if(dat_set_water.water_chicken <= 65534)
dat_set_water.water_chicken+=1;
}
}
}
主程序while1中的串口接受数据处理
//当发生帧错误或者溢出时,初始化串口
if(RCSTA2bits.OERR || RCSTA2bits.FERR)
{
RCSTA2bits.CREN = 0;
config_uart2();
}
if(RCSTA1bits.OERR || RCSTA1bits.FERR)
{
RCSTA1bits.CREN = 0;
config_uart1();
}
if(Usart1_r_finish) //
{
Rx_en = 0; //暂时拒绝接受新数据
Usart1_r_finish = 0;
com_pro(); //处理数据
RxCounter1 = 0;
for(i=0;i<USART1_R_LEN;i++)
{
Usart1_rbuff = 0;
}
Rx_en = 1;//重新使能接受
}
、、、、、、、、、、、、、、、、、、、、
这是定时器中累减Comdelay。当 Comdelay==0就认为一帧数据结束,置位接受完成标志Usart1_r_finish ==1;
if(INTCONbits.TMR0IE && INTCONbits.TMR0IF) {
// portValue++;
TMR0L += 0x63; //10ms timer
jiffies += 10;
INTCONbits.TMR0IF = 0; // clear this interrupt condition
if(Comdelay)
{
Comdelay--;
if(Comdelay==0)
{
Usart1_r_finish = 1;
Rx_en = 0;
}
}
if(Comdelay0)
{
Comdelay0--;
if(Comdelay0==0)
{
// Rx_en0 = 0;
Usart_r_finish = 1;
}
}
、、、、、、、、、、、、、、、、、
恳请大侠出手相救,或加我微信13355039693.问题解决定当1000元酬谢。。
|