深度探索串口通信

串口通信,用的太多了,然而一直沒有深入研究過。從剛開始入門單片機,就學習瞭如何用電腦和單片機通信,但是一旦通信成功後,就再也沒有仔細去深入研究過了。這次在使用嵌入式Linux開發板的過程中,被一個問題卡了很久很久,使得我重新認識了串口通信。

問題初現

JZ2440開發板帶有1個USB-COM口,三個普通的COM口。電腦通過一條USB線,插到板子的USB-COM口,與板子相連,用來發送控制命令。現在我想使用普通的COM口來和電腦通信,筆記本電腦不帶COM口,所以常規的做法就是接一條USB轉串口線來實現。

接好之後,開發板串口測試程序也寫好了,於是,我打開了電腦上的串口調試助手,開始調試。結果發現,從開發板發過來的數據,跟調試助手顯示的不一致。我從開發板發送“ttttt”,電腦收到的十六進制是D1 D1 D1 D1 11。從ascii表上,查到't'應該是74,完全對不上。從此,我陷入到了維持幾乎兩週的困境。

噩夢開始

1.懷疑COM2口本身壞了,換成旁邊的COM3,依舊如此,更換了USB轉串口線,還是如此。

2.仔細檢查程序是否存在bug,並沒有。

3.檢查串口參數設置是否一致。波特率、數據位、校驗位、停止位、流控,全部都一致。

4.接下來,我開始從發送和接收的數據上來推算,某些規律。

下面是一些測試:
發送一個0x01
電腦串口助手發送 0000 0001
開發板收到的 是   0111 1111
感覺上是位的位置對調,然後全部取反了。電腦和開發板的取位順序不一致?

發送兩個0x01
電腦串口助手發送 0000 0001 0000 0001
開發板收到的是   0111 1111 0111 1111
是一樣的。

發送一個0x02
電腦串口助手發送 0000 0010 
開發板收到的 是  0011 1111
這個已經不符合上面的推測了

發送兩個個0x02
電腦串口助手發送 0000 0010 0000 0010
開發板收到的 是   1011 1111 0011 1111 
跟上面發送一個0x02相比,很奇怪,感覺錯位了。

我凌亂了。。。

5.我開始懷疑是不是編碼的問題,找了一些編碼轉換函數,依舊沒什麼變化。
6.開發板COM2的TXD和RXD腳短接,自發自收,發送的跟接收的是一致的。同樣的,將USB轉串口線上的2號腳和3號腳短接,串口調試助手自收自發,結果也是一致的。可以得出的結論是,兩邊各自都沒有問題,一旦相互,就出現了問題。
7.再次懷疑編碼的問題,難道Linux和Windows的編碼方式不一樣?網上講了一大堆ASCII,UTF-8,Unicode等,絲毫幫不上忙。
8.我開始尋求外援,最後給到的最好的答案是用示波器來觀察電平。
剛開始我很懷疑,發送的數據能在示波器上顯示出來?不嘗試怎麼會知道。我先來測試電腦發送的數據波形圖,畢竟電腦或者說串口調試助手都是比較穩定的東西,一般都不會錯。設置10ms重複發送0x01,真的就看到了圖,慢慢調節後,圖就出來了。然而,出來的圖跟預想的不一樣,其實我壓根就不知道應該是什麼樣的圖。只知道0和1表現爲一高一低的方波。去網上一搜,才知道了真相。

不得不重新來認識一下串行數據的格式,以下內容來自網上一篇文章,也不知道作者是誰,感謝作者。

————————————————— 引用 ————————————————

異步串行數據的一般格式是:起始位+數據位+停止位,其中起始位1 位,數據位可以是5、6、7、8位,停止位可以是1、1.5、2位。起始位是一個值爲0的位,所以對於正邏輯的TTL電平,起始位是一位時間的低電平;停止位是值爲1的位,所以對於正邏輯的TTL電平,停止位是高電平。對於負邏輯(如RS-232電平)則相反。

例如,對於16進制數據0x55aa,當採用8位數據位、1位停止位傳輸時,它在信號線上的波形如圖1(TTL電平)和圖2(RS-232電平)所示。 (先傳第一個字節55,再傳第二個字節aa,每個字節都是從低位向高位逐位傳輸)

 
圖1 TTL電平的串行數據幀格式(0x55aa)

 
圖2 RS-232電平的串行數據幀格式(0x55aah)

————————————————————————————————————

裏面我要重點強調“每個字節都是從低位向高位逐位傳輸”這一點,如0001這個,示波器圖形表現爲1000。

另外,終於明白了數據格式的真正的具體形式:起始位+數據位+停止位,從上面的圖中就能很清晰看出。

當時着急尋找答案,忘了拍波形圖,從網上down來一張,僅供演示:



回到前面我說圖形跟數據對不上,實際是自己壓根就不懂,瞎猜的。圖像跟我所發的數據完全一致。同樣的,我測試了開發板串口發出的數據,圖形也是吻合的。那就奇怪了,因爲示波器是同一個,開發板和電腦給示波器發同一個指令,得到的是一樣的圖形。這就沒問題啊,爲什麼兩者一連通就出現問題了呢?

答案初現

偶然間,我瞥見開發板發數據的圖形上面,電壓是3.4V。但是,在測試電腦發數據的時候,印象中是10V。回來驗證了一下,果真是10V。兩邊電壓不對等啊!連忙去看了開發板的原理圖,驚呆了,COM2接口是直接從arm芯片引腳出來的,沒有任何轉變。常規都是通過一個MAX232芯片來轉換一下才接出來。因爲arm芯片引腳出來的是TTL電平,差不多3.3-5V,而RS-232電平在10-15v左右,所以不能直連,需要像MAX232這種芯片來轉換一下。原來如此,問題就出在這裏了,COM2是TTL電平3.4V,而USB轉串口線這邊是RS-232電平10V。直接連在一起就大錯特錯了。

新的疑問

前面說過,板子自帶一個USB-COM口,於是我去研究了一下,它其實是arm芯片引腳出來接了一個PL2303芯片,這個芯片直接將串口信號轉化成了USB信號。再來看我另買的USB轉串口線,剛好線材是透明的,我能看到裏面有個芯片也是PL2303。這就奇怪了,爲什麼同樣都是PL2303,板子的可以直接連到芯片引腳上,而USB轉串口線的必須通過一個MAX232芯片來轉換呢?

終極答案

我又仔細看了板子的PL2303芯片,全稱是PL2303TA,USB轉串口線裏面的全稱是PL2303RA,一個字母之差會有什麼區別呢?在網上找到了PL2303TA和PL2303RA的技術手冊,終於真相大白了。雖然同爲PL2302芯片,PL2303TA直接在TTL電平下將串口信號轉換成USB信號。而PL2303RA會將電平拉高,信號轉換的同時電平也變化了。

解決方案

針對COM2口,可以有兩種選擇:

  1. 買一個帶PL2303TA的USB接頭,直接插到電腦上
  2. 買一個帶MAX232的9針串口,插到USB轉串口線上,再插到電腦上

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章