什么是串口通信?
串口,一般指異步串行接口(Serial port),主要用于串行式逐位數(shù)據(jù)傳輸。串口對于處于嵌入式行業(yè)的我們來說,是必不可缺的一部分,在剛開始學(xué)習(xí)單片機(jī)時,我們最先學(xué)習(xí)的通信接口就是USART(Universal Synchronous/Asynchronous Receiver/Transmitter)——通用同/異步串行接收/發(fā)送器。其中最常見的串口通信的時序如下圖:
于是在串口通信就有了起始位、數(shù)據(jù)位、校驗位、停止位、波特率這幾個參數(shù)。
另外,串口通信主要分為RS232、RS422、RS485三種通信方式,之前有系統(tǒng)地講解過,小編這里就不再進(jìn)行詳細(xì)地介紹了。
二、串口通信常見問題及解決
如上所述,串口作為我們?nèi)粘i_發(fā)時的非常重要的一個角色,我們也時常會碰到很多問題,深受各種折磨,接下來我們就來說說平時串口通信中常見的問題以及解決方法。
通常我們調(diào)試串口通信碰到問題時,需要用到一個USB轉(zhuǎn)TTL、杜邦線(導(dǎo)線)等工具,首先我們應(yīng)當(dāng)保證自己的工具是正常的,可以通過以下方法自測:
1、將USB轉(zhuǎn)TTL中的TX、RX使用杜邦線或是跳線帽短接,打開串口調(diào)試工具,例如XCOM、SSCOM等,將波特率、停止位、校驗位等參數(shù)調(diào)至即將需要通信的模塊的參數(shù),再去隨意發(fā)送一些數(shù)據(jù),通常筆者是更傾向于使用16進(jìn)制發(fā)送和接收,以此來保證數(shù)據(jù)中間或者結(jié)尾出現(xiàn)一些不可使用ASCII值直觀看到的數(shù)據(jù),例如數(shù)據(jù)的結(jié)尾多了0x00,0x0a等。若確保自己的工具以及導(dǎo)線沒有問題后,即可繼續(xù)排查通信問題
2、發(fā)現(xiàn)使用USB轉(zhuǎn)TTL與模塊之間明明已經(jīng)反接了TX、RX,發(fā)指令給模塊之后卻沒有任何反應(yīng)。
解決方法:當(dāng)碰到如上問題時,應(yīng)當(dāng)首先自檢工具,再檢查是否雙方共地,GND提供了一個基準(zhǔn)0電平,如果沒有共地的話,那極有可能會出問題,其次是檢查雙方的串口參數(shù)是否一致,串口通信是一個易于開發(fā)并且速度可調(diào)的一個的通信協(xié)議,其中我們大部分都會使用UART——通用異步傳輸接收/發(fā)送器,串口異步通信也可稱為起止式異步通信,是直接以字符為單位進(jìn)行傳輸?shù)?,字符之間沒有固定的時間要求,每個字符中的每一位以固定的時間傳送。這就意味著,如果你使用一個較為高的波特率的速度去與一個較為低的波特率的速度去通信的話,那極大可能會導(dǎo)致低波特率設(shè)備無法讀取到通信時的空閑信號的跳變信息。在這里我用一個比較極端例子進(jìn)行說明:
當(dāng)雙方串口的參數(shù)的數(shù)據(jù)位都為8bit,停止位為1bit,校驗位為0bit時,但是A設(shè)備的波特率為9600,B設(shè)備為921600,就會出現(xiàn)以下情況:
當(dāng)B設(shè)備向A設(shè)備發(fā)送一個字節(jié)的數(shù)據(jù)時,B設(shè)備從發(fā)送到結(jié)束所需用的時間為1/921600*(8+1+1)=10.8us,而相同的A設(shè)備發(fā)送/接收一個字節(jié)的時間為(8+1+1)/9600=1.04ms,試問,像這種相差數(shù)倍的時間,當(dāng)高波特率發(fā)送給低波特率設(shè)備時,很有可能低波特率設(shè)備壓根就不會認(rèn)為發(fā)送過來的數(shù)據(jù)流是一串?dāng)?shù)據(jù),因為壓根沒法解析到。
因此串口通信一定要保證雙方波特率、停止位等參數(shù)一致。反之,低波率向高波特率發(fā)送數(shù)據(jù)就會被認(rèn)為是錯誤的數(shù)據(jù),也就是所謂的亂碼。
3、發(fā)現(xiàn)雙方已經(jīng)使用了相同的參數(shù)進(jìn)行通信,但是依舊通信有問題,例如收到亂碼等。
解決方法:首先應(yīng)該降低波特率先確保模塊與USB轉(zhuǎn)TLL均無問題,也要確保模塊沒有處于透傳等特殊情況下,也可以使用邏輯分析儀等工具進(jìn)行排查,現(xiàn)在的很多邏輯分析儀是自帶數(shù)據(jù)分析的,可以由此來確保模塊正常。其實大部分碰到這種問題的時候,更建議優(yōu)先查看USB轉(zhuǎn)TLL是否支持當(dāng)前的工作模式。
4、串口通信的弱點?
1)信號干擾的問題建議使用帶屏蔽線,接線要嚴(yán)格,比如要接地。有些485通信上,還考慮接上終端電阻來匹配。如果是232,盡量不要讓線太長。通信協(xié)議上盡量避免長報文的數(shù)據(jù)通信。
2)波特率匹配的問題因為有些設(shè)備的計算的波特率是存在誤差的,特別是一些控制器,由于使用的晶振不一樣。因此在一些波特率比如9600波特率就存在誤差。存在誤差帶來的影響是什么呢。因為接收方是通過時間來計算一個位的。那么如果一個報文過長,就會存在誤差積累的問題,算著算著就偏了。所以,這也是串口通信不穩(wěn)定的一些地方,在使用上應(yīng)注意避免發(fā)送太長數(shù)據(jù)的包。
3)在一些可能會存在干擾的情況,可以考慮使用奇校驗或者偶校驗因為雖說出現(xiàn)錯誤的可能性不大,但既然存在干擾,如果加了校驗,至少可以把錯誤的報文過濾掉。總好比沒有校驗然后通信數(shù)據(jù)錯了不知道?;蛘弑M量使用一些帶校驗的協(xié)議,防止數(shù)據(jù)出錯。
4)串口通信本來就比較慢,請降低對數(shù)據(jù)響應(yīng)的要求因為串口通信本身就比以太網(wǎng)慢。而且,串口通信并不是能像CPU那樣多線程處理。因為就一個口一個線數(shù)據(jù)出去,即便你應(yīng)用到程序再怎么用多線程處理數(shù)據(jù),但是最底下也只有一個口出去,一次也只能傳一個位,一個字節(jié)過去。因為有客戶在使用9600的波特率通信,但是又希望多少的數(shù)據(jù)可以在多少毫秒內(nèi)得到響應(yīng)。
但是串口通信還是要實事求是,所以正確認(rèn)識串口通信對應(yīng)用,對開發(fā),對溝通都有著很大的幫助的。
5、為什么不用同步通信?
剛才提到,同步通信需要依賴于時鐘信號。這就存在一個問題,這個時鐘信號是誰來發(fā)起呢。在同步通信中,往往需要一個主設(shè)備發(fā)起時鐘信號讀從模塊的數(shù)據(jù)。在實際中,有屏讀PLC,有屏讀屏的數(shù)據(jù)。而單純地從異步串口通信來說,是沒有主從之說,雙方都是平等的角色,都可以互發(fā)信息,互收信息。而同步通信一般是應(yīng)用于CPU讀一些模塊,由CPU發(fā)起時鐘信號,比如讀SD卡模塊,就可以通過SPI方式,還有一些傳感器模塊。