串口協議以(yǐ)及串口二進製整數據包解析
以串口作為傳輸媒介,介紹下怎樣來發送接收(shōu)一個完整的數據包(bāo)。過程涉及到封包(bāo)與解包。設計一個(gè)良好的包傳輸機製很有利於數據傳輸的穩(wěn)定性以(yǐ)及正確性。串口隻是一種傳輸媒介,這種包機製同時也可以用於SPI,I2C的總線下的數據傳輸。在單片機通信係統(多機通信以及PC與單片機通信)中,是很(hěn)常見的問題。
一、根據幀頭幀尾或者幀長檢測一個數據幀
1、幀頭+數據+校驗+幀尾
這是一個典型的方案,但是對幀頭與幀尾在設計的時候都要注意,也就是說幀頭、幀尾不能在所傳輸的數據域中出現,一旦出現可能就被誤判。如果(guǒ)用中斷來接收(shōu)的話,程序基本可以這麽實現:
unsigned char recstatu;//表(biǎo)示是否處於一個正在接收數據包(bāo)的狀態
unsigned char ccnt; //計數
unsigned char packerflag;//是否接收到一個完整的數據包標誌
unsigned char rxbuf[100];//接收數據的緩衝區
void UartHandler()
{
unsigned char tmpch;
tmpch = UARTRBR;
if(tmpch 是包頭) //檢測(cè)是否是包頭
{
recstatu = 1;
ccnt = 0 ;
packerflag = 0;
return ;
}
if(tmpch是包尾) //檢測(cè)是否是包尾
{
recstatu = 0;
packerflag = 1; //用於告知係統已(yǐ)經接收到(dào)一個(gè)完整的數據包
return ;
}
if(recstatu ==1) //是否處於接收數據包狀(zhuàng)態(tài)
{
rxbuf[ccnt++] = tmpch;
}
}
上麵也(yě)就(jiù)是接收一(yī)個數據包,但是再次提醒,包頭和包尾不能在數據域中出現,一旦出現將會出現誤判。另外一個。數據的(de)校(xiào)驗算法是很必要的,在數據傳輸中,由於受到幹擾,很難免有時出現數據錯誤,加上校驗碼可在發(fā)現數據傳輸錯誤時,可以要求數據的另一方重新發送,或是進行(háng)簡(jiǎn)單的丟棄(qì)處理(lǐ)。校(xiào)驗算法不一定要很(hěn)複雜,普通的(de)加和,異或,以及循(xún)環冗餘都是(shì)可以的。我(wǒ)上麵的接收程序在接收數據時,已經將(jiāng)包頭和包尾去掉,這些(xiē)可以根(gēn)據自(zì)己的需求加上,關鍵是要理解原理。
上述包協議出現(xiàn)了以下(xià)的幾(jǐ)種(zhǒng)變種:
1.1 幀頭(tóu)+數據長度+數據+校驗值
1.2包長(zhǎng)+校驗值
上麵兩種其實都是知道了數據包的長度,然後根據接收字節的長度來判斷(duàn)一個完整(zhěng)的數據包。例(lì)如,定義一個數據包的長度為256字節,那我們就可(kě)以一直(zhí)接收(shōu),直到接收到256個字節,就認為是一個數據包。但是,會不(bú)會存在問(wèn)題呢?比如說從機向主機發(fā)送數據(jù),發送了一半,掉電,重啟,開機後繼續(xù)發送,這很明顯接收到的數據(jù)就(jiù)不對了,所以此時很有必要定義一個超限時間,比如我們可以維護下麵這樣的一個結構體。
struct uartrd{
char rd[ 256];
unsigned int timeout;
}
成員(yuán)變(biàn)量rd用來存放接收到的數據字節;成員變量timeout用來維護超時值(zhí),這(zhè)裏主(zhǔ)要討論(lùn)這個(gè)。這個數(shù)值怎(zěn)麽維護呢,可以用一個定時器來維護,以可以放在普通的滴答中斷裏麵來(lái)維護,也可以根據係統(tǒng)運行一(yī)條指令的周期,在自己(jǐ)的循環中來維(wéi)護,給其設置個初值,比如(rú)說100,當有第一個數(shù)據到來以後,timeout在指定的時間就會減少1,減少到0時,就認為超時,不論是否接收到足夠的數據,都應該拋棄。
二、根(gēn)據接收超時來判(pàn)斷一個數據包
2.1 數據+校(xiào)驗
核心思想是如果在達到一定的時間沒有接受到數據,就認為數據包(bāo)接收完成(chéng)。modbus協(xié)議裏就有通過時間間隔來判斷幀結束(shù)的。具體(tǐ)實現是要使用一個定時器,在接收到第一個數據時候,開啟定時器,在接收到(dào)一個數據時候,就將定時器清零,讓定時器重新開始計時,如果設定的超時時間到(超時時間長度可以設置為5個正常接(jiē)收的周期),則認為在這一段時間內沒(méi)有接受到新的數據,就認為接收到一個完整的數據包了。
進行一(yī)個簡單的小的總結,上述幾種方法都還是較為常用的(de),在具體的實現上,可以根據(jù)具體的實際情況,設計出具(jù)體的通(tōng)訊協議。數據校驗位(wèi),有時候感覺不出來其重要性,但是一定要(yào)加上,對數據進(jìn)行一個相關的(de)驗證還(hái)是必要的。現在很在MCU都帶有FIFO,DMA等功能(néng),所以有時候利用(yòng)上這些特性,可以設計出更好的通訊方式。有的人問在接受串口(kǒu)數(shù)據時候是應該中斷一(yī)次接收一個,還是進入中斷後接收一段數據呢,我認為應該中斷接收一個,因為(wéi)CPU是很快的,至少對於串口是這樣,在接(jiē)受每個數(shù)據的間隔期間,處理(lǐ)器還是可以做些(xiē)其他工作的。在多線程中,那就可以直接建立一個數據接收線程。
- 上一篇:串口通信的MPU姿態傳感器數據包解析技術 2018/1/19
- 下一(yī)篇:Valve拆開賣HTC Vive的雙跟蹤基站,HTC失去絕對 2017/12/15
