打印
[PIC®/AVR®/dsPIC®产品]

PIC16f1947 串口通讯异常

[复制链接]
5882|18
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
laocuo1142|  楼主 | 2025-2-18 16:00 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
最近我在做一个项目遇到一个串口异常问题,我用电脑连接的时候,串口通讯时间间隔10ms都是没有问题,最多出现乱码,因为是用485,乱码比较正常,停止10ms发送切换50ms能返回正常的数据。但是我多个单片机通讯的时候,总会有单片机串口崩溃现象,其他操作正常,就是串口没有数据反馈。在串口中断做了帧错误和溢出错误的处理。串口初始化代码
void uart_init(UINT8 brg)
{     
    TX2STA &= ~(0x01 << 4); //异步串口
    //SYNC = 0;   //异步串口
    if(BRG_9600 == brg)
    {
        TX2STA &= ~(0x01 << 2); //低速波特率
        //BRGH = 0;   //低速波特率
        BAUD2CON &= ~(0x01 << 3); //使用8位波特率发生器
        //BRG16 = 0;  //使用8位波特率发生器
        SP2BRGL = 51;//9600波特率
    }
    else if(BRG_115200 == brg)
    {
        TX2STA |= (0x01 << 2); //高速波特率
        //BRGH = 1;   //高速波特率
        BAUD2CON |= (0x01 << 3);    //使用16位波特率发生器
        //BRG16 = 1;  //使用16位波特率发生器
        SP2BRGL = 68;//115200波特率
        SP2BRGH = 0;
    }
    else
    {
        TX2STA &= ~(0x01 << 2); //低速波特率
        BAUD2CON &= ~(0x01 << 3); //使用8位波特率发生器
        SP2BRGL = 51;//9600波特率
    }
   
    TRISG1 = 0;     //IO配置 TX2      
    TRISG2 = 1;     //IO配置 RX2   
   
    ANSG2 = 0;    //必配
   
    RC2STA |= (0x01 << 7);   //使能串口
    //SPEN = 1;   //使能串口
    TX2STA &= ~(0x01 << 6); //发送8位数据位
    //TX9 = 0;    //发送8位数据位
    //CKTXP = 0;  //发送数据极性 不翻转
    RC2STA &= ~(0x01 << 6); //接收8位数据位
    //RX9 = 0;    //接收8位数据位
   
    RC2STA |= (0x01 << 4); //使能接收
    //CREN = 1;   //使能接收
    //RC2IF = 0;
   
    RC2IE = 1;  //接收使能
    //PIE4 |= (0x01 << 5);
    //INTCON |= (0x03 << 6);
    RC2STAbits.CREN=1;//激活接收
    PEIE = 1;   //外设中断使能
    GIE = 1;    //总中断使能  
   
   
    //RC2STA &= ~(0x01 << 4); //使能接收
    //RC2STA &= ~(0x01 << 7);   //使能串口
    //RC2STA |= (0x01 << 4); //使能接收
    //RC2STA |= (0x01 << 7);   //使能串口
}
复制代码


串口中断:
if (RC2IE && RC2IF)
    {  
       // backlight_Dim(3);
       // RC2IF = 0;
         if(RC2STAbits.FERR)//监测是否有帧错误         
        {            
            err=RC2REG;
            return;
        }         
        if(RC2STAbits.OERR)         
        {            
            RC2STAbits.CREN=0;               
            RC2STAbits.CREN=1;   //接收模块被复位重置,OERR清零
            return;
        }
        
        
        //err = RC2STA & 0x04;
        //err = FERR;
        //RC2IF = 0;
        ch = RC2REG;
        
        
        if(RC2IF)
        {
           RC2IF = 0;
        }
        
        
        if(Ccnt > 25)
        {
            Ccnt = 0;
            return;
        }
        if(ch == SOI0)
        {
            Ccnt = 0;
            SOI_Flag = 1;
            return;
        }
        if(SOI_Flag == 1)               //检测是否是包头
        {  
            SOI_Flag = 0;
            if(ch == SOI1)
            {
                Recstatu = 1;
                Ccnt = 0;
                PackerFlag = 0;
                return;
            }
            else
            {              
                if(Recstatu == 1)              //是否处于接收数据包状态
                {
                    RxBuf[Ccnt++] = SOI0;
                }
            }
        }
        
        if(ch == EOI0)
        {
            EOI_Flag = 1;
            return;
        }
        if(EOI_Flag == 1)               //检测是否是包头
        {  
            EOI_Flag = 0;
            if(ch == EOI1)               //检测是否是包尾
            {
                Recstatu = 0;
               
                PackerFlag = 1;         //用于告知系统已经接收到一个完整的数据包
                GIE = 0;
                return ;
            }
            else
            {               
                if(Recstatu == 1)              //是否处于接收数据包状态
                {
                    RxBuf[Ccnt++] = EOI0;
                }
            }
       }
        if(Ccnt > 25)
        {
            Ccnt = 0;
            return;
        }
      if(Recstatu == 1)              //是否处于接收数据包状态
      {
            RxBuf[Ccnt++] = ch;
      }
}
复制代码

使用特权

评论回复
沙发
锵才才| | 2025-2-20 10:54 | 只看该作者
中断服务程序除了处理串口中断外是否还要处理其他中断?

使用特权

评论回复
板凳
幸福小强| | 2025-2-21 12:18 | 只看该作者
从你的描述和代码中,可以看出你在使用RS-485进行串口通信,并且在多个单片机通讯时遇到了串口崩溃的问题。这里有几个可能的原因和建议,希望能帮助你解决问题:

‌波特率设置‌:

确保所有单片机和电脑端的波特率完全一致。任何微小的差异都可能导致通信错误或串口崩溃。
你提到在9600波特率下使用8位波特率发生器,而在115200波特率下使用16位波特率发生器。请确认这种设置是否在所有单片机上都一致,并且与你的实际需求相符。
‌串口缓冲区溢出‌:

当多个单片机同时发送数据时,如果接收端的处理速度不够快,可能会导致串口缓冲区溢出。你已经在中断中处理了溢出错误(OERR),但可能需要进一步优化接收和处理数据的逻辑,确保数据不会被丢失或覆盖。
考虑增加接收缓冲区的大小,或者优化中断处理函数,使其能更快地处理接收到的数据。
‌硬件问题‌:

RS-485总线是差分信号,对线路的质量、终端电阻以及节点的数量都有一定要求。请检查你的线路连接是否可靠,终端电阻是否匹配(通常在总线两端各接一个120Ω的电阻),以及节点数量是否超过了RS-485总线的承载能力。
检查是否有单片机或线路上的其他设备出现了硬件故障,如短路、断路或元件损坏。
‌中断处理‌:

你的中断处理函数似乎没有清除RC2IF标志位。在每次进入中断后,都应该清除这个标志位,否则中断可能会不断触发,导致程序异常。
在处理完接收到的数据后,确保退出中断前没有其他未处理的错误或状态需要清除。

使用特权

评论回复
地板
幸福小强| | 2025-2-21 12:18 | 只看该作者
‌软件优化‌:

考虑在发送和接收数据时增加一些同步机制,如使用握手协议或确认/应答机制,以确保数据的完整性和正确性。
检查是否有其他任务或中断与串口通信产生了冲突,导致串口崩溃。优化任务调度和中断优先级设置,确保串口通信能够顺利进行。
‌调试和测试‌:

使用示波器或逻辑分析仪等工具监测串口线上的信号质量,检查是否有异常波形或噪声干扰。
在单片机上增加调试输出,如通过LED闪烁或输出调试信息到另一个串口,以便跟踪程序执行情况和串口状态。

使用特权

评论回复
5
玛尼玛尼哄| | 2025-2-22 12:52 | 只看该作者
解决了没,这系列没支持MCC吧

使用特权

评论回复
6
狗啃模拟| | 2025-2-23 00:01 | 只看该作者
实现主从模式,确保只有一个设备在发送数据。

使用特权

评论回复
7
花间一壶酒sd| | 2025-2-23 00:11 | 只看该作者
在发送数据前检测总线是否空闲,避免冲突。

使用特权

评论回复
8
nuan11nuan| | 2025-3-7 13:24 | 只看该作者
485总线是半双工通讯,多个设备同时发送数据会导致冲突,进而引发帧错误或溢出错误。

使用特权

评论回复
9
gongqijuns| | 2025-3-7 14:32 | 只看该作者
看你代码来说,建议增加超时机制,在发送数据前检测总线是否空闲,避免冲突

使用特权

评论回复
10
gra22ce| | 2025-3-7 15:43 | 只看该作者
你是不是可以使用硬件流控?如果硬件支持,启用 RTS/CTS 流控。

使用特权

评论回复
11
pe66ak| | 2025-3-7 16:55 | 只看该作者
一般建议优化发送间隔,增加发送间隔,避免多个设备同时发送

使用特权

评论回复
12
hight1light| | 2025-3-7 19:15 | 只看该作者
中断处理代码可能未完全清除标志位或未正确处理错误状态,导致中断被阻塞

使用特权

评论回复
13
hight1light| | 2025-3-7 20:25 | 只看该作者
确保在中断中清除所有相关标志位(如 RC2IF)。在帧错误或溢出错误处理后,重新激活接收。

使用特权

评论回复
14
canfeil| | 2025-3-7 22:54 | 只看该作者
多个单片机的波特率设置不一致,可能导致通讯错误。查所有单片机的波特率设置,确保一致。使用示波器或逻辑分析仪测量实际波特率,验证是否匹配。

使用特权

评论回复
15
一切D都好| | 2025-3-8 09:16 | 只看该作者
电源噪声可能导致通讯异常,尤其是在多设备共用电源时。在 485 总线上增加终端电阻(通常为 120Ω)。使用独立的电源或稳压器为每个设备供电。在电源引脚附近添加滤波电容(如 0.1µF 陶瓷电容和 10µF 电解电容)。

使用特权

评论回复
16
yuliangren| | 2025-3-8 11:45 | 只看该作者
数据包处理逻辑可能导致缓冲区溢出或状态机异常。增加缓冲区溢出检查,确保 Ccnt 不超过缓冲区大小。优化状态机逻辑,确保在异常情况下能正确恢复。

使用特权

评论回复
17
suiziq| | 2025-3-8 14:28 | 只看该作者
硬件连接不良或 485 芯片故障可能导致通讯异常。可以检查 485 芯片的电源和地线连接。更换485芯片,排除硬件故障。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1281

主题

6001

帖子

14

粉丝