使用串口進行數據的收發在嵌入式產品中是很常用的一種通信方式,因為串口的簡單使用,很容易就被選為產品中數據交互的通信手段。
基于串口進行開發的功能有很多,比如同類/不同類產品之間的通信,RS485通信,RS232通信方式,實現串口命令行終端用于調試等等的。雖然應用的場景有所不同,但是都會涉及到一個共同的問題:怎么確保收到一幀完整的數據?
使用過串口的朋友都會知道,串口收發數據都是按照串行的方式進行的,數據是按照bit的方式一位一位進行發送的。而且發送數據方想要發送的數據長度不一定是固定的,有可能長有可能短,這就會涉及到怎么識別一幀數據已經被接收完了的問題。
1. 串口數據的發送和接收方式
串口的接收和發送在兩個設備之間是按照bit的方式進行通信的,參見下面的示意圖:
數據從一方按照bit的方式1bit進行傳輸,另外一方也是按照1bit的方式進行接收,直到接收完1Byte數據為止,然后再接收下一個1Byte的數據。
這里還需要考慮另外一個問題,就是一個字節數據之間的時間間隔。簡單而言就是接收第一個字節和第二個字節之間的時間間隔,這個時間間隔在大數據量的情況下是要考慮的,數據量少的情況下可以忽略不計。參見下面的示意圖:
2. 串口接收不定長數據的實現方式
對于串口接收數據,最需要考慮的是怎么確保收到一幀完整的數據。因為在很多場景下都會遇到的一個問題,就是串口發送的數據是長度不固定的,有時候長有時候短,這就給接收數據和識別數據是有效的帶來了一些難度。
下面根據我個人在項目中使用串口進行數據接收的時候,針對不定長數據的處理方式進行簡單的分享。
2.1、固定格式幀的不定長數據接收
這種數據一般都是應用在某些產品之間的通信協議,有固定的數據幀格式,比如有固定的幀頭和幀尾用于確定數據幀,如下的固定幀頭尾的各式:
#define CMD_HEAD 0XAA5A //幀頭
#define CMD_TAIL 0XFDFCFF //幀尾
這種方式接收數據的時候就比較簡單,可以在接收數據的時候進行判斷,遇到幀頭的時候就開始保存數據,在識別到幀尾之后完成一幀數據的接收,再用其他的手段將這幀數據進行解析。
或者也可以先將所有的數據先接收起來,比如用一個數據緩沖區先保存所有的數據,然后再由應用程序去解析。因為這種數據是有固定格式的,所以解析的時候也很方便,只要按照數據幀的格式進行判別,如果符合格式的定義,就可以認為是一幀完整的數據,否者就丟棄。
2.2、格式不固定長度也不固定的數據的接收
這種數據的接收就相對比較麻煩一點,因為格式不是固定的,沒有明確的標識數據幀開頭和結尾的特征數據,所以這種方式的數據接收往往考慮的是數據幀之間的間隔,根據兩幀數據之間的間隔進行判斷,設置一個時間間隔,如果符合這個時間間隔就認為數據的接收是有效的,否者認為無效。
這種方式需要用到一個計時,并設定一個幀之間的時間間隔,從接收到數據就開始計時,然后每收一個數據就重置這個計時,直到計時到達設置的幀間隔時間沒有再接收到數據則認為數據已經接收完成。
這個幀的時間間隔可以任意設置,一般我們考慮是3.5個字符的時間。如果3.5個字符的時間沒有再收到數據,就認為數據的傳輸已經完成,接收端已經完成了數據的接收。
操作的步驟大致如下:
1)使用一個計時功能
2)接收到數據時啟動計時,然后之后每收到一個數據重置一次這個計時
3)在沒有收到數據之后,計時達到了設定的值,接收就算結束了,處理接收到數據,并關閉計時功能。
4)下一幀的數據接收,重復上面的步驟。
2.3、串口的空閑中斷
這種方式是使用的串口的空閑中斷功能,大概原理是在串口配置開啟了空閑中斷時,如果接收到數據之后就會啟動這個串口的空閑狀態檢測,在一段時間串口不在收到數據就會觸發串口的空閑中斷,告知完成一次數據的接收。
這種方式顯然更好,不用額外再實現空閑檢測功能,只要在串口觸發中斷并是空閑中斷的時候,就知道數據完成了接收。
但是,這個功能不是所有的MCU都具備,一般都是在一些高端一點的MCU中才有,低端一些的MCU估計都是沒有空閑中斷的。
當然,方式還有很多中,這里只是簡單的列舉了本人使用過的幾種方式,具體使用什么樣的方式還要根據實際的項目情況需要而定吧!
-
嵌入式
+關注
關注
5085文章
19138瀏覽量
305710 -
數據
+關注
關注
8文章
7067瀏覽量
89112 -
中斷
+關注
關注
5文章
898瀏覽量
41527 -
串口
+關注
關注
14文章
1555瀏覽量
76584
發布評論請先 登錄
相關推薦
評論