PIC16f1947 串口通讯异常

2019-03-25 18:50发布

您们好,最近我在做一个项目遇到一个串口异常问题,我用电脑连接的时候,串口通讯时间间隔10ms都是没有问题,最多出现乱码,因为是用485,乱码比较正常,停止10ms发送切换50ms能返回正常的数据。但是我多个单片机通讯的时候,总会有单片机串口崩溃现象,其他操作正常,就是串口没有数据反馈。在串口中断做了帧错误和溢出错误的处理。串口初始化代码
  1. void uart_init(UINT8 brg)
  2. {     
  3.     TX2STA &= ~(0x01 << 4); //异步串口
  4.     //SYNC = 0;   //异步串口
  5.     if(BRG_9600 == brg)
  6.     {
  7.         TX2STA &= ~(0x01 << 2); //低速波特率
  8.         //BRGH = 0;   //低速波特率
  9.         BAUD2CON &= ~(0x01 << 3); //使用8位波特率发生器
  10.         //BRG16 = 0;  //使用8位波特率发生器
  11.         SP2BRGL = 51;//9600波特率
  12.     }
  13.     else if(BRG_115200 == brg)
  14.     {
  15.         TX2STA |= (0x01 << 2); //高速波特率
  16.         //BRGH = 1;   //高速波特率
  17.         BAUD2CON |= (0x01 << 3);    //使用16位波特率发生器
  18.         //BRG16 = 1;  //使用16位波特率发生器
  19.         SP2BRGL = 68;//115200波特率
  20.         SP2BRGH = 0;
  21.     }
  22.     else
  23.     {
  24.         TX2STA &= ~(0x01 << 2); //低速波特率
  25.         BAUD2CON &= ~(0x01 << 3); //使用8位波特率发生器
  26.         SP2BRGL = 51;//9600波特率
  27.     }
  28.    
  29.     TRISG1 = 0;     //IO配置 TX2      
  30.     TRISG2 = 1;     //IO配置 RX2   
  31.    
  32.     ANSG2 = 0;    //必配
  33.    
  34.     RC2STA |= (0x01 << 7);   //使能串口
  35.     //SPEN = 1;   //使能串口
  36.     TX2STA &= ~(0x01 << 6); //发送8位数据位
  37.     //TX9 = 0;    //发送8位数据位
  38.     //CKTXP = 0;  //发送数据极性 不翻转
  39.     RC2STA &= ~(0x01 << 6); //接收8位数据位
  40.     //RX9 = 0;    //接收8位数据位
  41.    
  42.     RC2STA |= (0x01 << 4); //使能接收
  43.     //CREN = 1;   //使能接收
  44.     //RC2IF = 0;
  45.    
  46.     RC2IE = 1;  //接收使能
  47.     //PIE4 |= (0x01 << 5);
  48.     //INTCON |= (0x03 << 6);
  49.     RC2STAbits.CREN=1;//激活接收
  50.     PEIE = 1;   //外设中断使能
  51.     GIE = 1;    //总中断使能  
  52.    
  53.    
  54.     //RC2STA &= ~(0x01 << 4); //使能接收
  55.     //RC2STA &= ~(0x01 << 7);   //使能串口
  56.     //RC2STA |= (0x01 << 4); //使能接收
  57.     //RC2STA |= (0x01 << 7);   //使能串口
  58. }
复制代码

串口中断:
  1. if (RC2IE && RC2IF)
  2.     {  
  3.        // backlight_Dim(3);
  4.        // RC2IF = 0;
  5.          if(RC2STAbits.FERR)//监测是否有帧错误         
  6.         {            
  7.             err=RC2REG;
  8.             return;
  9.         }         
  10.         if(RC2STAbits.OERR)         
  11.         {            
  12.             RC2STAbits.CREN=0;               
  13.             RC2STAbits.CREN=1;   //接收模块被复位重置,OERR清零
  14.             return;
  15.         }
  16.         
  17.         
  18.         //err = RC2STA & 0x04;
  19.         //err = FERR;
  20.         //RC2IF = 0;
  21.         ch = RC2REG;
  22.         
  23.         
  24.         if(RC2IF)
  25.         {
  26.            RC2IF = 0;
  27.         }
  28.         
  29.         
  30.         if(Ccnt > 25)
  31.         {
  32.             Ccnt = 0;
  33.             return;
  34.         }
  35.         if(ch == SOI0)
  36.         {
  37.             Ccnt = 0;
  38.             SOI_Flag = 1;
  39.             return;
  40.         }
  41.         if(SOI_Flag == 1)               //检测是否是包头
  42.         {  
  43.             SOI_Flag = 0;
  44.             if(ch == SOI1)
  45.             {
  46.                 Recstatu = 1;
  47.                 Ccnt = 0;
  48.                 PackerFlag = 0;
  49.                 return;
  50.             }
  51.             else
  52.             {              
  53.                 if(Recstatu == 1)              //是否处于接收数据包状态
  54.                 {
  55.                     RxBuf[Ccnt++] = SOI0;
  56.                 }
  57.             }
  58.         }
  59.         
  60.         if(ch == EOI0)
  61.         {
  62.             EOI_Flag = 1;
  63.             return;
  64.         }
  65.         if(EOI_Flag == 1)               //检测是否是包头
  66.         {  
  67.             EOI_Flag = 0;
  68.             if(ch == EOI1)               //检测是否是包尾
  69.             {
  70.                 Recstatu = 0;
  71.                
  72.                 PackerFlag = 1;         //用于告知系统已经接收到一个完整的数据包
  73.                 GIE = 0;
  74.                 return ;
  75.             }
  76.             else
  77.             {               
  78.                 if(Recstatu == 1)              //是否处于接收数据包状态
  79.                 {
  80.                     RxBuf[Ccnt++] = EOI0;
  81.                 }
  82.             }
  83.        }
  84.         if(Ccnt > 25)
  85.         {
  86.             Ccnt = 0;
  87.             return;
  88.         }
  89.       if(Recstatu == 1)              //是否处于接收数据包状态
  90.       {
  91.             RxBuf[Ccnt++] = ch;
  92.       }
  93. }
复制代码

此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。