RS232、RS485和TTL
作為一個底層軟件開發工程師,經常會碰到RS232、RS485和TTL這一類的問題。
之前總是碰到問題之后Google一下,把當下的問題解決了之后就不管了,過個一兩天就忘得一干二凈,結果后續每次都會碰到類似的問題,都是從零開始地去解決,這種方式看起來當時快速解決了問題,結果在后續的開發中浪費了更多的時間。
為了解決這個問題,博主決定一次性把這些東西給弄清楚
串行通信
串行通信是指 使用一條數據線,將數據一位一位地依次傳輸,每一位數據占據一個固定的時間長度。
其只需要少數幾條線就可以在系統間交換信息,特別適用於計算機與計算機、計算機與外設之間的短距離通信。
串行通信在傳輸方式上分為同步通信和異步通信,在傳輸方向上分為單工通信,半雙工通信,全雙工通信。
同步通信
顧名思義,同步通信需要通信雙方進行數據同步,一般表現為通信雙方在時鍾線上的統一,雙方在在數據的收發上是同時的,根據時鍾線的跳變來操作數據線實現發送(讀取),常用的同步協議有SPI I2C。
異步通信
異步通信不需要建立數據同步即可傳輸數據,發送方按照一定的協議格式來發送數據,接收方接收到數據再根據協議進行解析,雙方的收發不需要同時進行,也不需要進行傳輸時的校驗,RS232,485和UART就屬於這一類。
同步通信和異步通信的比較
在這里,我們不妨可以先思考一下,同步通信和異步通信最根本的區別是什么?
同步通信,通信雙方遵循相同的時鍾,每一個幀數據的收發都是需要經過雙方共同確認,然后再進行下一幀傳輸。
而異步通信則不然,在發送發看來,需要發送數據的時候,只負責把數據發出去就行了,接受方到底收沒收到或者怎么解析不需要發送方操心。
從上述的原理上的區別出發,我們以發送0x55(01010101b)為例,可以發現兩者通信的區別:
在同步發送中,數據線上只需要根據時鍾發送數據01010101,接收方同時也可以根據時鍾來解析收到的數據。
但是在異步發送中,因為沒有時鍾同步,如果發送方僅僅將數據01010101發送出來,接收方無法解析接收到的數據。原因有兩個:
-
接收方不知道數據是以一個什么樣的間隔時間發送過來的,可能發送方的時鍾頻率和配置決定了發送為1bit/us,但是接收方的時鍾配置不一致,就出現解析錯誤。
-
接受方無法判斷數據的開始和結束,如果數據線的默認電平為高,發送數據的第一位也為高,將難以判斷數據是從哪里開始。
所以,針對這兩個問題,異步通信提出了兩個相應的解決方案:
- 通信雙方遵循相同的傳輸速率,即波特率
- 在通信協議中加入開始位,結束位,校驗位以實現數據的接收時解析。
同步通信和異步通信的優劣
-
可以看出,同步通信中的數據傳輸效率(注意是效率,非速率)要高於異步傳輸,同步傳輸效率一般能達到100%,而異步傳輸中傳輸的數據並非全是有效數據,像串口協議中,常用配置中(1停止位,無校驗)傳輸一個字節需要傳送10bit。
-
在更復雜的應用中,同步傳輸可以做到點對多點的傳輸,多點可以共用一個時鍾線,可以輕松實現一點寫,多點讀的操作。而在異步通信中,無法確定接收方接收數據的時間,所以不適用於點對多點的傳輸。
-
在相同的時鍾頻率下,傳輸效率高的同步通信自然能達到更高的數據吞吐量。
-
異步傳輸在傳輸效率上比同步傳輸低,但是同時也省去了同步所需要的時間,尤其是在遠距離傳輸時,時鍾同步所帶來的開銷也是不容忽視的,所以在長距離的傳輸中,一般使用異步通信,如RS485就支持KM級別的距離傳輸,而SPI I2C一般都用於板級通信。
-
異步傳輸不需要時鍾線,更容易實現且節省資源。
單工通信
單工即單向通信,在整個數據傳輸的過程中只允許定向地傳輸數據
半雙工通信
雙工即雙向通信,半雙工指的是在同一時刻,只允許一個方向的發送接收,就像兩個人打電話,A可以對B說話,B可以對A說話,但是A/B不能同時說話,那樣會造成混亂。
全雙工通信
全雙工通信就是允許數據在兩個方向上同時傳輸。數據的收和發之間不會相互影響。
RS232 RS485 TTL電平
RS232 RS485 TTL同屬於異步串行通信,這三種通信方式本質上是電平邏輯的區別。
RS232
RS232多用於電腦的串口,目前使用最廣泛的就DB9接口,即九線接口,目前一般的電腦主機后面都會有這樣的接口.
RS232電平采用負邏輯,
-15V ~ -3V 代表邏輯1
+3V ~ +15V 代表邏輯0
-3V ~ +3V 無意義
在早期還有DB25線的接口,后來IBM將標准改成9線接口。
這種信號傳輸方式決定了一根數據線即可實現數據傳輸,所以兩根信號線(TX RX)即可實現全雙工地數據傳輸,上圖中的其他信號腳類似於RTS/CTS等都是用於差錯控制,在較簡單的應用中只需要GND RX TX即可。
RS232電平傳輸方式有一些明顯的缺點:
- 接口的信號電平值相對太高,容易損壞接口電路的芯片。
- 傳輸速率比較低,在異步傳輸時,波特率只有20Kbps。
- 接口使用一根信號線和一根信號返回線回路構成共地的傳輸模式,很容易產生共模干擾,所以抗噪聲比較弱。
- 由於抗干擾能力弱,易產生共模干擾,所以傳輸距離並不遠。
針對RS232在這些方面的不足,於是不斷出現了一些新的標准,其中RS485是使用比較廣泛的標准。
RS485
RS485多用於長距離傳輸的應用場景,大多數是在工業場景中,RS485電平邏輯采用差分電平,即傳輸數據至少需要兩根信號線,根據兩根信號線電壓的差值來確定電平邏輯,發送端電平:
+2V ~ +6V 代表邏輯1
-2V ~ -6V 代表邏輯0
其他 無意義
接收端電平:
> +200mv 代表邏輯1
< -200mv 代表邏輯0
其他 無意義
由於在傳輸數據時需要兩根信號線同時工作,所以RS485只能做到半雙工通信,在RS232上依然有以下優化:
- 差分信號抗干擾能力強
- 傳輸距離大大加長,可以達到KM級別的傳輸
- 相對應RS232而言可以支持多點傳輸甚至聯網構成分布式系統。
- 傳輸速率可達到10M/bps。
TTL電平
目前我們熟知的單片機基本上都是使用的TTL電平的信號系統,這是計算機處理器控制的設備內部各部分之間通信的通信標准。
TTL集成電路的全名是晶體管-晶體管邏輯集成電路(Transistor-Transistor Logic)。在傳統的單片機系統中,VCC(供電電壓)為5V,電平標准為:
輸出:
小於0.8V 代表邏輯0
大於2.4V 代表邏輯1
輸入:
小於1.2V 代表邏輯0
大於2.0V 代表邏輯1
其他 無意義
因為2.4V和5V之間還有很大的空閑,白白增加了系統的功耗,同時影響了速度,所以來后就把一部分砍掉了,也就是后來的LVTTL,LVTTL又分為3.3V、2.5V甚至更低電壓的LVTTL(Low Voltage TTL).在3.3V LVTTL,Vcc = 3.3V中,電平標准為:
輸出:
大於2.4V 代表邏輯1
小於0.4V 代表邏輯0
輸入:
小於0.8V 代表邏輯0
大於2V 代表邏輯1
其他 無意義
TTL電平輸入腳懸空時是內部認為是高電平。要下拉的話應用1k以下電阻下拉。
TTL電平無法進行長距離傳輸,抗干擾能力弱,信號衰減較大。
TTL電平為邏輯電平而設計,基本用於板級通信,單片機基本上都使用TTL信號系統。
無意義的電平
在上面的電平描述中,都提到了無意義的電平,事實上在數據的接收中,如果接收到一個無意義的電平,這時候的邏輯輸出是不確定的,有可能是正確的,有可能是錯誤的。
例如,RS232的系統中,需要傳輸數據0x55(01010101b),但是在傳輸過程中由於干擾,最低位的數據1電平在接收端為0V,即無意義電平,其他位正常,這時候在接收端的解析中可能出現接收數據為0x54和0x55的結果,即無意義電平的解析是不確定的,可能是正確結果,也可能不是。
串行通信流控
串行通信中的流控制
這里講到的流,指的是數據流,數據在兩個串口之間傳輸時,常常出現一些意料之外的情況,比如通信雙方速率不一致,又或者是接收端緩沖區溢出導致數據丟失等等。
流控制專門為了解決這些問題而生,例如,當接收端的數據處理不過來時,就可以發出“不再接收”的信號,發送端收到信號馬上停止發送,等接收端可以繼續接收之后,再發送“繼續接收”的信號提醒發送端繼續發送。
流控制一般分為硬件流控制和軟件流控制,顧名思義,硬件流控制需要硬件上的支持,常用的有rts/cts,dts/cts信號線,流控制的信號在這些信號線上傳輸,而軟件流控制則是由軟件來實現,在傳輸過程中定義特殊字段來作為流控制信號。
硬件流控制
硬件流控制必須將相應的電纜線連上,用rts/cts(請求發送/清除發送)流控制時,應將通訊兩端的rts、cts線對應相連,數據終端設備(如計算機)使用rts來起始調制解調器或其它數據通訊設備的數據流,而數據通訊設備(如調制解調器)則用cts來起動和暫停來自計算機的數據流。
這種硬件握手方式的過程為:
在編程時根據接收端緩沖區大小設置一個高位標志(可為緩沖區大小的75%)和一個低位標志(可為緩沖區大小的25%),當緩沖區內數據量達到高位時,我們在接收端將cts線置低電平(送邏輯0)。
當發送端的程序檢測到cts為低后,就停止發送數據,直到接收端緩沖區的數據量低於低位而將cts置高電平。
rts則用來標明接收設備有沒有准備好接收數據。
軟件流控制
由於電纜線的限制,我們在普通的控制通訊中一般不用硬件流控制,而用軟件流控制。一般通過xon/xoff來實現軟件流控制。
常用方法是:當接收端的輸入緩沖區內數據量超過設定的高位時,就向數據發送端發出xoff字符(十進制的19或control-s,設備編程說明書應該有詳細闡述),發送端收到xoff字符后就立即停止發送數據;當接收端的輸入緩沖區內數據量低於設定的低位時,就向數據發送端發出xon字符(十進制的17或control-q),發送端收到xon字符后就立即開始發送數據。一般可以從設備配套源程序中找到發送的是什么字符。
但是這種流控制僅僅適用於字符流傳輸的情況,如果是傳輸二進制數據,很可能數據內容中就帶有xoff字符導致出現差錯,所以軟件流控制還是有比較大的缺陷。
不同電平之間的相互轉換
在嵌入式的軟件開發過程中,經常要用到不同設備之間的串口通信,既然這些串口分屬於不同的電平信號系統,自然是不能直接進行通信的。
比如:將RS232的TX連接到TTL電平的RX時,發送端發送邏輯0信號為+10V,但是+10V的信號很可能直接將TTL端的芯片損壞,因為TTL端只支持0~5V的電平,所以在雙方進行通信的時候,需要對電平進行轉換才能進行通信。
對於電平的轉換,網上已經有非常成熟的方案可以直接使用:
好了,關於串行通信的問題討論就到此為止了,如果朋友們對於這個有什么疑問或者發現有文章中有什么錯誤,歡迎留言
個人郵箱:linux_downey@sina.com
原創博客,轉載請注明出處!
祝各位早日實現項目叢中過,bug不沾身.
(完)
TTL電平部分參考:https://blog.csdn.net/lijiuyangzilsc/article/details/48599745