<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 網(wǎng)絡(luò )與存儲 > 設計應用 > 嵌入式系統上的異步串口通信的實(shí)現

嵌入式系統上的異步串口通信的實(shí)現

作者: 時(shí)間:2017-11-03 來(lái)源:網(wǎng)絡(luò ) 收藏

  在系統中,異步串口(UART)使用非常頻繁,可以用于與各種外部系統(幀括PC)之間的通信。在硬件上UART通過(guò)在每個(gè)字節的傳輸中插入開(kāi)始位和停止位,保證接收端可以正確地找到字節的開(kāi)始和結束,同時(shí)也可以通過(guò)插入奇偶校驗位,讓接收端檢驗收到的字節是否正確。而且,由于有開(kāi)始位和停止位的存在,使得字節之間可以插入任意的空閑位(與停止位同為高電平),而不影響下一個(gè)字節的正常傳輸。因此,UART硬件保證了每個(gè)字節的正確傳輸,并可以有效檢出字節傳輸的錯誤。但并不保證一串字節的正確傳輸,這需要軟件來(lái)完成。

本文引用地址:http://dyxdggzs.com/article/201711/370982.htm

  從軟件的角度來(lái)看,所有的通信都是一串字節(叫做數據幀)的連續傳輸。軟件需要采用適當的機制來(lái)保證接收端能夠正確識別出一個(gè)完整的數據幀、能夠檢查接收到的數據幀是正確的、在傳輸發(fā)生錯誤時(shí)有合適的恢復機制。為此就需要定義一個(gè)合適的數據幀格式。

  數據幀的提取

  為了識別出一個(gè)完整的數據幀,基本上有兩個(gè)機制:一是在軟件上規定字節之間的間隔最大值,一旦兩個(gè)字節間的間隔超過(guò)某個(gè)閾值,就認為一個(gè)數據幀結束;另一種機制不對字節間的間隔作規定,而是用特殊的字節來(lái)定義數據報的開(kāi)始和結束,當收到該特殊字節時(shí),就認為一個(gè)數據幀的傳輸已完成。

  采用第一種機制的,比如Modbus-RTU。就是規定了同一個(gè)數據幀的字節間隔不能大于1.5個(gè)字節的傳輸時(shí)間,一旦大于該間隔,則認為前一個(gè)幀的傳輸已經(jīng)結束,或者出錯。同時(shí)為了保證不同數據幀之間有足夠的間隔,還規定了兩個(gè)數據幀之間最少插入3.5個(gè)字節的空閑位。下圖摘自Modbus協(xié)議,表示了一個(gè)正確的數據幀、錯誤的數據幀以及數據幀之間的間隔。同時(shí)在數據報中引入了CRC,用于檢出數據幀層面的傳輸錯誤。

    

 

    

 

  第二種機制需要選用一個(gè)特殊字節作為幀頭幀尾(也可以給幀頭幀尾選用不同的字節),比如說(shuō),選用0xFF作為幀頭幀尾字節,也即發(fā)送端在每個(gè)數據幀的頭尾都插入至少一個(gè)0xFF,接收端收到該字節就結束上一個(gè)幀的接收,同時(shí)從下一個(gè)非0xFF字節開(kāi)始一個(gè)新的數據幀的接收。但該機制有一個(gè)問(wèn)題,那就是所選的特殊字節(此處是0xFF)也可能是數據幀中的一個(gè)有效字節,如果不作特殊處理,接收端就可能把這個(gè)數據幀中的字節誤認為是數據幀的結束標識,從而導致接收錯誤。因此,此處采取字節替換的特殊處理,以消除在數據幀的中間出現的特殊字節,以下是一個(gè)例子。

    

 

  在此處,選0xFE作為字節替換的標識字節,將0xFF替換成0xFE 0x0F。由于0xFE是字節替換的標志,也成了一個(gè)特殊字符,同樣需要進(jìn)行替換。在上圖中,將0xFE替換成0xFE 0x0E。

  采用該機制時(shí),發(fā)送端對數據幀中的所有0xFF,0xFE進(jìn)行替換。在接收端則進(jìn)行反向替換。如果在接收端的0xFE后面的字節收到非0x0F,0x0E的字符,說(shuō)明發(fā)生了傳輸錯誤,丟棄已經(jīng)接收的內容,重新搜索幀頭字符開(kāi)始一個(gè)新數據幀的接收。

  數據幀的校驗

  考慮到有一定的誤碼率,無(wú)論是采用那種傳輸方式,必須有錯誤幀檢出機制。通常選用的是CRC。一般用2個(gè)字節或4個(gè)字節。

  串口驅動(dòng)的實(shí)現

  在系統中,串口驅動(dòng)的實(shí)現一般有兩個(gè)途徑:一個(gè)是通過(guò)串口的收發(fā)中斷與串口控制器的Buffer直接交換數據;另一種是通過(guò)DMA,利用DMA與串口Buffer交互自動(dòng)收發(fā)數據。

  與串口控制器直接交互的方式,實(shí)現簡(jiǎn)單,既可以實(shí)時(shí)進(jìn)行字節替換以節省內存,也可以方便設置字節間的定時(shí)器。但頻繁打斷CPU,對有一定BUFFER大小的串口,還可以利用BUFFER進(jìn)行性能優(yōu)化,而對一些只有一個(gè)字節或兩個(gè)字節BUFFER的串口,就需要一個(gè)字節起一次中斷,如果CPU負荷較重,很容易由于中斷處理不及時(shí)而導致字節丟失,特別是在高波特率的情況。

  利用DMA與串口控制器交互的方式,由于不能實(shí)時(shí)進(jìn)行字節替換,需要在放入DMA之前完成字節替換,導致占用較大內存空間。另外對于字節間間隔敏感的傳輸策略,需要用另外的機制,比如PRS,去操作定時(shí)器。用DMA的另一個(gè)問(wèn)題是在接收時(shí)無(wú)法實(shí)時(shí)確定幀尾(采用幀頭幀尾模式時(shí)),一般只能采用定時(shí)器與DMA配合,用字節流的方式處理接收。



關(guān)鍵詞: 嵌入式 串口通信

評論


相關(guān)推薦

技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>