嵌入式系統中串口通信幀的同步方法研究
串口通信是日前單片機和DSP等嵌入式系統之間,以及嵌入式系統與PC機或無(wú)線(xiàn)模塊之間的一種非常重要且普遍使用的通信方式。在嵌入式系統的硬件結構中,通常只有一個(gè)8位或16位的CPU,不僅要完成主流程的工作,同時(shí)還要處理隨時(shí)發(fā)生的各種中斷,因而嵌入式系統中的串口通信程序設計與PC機有很大的不同。若嵌入式系統中.中斷服務(wù)子程序在系統運行過(guò)程中占用了較多的時(shí)間,就有可能在中斷服務(wù)子程序正運行時(shí),又產(chǎn)生一個(gè)同類(lèi)型或其他類(lèi)型的中斷,從而造成主程序得不到執行或后續中斷數據丟失。所以,嵌入式系統中的串口通信雖然看似簡(jiǎn)單,但其中仍有許多問(wèn)題值得研究,例如串口通信過(guò)程中的幀同步問(wèn)題。本文針對該問(wèn)題給出了逐次比較、基于FIFO隊列和基于狀態(tài)機的3種幀同步方法。通過(guò)測試、分析和比較得出,基于有限狀態(tài)機的方法是嵌入式系統串口通信中很有效的幀同步方法,同時(shí)也是一種很不錯的串口通信程序設計結構。
本文引用地址:http://dyxdggzs.com/article/201611/321758.htm二、串口通信的數據幀結構
現代工業(yè)控制,往往需要由多個(gè)獨立的控制模塊來(lái)共同完成。它們之間通過(guò)串口通信完成復雜的控制過(guò)程,必須在通信過(guò)程中加入必要的通信協(xié)議,以提高系統的可靠性和穩定性;而要完成特定的通信協(xié)議,就得有一定的同步機制。下面介紹一下簡(jiǎn)化的串口通信數據幀結構,以便分析說(shuō)明嵌入式系統串口通信過(guò)程中的幀同步方法。
假定串口發(fā)送的數據幀結構為:
其中:包頭用于同步,一般是一個(gè)或多個(gè)ASCII字符,本文中假定數據幀同步頭有2字節(0xAA、0x55);包長(cháng)表示數據包中除去包頭和包長(cháng)的字節數,一般用約定好的幾個(gè)字節表示;類(lèi)型為通信協(xié)議里規定的命令類(lèi)型;數據為應發(fā)送的主要信息;校驗通常采用單字節“異或的方法。
二、串口通信中的幀同步方法
1、逐次比較的幀同步方法
首先等待串口數據,將接收到的第1個(gè)字節數據與約定好的包頭信息的第1個(gè)字節進(jìn)行比較。如果不正確,則等待新字節,直到接收的數據與包頭信息的第1個(gè)字節相同。第1個(gè)字節比較正確以后,將收到的第2個(gè)字節與包頭信息的第2個(gè)字節進(jìn)行比較。如果仍然正確,則說(shuō)明串口接收已經(jīng)同步,可以開(kāi)始接收數據幀中的數據部分;否則,重新開(kāi)始同步過(guò)程。其程序流程如圖1所示。
此種方法代碼量小,編程簡(jiǎn)單,一般用于在主程序中以非中斷方式接收串口數據、實(shí)時(shí)性很差、數據幀較短的場(chǎng)合。但是,在串口速度過(guò)快且包頭字節數比較多的情況下,串口實(shí)現同步花費的時(shí)間很長(cháng)或很難實(shí)現同步。例如,串口接收到序列Ox0O OxAA 0xAA 0x55…,當遇到第一個(gè)“0xAA時(shí),該方法認為第1個(gè)字節正確開(kāi)始比較第2個(gè)同步頭。第2個(gè)字節仍是“0xAA而不是“0x55,所以必須等待新的字節重新開(kāi)始比較第1個(gè)同步頭。而緊隨其后的是“0x55,因而,此時(shí)包頭的第1個(gè)字節也沒(méi)有同步上。事實(shí)上,“0x00 OxAA是干擾字節,“0xAA 0x55才是通信協(xié)議中的同步頭。
2、基于FIFO隊列的幀同步方法
根據同步包頭的長(cháng)度,定義一個(gè)相同長(cháng)度的全局字節數組,把該數組看成是一個(gè)如圖2所示的先入先出(FIFO)的隊列。程序流程如圖3所示。
本例中定義兩個(gè)字節HEADl和HEAD2,都初始化為0xFF。同步時(shí),丟棄數組頭字節HEADl,數組中的所有數據向前移動(dòng)一個(gè)字節,串口接收到的新字節存入數組末字節HEAD2中,將整個(gè)數組與協(xié)議中的包頭信息比較。如果正確,則置位已同步標志位,然后開(kāi)始接收、存儲有用數據;否則,繼續等待同步。串口數據接收完后,不僅要清除已同步標志,還要把HEADl和HEAD2兩個(gè)字節都賦值0xFF;否則,將會(huì )影響下一幀數據的同步和接收。用前面提到的序列“0x00 0xAA 0xAA 0x55…進(jìn)行測試,隨著(zhù)串口接收中斷收到新的字節。幀同步隊列中的數據依次為:[0xFF,0xFF]→[0x00,0xFF]→[0xAA,0x00]→[0xAA,0xAA]→[0x55,0xAA]。此時(shí),該算法檢測出[HEAD2,HEAD2]==[0x55,0xAA],從而實(shí)現了同步,置位已同步標志位以便下次進(jìn)入串口接收中斷服務(wù)子程序時(shí)開(kāi)始接收數據包的數據部分。
此種方法與逐次比較的幀同步方法相比,能夠比較快速、正確地檢測出同步包頭;但是如果包頭的字節數很多,同步過(guò)程中每次進(jìn)入串口中斷服務(wù)子程序都要進(jìn)行大量的字節搬移,將必然耗費很長(cháng)的時(shí)間。為了使嵌入式系統更健壯,程序設計應把握的基本原則之一就是使中斷處理程序最短。所以基于FIFO隊列的幀同步方法也不是最優(yōu)的。
3、基于有限狀態(tài)機的幀同步方法
為解決以上問(wèn)題,可以采用基于有限狀態(tài)機的設計方法。該方法將數據幀的接收過(guò)程分為若干個(gè)狀態(tài):接收信息頭HEADl狀態(tài)、接收信息頭HEAD2狀態(tài)、接收包長(cháng)狀態(tài)、接收數據類(lèi)型狀態(tài)、接收數據狀態(tài)及接收校驗和狀態(tài)。系統的初始狀態(tài)為HEADl狀態(tài),各接收狀態(tài)間的狀態(tài)轉移圖如圖4所示,仍用前面提到的序列“0x00 0xAA 0xAA 0x55…進(jìn)行測試。隨著(zhù)串口接收中斷新字節的接收,系統的接收狀態(tài)依次為HEAD1→HEAD1→HEAD2→HEAD2→LEN??梢?jiàn)此時(shí)就是同步狀態(tài)。該方法也快速、有效地實(shí)現了同步;但是需要注意的是,在每一次接收完1幀完整的數據之后,必須把系統的接收狀態(tài)重新設置為HEADl,否則將會(huì )影響下一幀的數據接收。
此后,程序按照協(xié)議開(kāi)始依次接收數據幀長(cháng)度、命令類(lèi)型、數據和校驗位。接收完后,重新設置系統接收狀態(tài)為HEADl,同時(shí)對該數據幀進(jìn)行校驗。校驗正確后,利用消息機制通知主程序根據命令類(lèi)型對數據幀進(jìn)行處理或執行相應的命令操作。
相關(guān)推薦
技術(shù)專(zhuān)區
- FPGA
- DSP
- MCU
- 示波器
- 步進(jìn)電機
- Zigbee
- LabVIEW
- Arduino
- RFID
- NFC
- STM32
- Protel
- GPS
- MSP430
- Multisim
- 濾波器
- CAN總線(xiàn)
- 開(kāi)關(guān)電源
- 單片機
- PCB
- USB
- ARM
- CPLD
- 連接器
- MEMS
- CMOS
- MIPS
- EMC
- EDA
- ROM
- 陀螺儀
- VHDL
- 比較器
- Verilog
- 穩壓電源
- RAM
- AVR
- 傳感器
- 可控硅
- IGBT
- 嵌入式開(kāi)發(fā)
- 逆變器
- Quartus
- RS-232
- Cyclone
- 電位器
- 電機控制
- 藍牙
- PLC
- PWM
- 汽車(chē)電子
- 轉換器
- 電源管理
- 信號放大器
評論