單片機串口接收的幾種常用的數據處理方法

單片機串口接收的幾種常用的數據處理方法

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

二、串口接收重點關注的幾個標誌
爲了保證通訊的穩定性,一般的通訊協議會加入幀頭、幀尾、數據長度、校驗這四個標誌中的一個或多個。它們的作用如下:
1、幀頭:串口發送數據的第一個字節是最容易出錯的,如果你把重要的指令放在第一個字節,一旦出現錯誤,可能會使從機執行錯誤的操作。而幀頭能夠有效規避這個問題。
2、幀尾:和幀頭類似,幀尾也能避免最後一個字節出錯,同時,它也可以作爲接收端接收完成的標誌。
3、數據長度:它可以作爲接收端接收完成的標誌。有時也能作爲判斷數據是否正確的標誌。
4、校驗:能夠有效避免校驗以外的所有數據的錯誤,但是校驗正確不代表數據一定沒有出錯,每種校驗方式都有一定的缺陷。
幀頭、幀尾、數據長度和校驗,這四種標誌加起來之後能夠大大的增強數據傳輸的穩定性,但不是每個通訊協議都會包含以上四個標誌,可能只會用到其中的一兩個。因爲如果要發送的主要數據本身就比較長,加上這個幾個標誌之後會更長,這對於那種傳輸速度慢、傳輸數據時間長、傳輸指令頻繁處理速度慢的設備來說,較長的指令可能會影響工作效率。具體我就不多說了,我今天主要講的是接收數據的處理方法,大家根據自己的協議選擇合適的處理方法就行了。

三、常用的幾種數據處理方法
1、判斷幀頭:串口接收到第一個數據之後先判斷是否是幀頭,如果幀頭正確就存起來繼續收,反之則丟掉繼續等幀頭。示例代碼片段如下:

if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中斷
{
	Res = USART_ReceiveData(USART1);//讀取接收到的數據,同時也清除了中斷標誌位
		   
	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;
	}
}

這種處理方法能夠有效避免第一個字節出錯的問題,我就試過一次主設備那邊傳過來的數據幀頭前面多了一個字節(可能是剛開始傳輸的時候電壓不穩定產生的紋波),用這種方法就能夠之間把第一個錯誤的數據丟掉,從正確的幀頭開始接收。但是這種方法不能夠檢查幀頭後面的數據是否正確。
2、判斷幀尾:可以把幀尾作爲一幀數據接收完成的標誌。另外,當接收緩存存了多個指令的時候,幀尾能夠幫助我們在一堆數據中區分出哪些數據是同一個指令的。當然,如果僅僅是區分數據用幀頭也可以。不過這種辦法必須保證幀尾和其他數據不一樣,不然就會出現錯誤的判斷。所以有些人爲了避免這個問題會用兩個字節作爲幀尾,不過這樣一來,數據長度就更大了,影響通訊效率。
3、根據數據長度判斷是否完成接收:可以通過數據長度判斷接收是否完成。如果協議裏面的指令長度不是統一的,我們就不能根據固定的長度來接收數據。這個時候在一幀數據裏面加入數據長度這個標誌,就能夠給單片機一個判斷的準則,單片機接收到數據長度這個標誌之後,根據這個長度來接收剩下的數據。示例代碼片段如下:

if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中斷
{
	Res = USART_ReceiveData(USART1);//讀取接收到的數據,同時也清除了中斷標誌位
		   
	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];//數據長度
	}
	if(USART_RX_STA >= (USART_RX_Len + 4))
	{//接收完成
	    USART_RX_STA = 0;
	    USART_RXHANDLE_FLAG = 1;
	}
}

4、根據接收時間判斷一幀數據的長度。根據波特率計算出兩個字節傳輸的時間間隔,接收到數據之後定時器開始計時,在定時器中斷觸發之前收到數據就清空,重新計時,超過兩個字節的間隔時間,就認爲是一幀數據接收完成。具體的程序我就不寫了,這個網上能找到很多例程。這種方法適合接收長度不定的情況,在這個方法的基礎上還可以加上幀頭幀尾等標誌,增強穩定性。
5、校驗處理:校驗一般是在接收完成之後進行,校驗是很必要的,因爲它包含一幀數據的所有字節,通過校驗能夠大大的減少出錯的概率。

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

關於串口接收數據處理的相關內容就介紹到這裏,如果還有什麼問題,可以留言,如果文章有哪裏寫的不對,歡迎指正,謝謝!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章