UART怎样保证数据的实时性与可靠性

在做主板与主板之间通信时,我们会遇到各种各样的通信方式与协议,看干扰差错等方面通常会使用CAN或者485协议。

都是电平的0与1传输,它们好在哪里呢?怎样才能UART有数据防错能力呢?

首先在硬件协议上,CAN,485使用的是差分信号,能有效抑制电磁干扰中的公模信号(很有针对性的设计)。对比UART我们要做的就是改变其对0电位以及1电位的定义,吸收差分信号的优点做改进。对于差模信号改怎么抑制的问题,可以吸收类似NEC码的方式,给0与1信号一个容差时间,存在较大的差模信号存在的情况下,对电平的传输也影响不大。

软件协议上,采取固定帧头帧尾+数据码正反码+CRC校验的方式。事实上一般的通信增加正反码固定帧头帧尾的方式已经很稳定了。只是在其基础上对数据进行了一个二次保险而已。

下面我们来看看UART通信中如何应用固定帧头帧尾的方式来防止数据出错。

//在发生中断接收时,会主动查询帧头帧尾中数据的正确性,以判断整个数据帧数据的可靠性,以选择接收。

if(RI)
     {
         REN = 0;
         rcvUartdata[rcvUartCount] = SBUF;                                                                                //接收数据到缓存
    
         if((rcvUartCount % 5 == 0)&&(rcvUartdata[rcvUartCount] != 0x55))                //检测帧头
         {
             rcvUartdata[rcvUartCount] = 0;
         }
         else if((rcvUartCount % 5 == 1)&&(rcvUartdata[rcvUartCount] != 0xaa))
         {
             rcvUartdata[rcvUartCount] = 0;
             rcvUartdata[rcvUartCount-1] = 0;
             rcvUartCount = rcvUartCount - 1;
         }
         else if((rcvUartCount % 5 == 4)&&(rcvUartdata[rcvUartCount] != 0xfa))        //检测帧尾
         {
             rcvUartdata[rcvUartCount] = 0;
             rcvUartdata[rcvUartCount-1] = 0;
             rcvUartdata[rcvUartCount-2] = 0;
             rcvUartdata[rcvUartCount-3] = 0;
             rcvUartdata[rcvUartCount-4] = 0;
             rcvUartCount = rcvUartCount - 4;
         }
         else
         {
             if(rcvUartCount % 5 == 4)
             {
                 revOkFlg = 1;
             }
             rcvUartCount ++;
         }
        
         if(rcvUartCount == 20)
         {
             rcvUartCount = 0;
         }
         RI = 0;
         REN = 1;
     }

//uart数据处理--------------------------------------------------------------------------------------------------

//数据解析时会进行二次确认,保证数据执行的正确性,避免错误数据及指令。
                 if(revOkFlg)
                 {
                     for(arrayCount = 0;arrayCount < 20; arrayCount += 5)
                     {
                         if((rcvUartdata[arrayCount] == 0x55)&&(rcvUartdata[arrayCount+1] == 0xaa)&&(rcvUartdata[arrayCount+4] == 0xfa))
                         {
                             instruct    = rcvUartdata[arrayCount+2];
                             ctrolData  = rcvUartdata[arrayCount+3];
                             crcData = rcvUartdata[arrayCount+4];   
                        
                             switch(instruct)
                             {
                                 case 0x10:    lackWaterState = ctrolData;            //1 en 0 dis 加水
                                                         break;
                                 case 0x20:    slaveState = ctrolData;                        //1 EN 0 dis 开/关机
                                                         break;
                                 default:    break;
                             }
                             instruct = 0;
                             ctrolData = 0;
                             crcData = 0;
                            
                             rcvUartdata[arrayCount] = 0;   
                             rcvUartdata[arrayCount+1] = 0;   
                             rcvUartdata[arrayCount+2] = 0;
                             rcvUartdata[arrayCount+3] = 0;   
                             rcvUartdata[arrayCount+4] = 0;
                         }
                     }
                     revOkFlg = 0;
                 }

SaiOneC -mcu交流群群二维码

吹牛、扯淡、交朋友请联系:18665321219

posted @ 2020-08-16 22:18  steven_lg  阅读(1453)  评论(1编辑  收藏  举报