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