嵌入式系統(tǒng)中串口通信幀的同步方法[圖]

相關(guān)專題: 無(wú)線

引 言

串口通信是日前單片機(jī)和DSP等嵌入式系統(tǒng)之間,以及嵌入式系統(tǒng)與PC機(jī)或無(wú)線模塊之間的一種非常重要且普遍使用的通信方式。在嵌入式系統(tǒng)的硬件結(jié)構(gòu)中,通常只有一個(gè)8位或16位的CPU,不僅要完成主流程的工作,同時(shí)還要處理隨時(shí)發(fā)生的各種中斷,因而嵌入式系統(tǒng)中的串口通信程序設(shè)計(jì)與PC機(jī)有很大的不同。若嵌入式系統(tǒng)中.中斷服務(wù)子程序在系統(tǒng)運(yùn)行過(guò)程中占用了較多的時(shí)間,就有可能在中斷眼務(wù)子程序正運(yùn)行時(shí),又產(chǎn)生一個(gè)同類型或其他類型的中斷,從而造成主程序得不到執(zhí)行或后續(xù)中斷數(shù)據(jù)丟失。所以,嵌入式系統(tǒng)中的串口通信雖然看似簡(jiǎn)單,但其中仍有許多問(wèn)題值得研究,例如串口通信過(guò)程中的幀同步問(wèn)題。本文針對(duì)該問(wèn)題給出了逐次比較、基于FIFO隊(duì)列和基于狀態(tài)機(jī)的3種幀同步方法。通過(guò)測(cè)試、分析和比較得出,基于有限狀態(tài)機(jī)的方法是嵌入式系統(tǒng)串口通信中很有效的幀同步方法,同時(shí)也是一種很不錯(cuò)的串口通信程序設(shè)計(jì)結(jié)構(gòu)。

1 串口通信的數(shù)據(jù)幀結(jié)構(gòu)

現(xiàn)代工業(yè)控制,往往需要由多個(gè)獨(dú)立的控制模塊來(lái)共同完成。它們之間通過(guò)串口通信完成復(fù)雜的控制過(guò)程,必須在通信過(guò)程中加入必要的通信協(xié)議,以提高系統(tǒng)的可靠性和穩(wěn)定性;而要完成特定的通信協(xié)議,就得有一定的同步機(jī)制。下面介紹一下簡(jiǎn)化的串口通信數(shù)據(jù)幀結(jié)構(gòu),以便分析說(shuō)明嵌入式系統(tǒng)串口通信過(guò)程中的幀同步方法。

假定串口發(fā)送的數(shù)據(jù)幀結(jié)構(gòu)為:

其中:包頭用于同步,一般是一個(gè)或多個(gè)ASCII字符,本文中假定數(shù)據(jù)幀同步頭有2字節(jié)(0xAA、0x55);包長(zhǎng)表示數(shù)據(jù)包中除去包頭和包長(zhǎng)的字節(jié)數(shù),一般用約定好的幾個(gè)字節(jié)表示;類型為通信協(xié)議里規(guī)定的命令類型;數(shù)據(jù)為應(yīng)發(fā)送的主要信息;校驗(yàn)通常采用單字節(jié)“異或”的方法。

2 串口通信中的幀同步方法

2.1 逐次比較的幀同步方法

首先等待串口數(shù)據(jù),將接收到的第1個(gè)字節(jié)數(shù)據(jù)與約定好的包頭信息的第1個(gè)字節(jié)進(jìn)行比較。如果不正確,則等待新字節(jié),直到接收的數(shù)據(jù)與包頭信息的第1個(gè)字節(jié)相同。第1個(gè)字節(jié)比較正確以后,將收到的第2個(gè)字節(jié)與包頭信息的第2個(gè)字節(jié)進(jìn)行比較。如果仍然正確,則說(shuō)明串口接收已經(jīng)同步,可以開(kāi)始接收數(shù)據(jù)幀中的數(shù)據(jù)部分;否則,重新開(kāi)始同步過(guò)程。其程序流程如圖1所示。

此種方法代碼量小,編程簡(jiǎn)單,一般用于在主程序中以非中斷方式接收串口數(shù)據(jù)、實(shí)時(shí)性很差、數(shù)據(jù)幀較短的場(chǎng)合。但是,在串口速度過(guò)快且包頭字節(jié)數(shù)比較多的情況下,串口實(shí)現(xiàn)同步花費(fèi)的時(shí)間很長(zhǎng)或很難實(shí)現(xiàn)同步。例如,串口接收到序列Ox0O OxAA0xAA 0x55…,當(dāng)遇到第一個(gè)“0xAA”時(shí),該方法認(rèn)為第1個(gè)字節(jié)正確開(kāi)始比較第2個(gè)同步頭。第2個(gè)字節(jié)仍是“0xAA”而不是“0x55”,所以必須等待新的字節(jié)重新開(kāi)始比較第1個(gè)同步頭。而緊隨其后的是“0x55”,因而,此時(shí)包頭的第1個(gè)字節(jié)也沒(méi)有同步上。事實(shí)上,“0x00 OxAA”是干擾字節(jié),“0xAA 0x55”才是通信協(xié)議中的同步頭。

2.2 基于FIFO隊(duì)列的幀同步方法

根據(jù)同步包頭的長(zhǎng)度,定義一個(gè)相同長(zhǎng)度的全局字節(jié)數(shù)組,把該數(shù)組看成是一個(gè)如圖2所示的先入先出(FIFO)的隊(duì)列。程序流程如圖3所示。

本例中定義兩個(gè)字節(jié)HEADl和HEAD2,都初始化為0xFF。同步時(shí),丟棄數(shù)組頭字節(jié)HEADl,數(shù)組中的所有數(shù)據(jù)向前移動(dòng)一個(gè)字節(jié),串口接收到的新字節(jié)存入數(shù)組末字節(jié)HEAD2中,將整個(gè)數(shù)組與協(xié)議中的包頭信息比較。如果正確,則置位已同步標(biāo)志位,然后開(kāi)始接收、存儲(chǔ)有用數(shù)據(jù);否則,繼續(xù)等待同步。串口數(shù)據(jù)接收完后,不僅要清除已同步標(biāo)志,還要把HEADl和HEAD2兩個(gè)字節(jié)都賦值0xFF;否則,將會(huì)影響下一幀數(shù)據(jù)的同步和接收。用前面提到的序列“0x00 0xAA 0xAA 0x55…”進(jìn)行測(cè)試,隨著串口接收中斷收到新的字節(jié)。幀同步隊(duì)列中的數(shù)據(jù)依次為:[0xFF,0xFF]→[0x00,0xFF]→[0xAA,0x00]→[0xAA,0xAA]→[0x55,0xAA]。此時(shí),該算法檢測(cè)出[HEAD2,HEAD2]==[0x55,0xAA],從而實(shí)現(xiàn)了同步,置位已同步標(biāo)志位以便下次進(jìn)入串口接收中斷服務(wù)子程序時(shí)開(kāi)始接收數(shù)據(jù)包的數(shù)據(jù)部分。

此種方法與逐次比較的幀同步方法相比,能夠比較快速、正確地檢測(cè)出同步包頭;但是如果包頭的字節(jié)數(shù)很多,同步過(guò)程中每次進(jìn)入串口中斷服務(wù)子程序都要進(jìn)行大量的字節(jié)搬移,將必然耗費(fèi)很長(zhǎng)的時(shí)間。為了使嵌入式系統(tǒng)更健壯,程序設(shè)計(jì)應(yīng)把握的基本原則之一就是使中斷處理程序最短。所以基于FIFO隊(duì)列的幀同步方法也不是最優(yōu)的。

2.3 基于有限狀態(tài)機(jī)的幀同步方法

為解決以上問(wèn)題,可以采用基于有限狀態(tài)機(jī)的設(shè)計(jì)方法。該方法將數(shù)據(jù)幀的接收過(guò)程分為若干個(gè)狀態(tài):接收信息頭HEADl狀態(tài)、接收信息頭HEAD2狀態(tài)、接收包長(zhǎng)狀態(tài)、接收數(shù)據(jù)類型狀態(tài)、接收數(shù)據(jù)狀態(tài)及接收校驗(yàn)和狀態(tài)。系統(tǒng)的初始狀態(tài)為HEADl狀態(tài),各接收狀態(tài)間的狀態(tài)轉(zhuǎn)移圖如圖4所示,仍用前面提到的序列“0x00 0xAA 0xAA 0x55…”進(jìn)行測(cè)試。隨著串口接收中斷新字節(jié)的接收,系統(tǒng)的接收狀態(tài)依次為HEAD1→HEAD1→HEAD2→HEAD2→LEN?梢(jiàn)此時(shí)就是同步狀態(tài)。該方法也快速、有效地實(shí)現(xiàn)了同步;但是需要注意的是,在每一次接收完1幀完整的數(shù)據(jù)之后,必須把系統(tǒng)的接收狀態(tài)重新設(shè)置為HEADl,否則將會(huì)影響下一幀的數(shù)據(jù)接收。

此后,程序按照協(xié)議開(kāi)始依次接收數(shù)據(jù)幀長(zhǎng)度、命令類型、數(shù)據(jù)和校驗(yàn)位。接收完后,重新設(shè)置系統(tǒng)接收狀態(tài)為HEADl,同時(shí)對(duì)該數(shù)據(jù)幀進(jìn)行校驗(yàn)。校驗(yàn)正確后,利用消息機(jī)制通知主程序根據(jù)命令類型對(duì)數(shù)據(jù)幀進(jìn)行處理或執(zhí)行相應(yīng)的命令操作。

下面給出該方法在KeilC5l中的示例程序:

由于采用了狀態(tài)機(jī)和消息機(jī)制的結(jié)構(gòu),上述設(shè)計(jì)思路快速有效地實(shí)現(xiàn)了串口通信的同步,而且程序結(jié)構(gòu)清晰,便于維護(hù),也易于向其他的串口通信協(xié)議移植。另外,串口中斷服務(wù)子程序中需要處理的工作很少,每個(gè)串口接收中斷平均耗時(shí)不超過(guò)20個(gè)機(jī)器周期(在單片機(jī)AT89C5l中),大大減輕了串口接收中斷服務(wù)程序的壓力,緩解了嵌入式系統(tǒng)有限資源與需求之問(wèn)的矛盾,提高了嵌入式系統(tǒng)的穩(wěn)定性。

3 結(jié)論

從上面的分析和測(cè)試可以看出,基于有限狀態(tài)機(jī)的串口通信幀同步方法是本文中提出的3種幀方法中最優(yōu)的,結(jié)構(gòu)清晰且系統(tǒng)資源利用率高。

對(duì)一個(gè)有著完整通信協(xié)議的串口中斷來(lái)說(shuō),因?yàn)橐容^命令頭、完成校驗(yàn)、解析數(shù)據(jù)等需要耗費(fèi)大量的機(jī)器周期,所以嵌入式系統(tǒng)中的串口中斷服務(wù)程序設(shè)計(jì)顯得更為重要。在實(shí)際的串口通信程序中,可采用狀態(tài)機(jī)和消息機(jī)制相結(jié)合的方法,僅在中斷服務(wù)程序中設(shè)置一個(gè)標(biāo)志,而在主程序中根據(jù)相應(yīng)標(biāo)志來(lái)作處理,這樣就回避了某些中斷可能需要較長(zhǎng)處理時(shí)間的問(wèn)題。在程序結(jié)構(gòu)上,由于采用狀態(tài)機(jī)的結(jié)構(gòu),既提高了可讀性。同時(shí)又提高了運(yùn)行速度,因而該方法不僅是一種很好的幀同步方法,還是一種很不錯(cuò)的串口通信程序設(shè)計(jì)方法。

作者:周奮 王婷 來(lái)源:?jiǎn)纹瑱C(jī)與嵌入式系統(tǒng)應(yīng)用

我推薦大家讀

輕松參與

VS

表達(dá)立場(chǎng)

這是垃圾文章


微信掃描分享本文到朋友圈
掃碼關(guān)注5G通信官方公眾號(hào),免費(fèi)領(lǐng)取以下5G精品資料
  • 1、回復(fù)“YD5GAI”免費(fèi)領(lǐng)取《中國(guó)移動(dòng):5G網(wǎng)絡(luò)AI應(yīng)用典型場(chǎng)景技術(shù)解決方案白皮書(shū)
  • 2、回復(fù)“5G6G”免費(fèi)領(lǐng)取《5G_6G毫米波測(cè)試技術(shù)白皮書(shū)-2022_03-21
  • 3、回復(fù)“YD6G”免費(fèi)領(lǐng)取《中國(guó)移動(dòng):6G至簡(jiǎn)無(wú)線接入網(wǎng)白皮書(shū)
  • 4、回復(fù)“LTBPS”免費(fèi)領(lǐng)取《《中國(guó)聯(lián)通5G終端白皮書(shū)》
  • 5、回復(fù)“ZGDX”免費(fèi)領(lǐng)取《中國(guó)電信5GNTN技術(shù)白皮書(shū)
  • 6、回復(fù)“TXSB”免費(fèi)領(lǐng)取《通信設(shè)備安裝工程施工工藝圖解
  • 7、回復(fù)“YDSL”免費(fèi)領(lǐng)取《中國(guó)移動(dòng)算力并網(wǎng)白皮書(shū)
  • 8、回復(fù)“5GX3”免費(fèi)領(lǐng)取《R1623501-g605G的系統(tǒng)架構(gòu)1
  • 本周熱點(diǎn)本月熱點(diǎn)

     

      最熱通信招聘

    業(yè)界最新資訊


      最新招聘信息