搜索

有偿请教关于18F66k22串口假死问题。

[复制链接]
47|3
 楼主 | 2020-11-16 15:01 | 显示全部楼层 |阅读模式
本帖最后由 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元酬谢。。


使用特权

评论回复
| 2020-11-16 15:49 | 显示全部楼层
中断中的变量是不是定义为Volitle了?
是不是外接个串口,用PC串口工具进行压力测试,先把现象复现出来才好调试。

使用特权

评论回复
| 2020-11-16 16:15 | 显示全部楼层
串口接收中断接收到的数据,没有二级缓冲吗?在接收到一帧数据后,主程序在处理过程中,又来数据如何处理?

使用特权

评论回复
 楼主 | 2020-11-16 17:18 | 显示全部楼层
gx_huang 发表于 2020-11-16 16:15
串口接收中断接收到的数据,没有二级缓冲吗?在接收到一帧数据后,主程序在处理过程中,又来数据如何处理? ...

再来新的数据会进入中断。不做进入接受数组。我考虑到这个问题。应该不会造成串口假死。

使用特权

评论回复
扫描二维码,随时随地手机跟帖
您需要登录后才可以回帖 登录 | 注册

本版积分规则

我要发帖 我要提问 投诉建议 申请版主

快速回复

您需要登录后才可以回帖
登录 | 注册
高级模式

论坛热帖

在线客服 快速回复 返回顶部 返回列表