加入星計劃,您可以享受以下權益:

  • 創(chuàng)作內容快速變現(xiàn)
  • 行業(yè)影響力擴散
  • 作品版權保護
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質創(chuàng)作者
  • 5000+ 長期合作伙伴
立即加入
  • 正文
    • 一、為什么串口接收的數(shù)據(jù)需要處理
    • 二、串口接收重點關注的幾個標志
    • 三、常用的幾種數(shù)據(jù)處理方法
    • 四、總結
  • 推薦器件
  • 相關推薦
  • 電子產(chǎn)業(yè)圖譜
申請入駐 產(chǎn)業(yè)圖譜

單片機串口接收的幾種常用的數(shù)據(jù)處理方法

03/12 12:44
6585
閱讀需 8 分鐘
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點資訊討論

一、為什么串口接收的數(shù)據(jù)需要處理

我們在做項目的時候經(jīng)常會用到串口,當我們用串口和別的設備通訊的時候就需要嚴格遵循通訊協(xié)議,然而,僅僅是遵循通訊協(xié)議是不夠的,因為單片機串口受到別的信號干擾的時候,容易出現(xiàn)數(shù)據(jù)錯誤,特別是串口發(fā)送的第一個字節(jié)和最后一個字節(jié)。一旦出現(xiàn)這種情況,設備之間的通訊可能會受到影響,甚至會導致系統(tǒng)癱瘓。另外,串口收到數(shù)據(jù)的時候,我們也需要判斷一幀數(shù)據(jù)的長度,特別是指令發(fā)送比較頻繁的時候。因此,串口在接收到數(shù)據(jù)之后應該先進行數(shù)據(jù)處理,再執(zhí)行命令,這樣能夠增強產(chǎn)品的穩(wěn)定性。

二、串口接收重點關注的幾個標志

為了保證通訊的穩(wěn)定性,一般的通訊協(xié)議會加入幀頭、幀尾、數(shù)據(jù)長度、校驗這四個標志中的一個或多個。它們的作用如下:

1、幀頭:串口發(fā)送數(shù)據(jù)的第一個字節(jié)是最容易出錯的,如果你把重要的指令放在第一個字節(jié),一旦出現(xiàn)錯誤,可能會使從機執(zhí)行錯誤的操作。而幀頭能夠有效規(guī)避這個問題。

2、幀尾:和幀頭類似,幀尾也能避免最后一個字節(jié)出錯,同時,它也可以作為接收端接收完成的標志。

3、數(shù)據(jù)長度:它可以作為接收端接收完成的標志。有時也能作為判斷數(shù)據(jù)是否正確的標志。

4、校驗:能夠有效避免校驗以外的所有數(shù)據(jù)的錯誤,但是校驗正確不代表數(shù)據(jù)一定沒有出錯,每種校驗方式都有一定的缺陷。

幀頭、幀尾、數(shù)據(jù)長度和校驗,這四種標志加起來之后能夠大大的增強數(shù)據(jù)傳輸的穩(wěn)定性,但不是每個通訊協(xié)議都會包含以上四個標志,可能只會用到其中的一兩個。因為如果要發(fā)送的主要數(shù)據(jù)本身就比較長,加上這個幾個標志之后會更長,這對于那種傳輸速度慢、傳輸數(shù)據(jù)時間長、傳輸指令頻繁處理速度慢的設備來說,較長的指令可能會影響工作效率。具體我就不多說了,我今天主要講的是接收數(shù)據(jù)的處理方法,大家根據(jù)自己的協(xié)議選擇合適的處理方法就行了。

三、常用的幾種數(shù)據(jù)處理方法

1、判斷幀頭:串口接收到第一個數(shù)據(jù)之后先判斷是否是幀頭,如果幀頭正確就存起來繼續(xù)收,反之則丟掉繼續(xù)等幀頭。示例代碼片段如下:

if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中斷
{
	Res = USART_ReceiveData(USART1);//讀取接收到的數(shù)據(jù),同時也清除了中斷標志位
		   
	USART_RX_BUF[USART_RX_STA ++] = Res;
	if(USART_RX_BUF[0] != 0xA5 && USART_RX_STA == 1)
	{//幀頭錯誤
	     USART_RX_STA = 0;//重新接收
	}
	if(USART_RX_STA >= USART_RX_Len)
	{//接收完成
	    USART_RX_STA = 0;
	    USART_RXHANDLE_FLAG = 1;
	}
}

這種處理方法能夠有效避免第一個字節(jié)出錯的問題,我就試過一次主設備那邊傳過來的數(shù)據(jù)幀頭前面多了一個字節(jié)(可能是剛開始傳輸?shù)臅r候電壓不穩(wěn)定產(chǎn)生的紋波),用這種方法就能夠之間把第一個錯誤的數(shù)據(jù)丟掉,從正確的幀頭開始接收。但是這種方法不能夠檢查幀頭后面的數(shù)據(jù)是否正確。

2、判斷幀尾:可以把幀尾作為一幀數(shù)據(jù)接收完成的標志。另外,當接收緩存存了多個指令的時候,幀尾能夠幫助我們在一堆數(shù)據(jù)中區(qū)分出哪些數(shù)據(jù)是同一個指令的。當然,如果僅僅是區(qū)分數(shù)據(jù)用幀頭也可以。不過這種辦法必須保證幀尾和其他數(shù)據(jù)不一樣,不然就會出現(xiàn)錯誤的判斷。所以有些人為了避免這個問題會用兩個字節(jié)作為幀尾,不過這樣一來,數(shù)據(jù)長度就更大了,影響通訊效率。

3、根據(jù)數(shù)據(jù)長度判斷是否完成接收:可以通過數(shù)據(jù)長度判斷接收是否完成。如果協(xié)議里面的指令長度不是統(tǒng)一的,我們就不能根據(jù)固定的長度來接收數(shù)據(jù)。這個時候在一幀數(shù)據(jù)里面加入數(shù)據(jù)長度這個標志,就能夠給單片機一個判斷的準則,單片機接收到數(shù)據(jù)長度這個標志之后,根據(jù)這個長度來接收剩下的數(shù)據(jù)。示例代碼片段如下:

if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中斷
{
	Res = USART_ReceiveData(USART1);//讀取接收到的數(shù)據(jù),同時也清除了中斷標志位
		   
	USART_RX_BUF[USART_RX_STA ++] = Res;
	if(USART_RX_BUF[0] != 0xA5 && USART_RX_STA == 1)
	{//幀頭錯誤
	     USART_RX_STA = 0;//重新接收
	}
	If(USART_RX_STA == 4)
	{
	USART_RX_Len = USART_RX_BUF[3];//數(shù)據(jù)長度
	}
	if(USART_RX_STA >= (USART_RX_Len + 4))
	{//接收完成
	    USART_RX_STA = 0;
	    USART_RXHANDLE_FLAG = 1;
	}
}

4、根據(jù)接收時間判斷一幀數(shù)據(jù)的長度。根據(jù)波特率計算出兩個字節(jié)傳輸?shù)臅r間間隔,接收到數(shù)據(jù)之后定時器開始計時,在定時器中斷觸發(fā)之前收到數(shù)據(jù)就清空,重新計時,超過兩個字節(jié)的間隔時間,就認為是一幀數(shù)據(jù)接收完成。具體的程序我就不寫了,這個網(wǎng)上能找到很多例程。這種方法適合接收長度不定的情況,在這個方法的基礎上還可以加上幀頭幀尾等標志,增強穩(wěn)定性。

5、校驗處理:校驗一般是在接收完成之后進行,校驗是很必要的,因為它包含一幀數(shù)據(jù)的所有字節(jié),通過校驗能夠大大的減少出錯的概率。

四、總結

其實串口接收數(shù)據(jù)處理主要要注意兩點,第一點是單片機如何確定一幀數(shù)據(jù)接收完成,第二點是單片機如果判斷接收到的數(shù)據(jù)是正確的指令。第一點可以通過幀尾,數(shù)據(jù)長度等標志確定接收完成。第二點可以先通過幀頭初步判斷指令的正確性,再通過校驗二次處理,判斷指令是否正確接收。

關于串口接收數(shù)據(jù)處理的相關內容就介紹到這里,如果還有什么問題,可以留言,如果文章有哪里寫的不對,歡迎指正,謝謝!

推薦器件

更多器件
器件型號 數(shù)量 器件廠商 器件描述 數(shù)據(jù)手冊 ECAD模型 風險等級 參考價格 更多信息
VOD217T 1 Vishay Intertechnologies VOD205T, VOD206T, VOD207T, VOD211T, VOD213T, VOD217T Optocoupler, Phototransistor Output, Dual Channel, SOIC-8 Package

ECAD模型

下載ECAD模型
$0.76 查看
TJA1051T/E,118 1 NXP Semiconductors TJA1051 - High-speed CAN transceiver SOIC 8-Pin

ECAD模型

下載ECAD模型
$0.3 查看
ECS-250-20-33-DU-TR 1 ECS International Inc Parallel - Fundamental Quartz Crystal, 25MHz Nom, SMD, 4 PIN
$0.86 查看

相關推薦

電子產(chǎn)業(yè)圖譜