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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM