換詳解:從UART到DB9串口通信)
之前在做一塊 STM32 控制板的時(shí)候調(diào)試上位機(jī)通信時(shí)發(fā)現(xiàn)一個(gè)很典型的現(xiàn)象用 USB 轉(zhuǎn) TTL 線連接一切正常換成電腦主板自帶的 DB9 串口后卻完全收不到數(shù)據(jù)甚至把主板串口芯片燒掉過一次。排查到最后問題根源就在 RS232 電平 和 TTL 電平 的轉(zhuǎn)換上。很多剛接觸嵌入式的朋友對(duì) RS232、TTL、UART、串口這幾個(gè)詞往往是一頭霧水。實(shí)際上它們描述的是不同維度的問題UART 是一種通信時(shí)序協(xié)議TTL 是數(shù)字芯片內(nèi)部使用的邏輯電平標(biāo)準(zhǔn)而 RS232 則是一套完整的串行通信電氣標(biāo)準(zhǔn)。本文就從這里開始把 RS232 電平、RS232 串口接線、常用電平轉(zhuǎn)換電路、調(diào)試方法和工程坑點(diǎn)一次講透幫助大家少走彎路。1. RS232 是什么先理清 UART、RS232、TTL 的關(guān)系1.1 為什么初學(xué)者經(jīng)常被這三個(gè)詞搞混我先說一個(gè)常見場(chǎng)景你在淘寶上買了一塊“USB 轉(zhuǎn) RS232”小板然后在設(shè)備管理器中看到的是 CH340 或者 FTDI 芯片插上電腦后出現(xiàn)的是 COM 口。于是你自然地以為這個(gè) COM 口輸出的一定就是 RS232 電平。但實(shí)際拆開外殼你會(huì)發(fā)現(xiàn)很多“USB 轉(zhuǎn) RS232”小板其實(shí)只是 USB 轉(zhuǎn) TTL只是把 DB9 接頭做成了 RS232 的外形內(nèi)部是否有真正的 RS232 電平轉(zhuǎn)換電路是看不出來的。另外你去查閱單片機(jī)串口外設(shè)時(shí)又看到大量關(guān)于“UART”的講解它和 RS232 好像講的是同一件事可電平又不完全一致。這種混亂的根源在于UART、RS232、TTL 分別是協(xié)議層、電氣標(biāo)準(zhǔn)層、邏輯電平層的概念它們?cè)谠O(shè)備中層層疊疊但并不是等價(jià)替換關(guān)系。1.2 三者的定義區(qū)分UART 是通用異步收發(fā)器它規(guī)定了數(shù)據(jù)按幀傳輸?shù)臅r(shí)序一個(gè)起始位、5/6/7/8 個(gè)數(shù)據(jù)位、一個(gè)可選的校驗(yàn)位、一個(gè)或多個(gè)停止位。它不關(guān)心信號(hào)電壓到底是多少伏只關(guān)心高低電平變化是否符合時(shí)序。RS232 串口通信中最常采用的底層協(xié)議就是 UART。TTL 電平是數(shù)字芯片內(nèi)部使用的邏輯電平標(biāo)準(zhǔn)。常見的 5V TTL 系統(tǒng)中高電平為 2V 到 5V低電平為 0V 到 0.8V3.3V 系統(tǒng)中高電平則最高到 3.3V。它使用正邏輯用高電平表示邏輯 1低電平表示邏輯 0。RS232是 EIA美國(guó)電子工業(yè)協(xié)會(huì)制定的一套串行通信電氣標(biāo)準(zhǔn)全稱是 RS-232C 或 EIA-232。它除了定義電平范圍還定義了接口引腳、時(shí)序關(guān)系、機(jī)械連接方式等內(nèi)容是 20 世紀(jì)中后期電腦與 Modem、鼠標(biāo)、工業(yè)設(shè)備之間最常用的串行接口之一。簡(jiǎn)單來說單片機(jī)內(nèi)部通過 UART 外設(shè)把并行數(shù)據(jù)變成串行數(shù)據(jù)然后以 TTL 電平輸出如果要把信號(hào)發(fā)送到 RS232 標(biāo)準(zhǔn)的 DB9 接口就必須經(jīng)過電平轉(zhuǎn)換芯片把 TTL 電平變換成 RS232 電平同時(shí)還要把 TX、RX 方向上的信號(hào)分別做邏輯反向。1.3 RS232 的典型應(yīng)用場(chǎng)景現(xiàn)在雖然新電腦已經(jīng)很少直接帶 DB9 串口但 RS232 在工業(yè)控制、儀器儀表、通信設(shè)備等領(lǐng)域依然活躍典型場(chǎng)景包括工控觸摸屏與 PLC、單片機(jī)控制器通信例如維綸通、昆侖通態(tài)觸摸屏的 COM 口?;魇?KV 系列 PLC 與上位機(jī)通信。迪文串口屏、組態(tài)屏與主控板之間進(jìn)行指令交互。老式數(shù)控機(jī)床、稱重儀表、UPS 監(jiān)控接口。銀行 POS 機(jī)、醫(yī)療設(shè)備等對(duì)穩(wěn)定性要求高的低速通信場(chǎng)合。在這些場(chǎng)景里RS232 電平標(biāo)準(zhǔn)仍然被作為工業(yè)設(shè)備之間的“通用語言”所以掌握 RS232 串口的電平定義、引腳含義和轉(zhuǎn)換電路是做嵌入式開發(fā)和工業(yè)通信調(diào)試的基礎(chǔ)功。2. RS232 電平到底是多少伏2.1 RS232 電平的電壓范圍標(biāo)準(zhǔn)RS232 標(biāo)準(zhǔn)規(guī)定的電平范圍如下信號(hào)邏輯狀態(tài)電壓范圍典型電壓發(fā)送端邏輯 0數(shù)據(jù) 05V ~ 15V12V發(fā)送端邏輯 1數(shù)據(jù) 1-5V ~ -15V-12V接收端邏輯 03V ~ 15V—接收端邏輯 1-3V ~ -15V—未定義區(qū)域—-3V ~ 3V—注意兩個(gè)關(guān)鍵點(diǎn)第一RS232 使用的是負(fù)邏輯。這和 TTL 恰好相反TTL 中高電平代表邏輯 1低電平代表邏輯 0而在 RS232 中正電壓12V 附近代表邏輯 0負(fù)電壓-12V 附近代表邏輯 1。第二RS232 接收端允許的電壓范圍比發(fā)送端寬從 3V 到 15V 都可以識(shí)別為邏輯 0從 -3V 到 -15V 都可以識(shí)別為邏輯 1。也就是說接收端有 2V 左右的噪聲容限這比 TTL 的噪聲容限大不少因此 RS232 在較長(zhǎng)距離的工業(yè)通信中比裸 TTL 抗干擾能力更強(qiáng)。2.2 TTL 電平標(biāo)準(zhǔn)與 3.3V/5V 系統(tǒng)常見的 TTL 電平分為兩類5V TTL 系統(tǒng)邏輯 1高電平2V ~ 5V通常在輸出端約為 5V。邏輯 0低電平0V ~ 0.8V。3.3V CMOS/LVTTL 系統(tǒng)邏輯 1高電平2V ~ 3.3V。邏輯 0低電平0V ~ 0.8V。有了上面的對(duì)比你就會(huì)明白為什么單片機(jī)的 TX/RX 引腳不能直接接到 RS232 DB9 接口上RS232 空閑時(shí)輸出為 -12V 左右的邏輯 1而單片機(jī)引腳如果輸入負(fù)壓輕則導(dǎo)致內(nèi)部 ESD 保護(hù)二極管導(dǎo)通重則燒毀引腳。RS232 的數(shù)據(jù) 0 是 12V 左右遠(yuǎn)超 3.3V 或 5V 單片機(jī)引腳耐壓范圍直接連接可能損壞單片機(jī)。反過來單片機(jī)輸出的 TTL 高電平一般只有 3.3V 或 5V正電壓幅度達(dá)不到 RS232 接收端要求的 3V 以上倒還好但 TTL 低電平是 0VRS232 接收端會(huì)把它當(dāng)成“未定義區(qū)域”不能可靠識(shí)別。所以在任何需要連接真實(shí) RS232 設(shè)備的電路中電平轉(zhuǎn)換電路都是必須的而不是可選項(xiàng)。2.3 那 -12V 是從哪里來的很多初學(xué)者會(huì)問一個(gè)問題電腦主板上的串口怎么會(huì)有 -12V難道是主板上還有一個(gè) -12V 電源嗎確實(shí)有。PC 主板的 PCI/ISA 電源總線上會(huì)提供 -12V 這一路電源但它的驅(qū)動(dòng)能力非常弱電流一般只有幾百毫安甚至更小。而 RS232 需要的正是這種“正負(fù)雙電源”的環(huán)境。單獨(dú)靠單片機(jī)控制板上的 3.3V 或 5V 單電源是沒有負(fù)壓來源的所以才會(huì)用 MAX232 這類電荷泵芯片來產(chǎn)生 -12V 左右的電壓這也就是很多電平轉(zhuǎn)換芯片內(nèi)部都內(nèi)置“電荷泵”的原因。3. RS232 串口接口與引腳定義3.1 DB9 引腳的定義提到 RS232 串口很多人第一反應(yīng)是那個(gè)梯形 DB9 插頭。DB9 分為公頭帶針和母頭帶孔兩種常見引腳定義如下引腳號(hào)信號(hào)名稱作用說明方向以 DTE 為準(zhǔn)1DCDCarrier Detect 載波檢測(cè)輸入2RXDReceive Data 接收數(shù)據(jù)輸入3TXDTransmit Data 發(fā)送數(shù)據(jù)輸出4DTRData Terminal Ready 數(shù)據(jù)終端就緒輸出5GNDSignal Ground 信號(hào)地—6DSRData Set Ready 數(shù)據(jù)設(shè)備就緒輸入7RTSRequest To Send 請(qǐng)求發(fā)送輸出8CTSClear To Send 允許發(fā)送輸入9RIRing Indicator 振鈴指示輸入這 9 個(gè)引腳中真正用于最基本數(shù)據(jù)通信的只有 2RXD、3TXD、5GND三根。其他引腳用于 Modem 撥號(hào)、流控和鏈路檢測(cè)等擴(kuò)展功能我們做普通的 RS232 串口通信時(shí)不一定全部要用。這里有個(gè)容易混淆的點(diǎn)DB9 公頭 2 腳是 RXD、3 腳是 TXD這是針對(duì) DTE 設(shè)備例如電腦而言的。很多 DB9 面板上標(biāo)注的 TXD 是指這個(gè)設(shè)備自己的發(fā)送腳而不是對(duì)面設(shè)備的發(fā)送腳。所以實(shí)際的串口調(diào)試中不要只看公頭還是母頭要看當(dāng)前板上信號(hào)的功能定義。3.2 最簡(jiǎn)單通信最少需要哪幾根線在設(shè)計(jì) RS232 通信電路時(shí)如果只是收發(fā)數(shù)據(jù)不做硬件流控那么三線制接法就夠了設(shè)備 A 的 TXD 接設(shè)備 B 的 RXD。設(shè)備 A 的 RXD 接設(shè)備 B 的 TXD。兩邊的 GND 接 GND。也就是說信號(hào)線需要交叉連接。很多新手把兩塊開發(fā)板用“TXD 接 TXD、RXD 接 RXD”的排線直接連結(jié)果兩邊都收不到數(shù)據(jù)。這本質(zhì)上就是因?yàn)闆]有理解發(fā)送端必須連接對(duì)端的接收端。如果是兩個(gè)串口設(shè)備之間通過 DB9 直連通常要做成交叉線即“2 對(duì) 3、3 對(duì) 2、5 對(duì) 5”。市面上某些成品 DB9 線是直通線用于連接電腦與 Modem 這類 DTE-DCE 組合而用于電腦與單片機(jī)調(diào)試板如果單片機(jī)板子模擬 DTE時(shí)多半需要交叉線買線材時(shí)要特別留意。3.3 如何判斷你手上的串口是 TTL 還是 RS232拿到一塊板子或者一個(gè)轉(zhuǎn)接器時(shí)最穩(wěn)妥的方法不是看絲印而是直接用萬用表測(cè)量串口的空閑狀態(tài)電壓如果 TXD/RXD 空閑時(shí)測(cè)量到 -5V ~ -12V 左右說明這是 RS232 電平。如果 TXD/RXD 空閑時(shí)測(cè)量到 3.3V 或 5V說明這是 TTL 電平。如果 TXD 上測(cè)量到 0V 且 RXD 上有 3.3V 之類的電壓要檢查芯片是否已經(jīng)進(jìn)入發(fā)送狀態(tài)或電路是否正常。一個(gè) RS232 收發(fā)器在空閑時(shí)TXD 輸出端應(yīng)該保持邏輯 1也就是負(fù)電壓。假如你測(cè)量 USB 轉(zhuǎn) RS232 線的 TXD 在空閑時(shí)是 5V 或 3.3V那么這根線大概率只是 USB 轉(zhuǎn) TTL并不能直接連接標(biāo)準(zhǔn)的 RS232 設(shè)備。4. 電平轉(zhuǎn)換電路TTL 和 RS232 之間到底怎么轉(zhuǎn)4.1 為什么不能直接連接我們已經(jīng)知道TTL 高電平是 3.3V/5V低電平是 0VRS232 的邏輯 1 是負(fù)電壓邏輯 0 是正電壓。從數(shù)學(xué)上看TTL 高電平對(duì)應(yīng) RS232 邏輯 0正電壓TTL 低電平對(duì)應(yīng) RS232 邏輯 1負(fù)電平所以電平轉(zhuǎn)換不僅要做電平幅度的搬移還要做一個(gè)邏輯反向。如果用一句話描述電平轉(zhuǎn)換電路的作用就是把單片機(jī)的“3.3V/5V 正邏輯串口”變換為“±12V 負(fù)邏輯串口”同時(shí)保護(hù)兩端芯片不被對(duì)方的高壓或負(fù)壓損壞。4.2 方案一使用 MAX232/SP3232 專用收發(fā)芯片這是最推薦、也最穩(wěn)定的方案。MAX232 系列芯片內(nèi)置電荷泵只需要單電源供電就能產(chǎn)生正負(fù)兩路 RS232 電源電壓內(nèi)部還集成了兩路發(fā)送器和兩路接收器可以同時(shí)處理 TX、RX 兩路信號(hào)。SP3232 是 MAX232 的低功耗替代型號(hào)兼容 3.3V 和 5V 供電也常用于便攜式設(shè)備。典型接線思路如下MAX232 引腳連接對(duì)象VCC5V部分型號(hào)支持 3.3V按芯片手冊(cè)GND電源地C1、C1-、C2、C2-4 只 0.1uF 電荷泵電容V電荷泵輸出正電壓通常接 0.1uF 電容到地V-電荷泵輸出負(fù)電壓通常接 0.1uF 電容到地T1IN單片機(jī) TXDTTL 輸入T1OUTRS232 TXD 發(fā)送輸出R1INRS232 RXD 接收輸入R1OUT單片機(jī) RXDTTL 輸出用 C 語言偽代碼描述一遍連接后的初始化流程// 單片機(jī) UART 初始化示意以 STM32 HAL 庫為例具體參數(shù)按芯片型號(hào)調(diào)整 UART_HandleTypeDef huart1; void MX_USART1_UART_Init(void) { huart1.Instance USART1; huart1.Init.BaudRate 9600; huart1.Init.WordLength UART_WORDLENGTH_8B; huart1.Init.StopBits UART_STOPBITS_1; huart1.Init.Parity UART_PARITY_NONE; huart1.Init.Mode UART_MODE_TX_RX; huart1.Init.HwFlowCtl UART_HWCONTROL_NONE; huart1.Init.OverSampling UART_OVERSAMPLING_16; if (HAL_UART_Init(huart1) ! HAL_OK) { Error_Handler(); } }在這個(gè)例子中單片機(jī)這一側(cè)的 USART1_TX 就會(huì)輸出 TTL 電平的串口數(shù)據(jù)把它接到 MAX232 的 T1INMAX232 的 T1OUT 就輸出了 RS232 電平的串行數(shù)據(jù)可以連接外部 RS232 設(shè)備的 RXD。4.3 方案二三極管分立電平轉(zhuǎn)換電路在某些低成本、對(duì)功耗不敏感的板卡上也會(huì)看到用三極管實(shí)現(xiàn)電平轉(zhuǎn)換的電路。不過需要先說明三極管分立轉(zhuǎn)換電路要做到真正符合 RS232 標(biāo)準(zhǔn)的 ±12V 輸出必須有正負(fù)雙電源否則輸出往往只是“0V 到 5V”或“0V 到 12V”的單極性信號(hào)無法達(dá)到標(biāo)準(zhǔn) RS232 接收端的負(fù)電平要求。一種常見思路是采用 NPN PNP 對(duì)管做發(fā)送端。以 TTL 輸入信號(hào)為例TTL 輸入為高電平時(shí)NPN 管導(dǎo)通、PNP 管截止輸出端被拉到接近負(fù)電源電壓。TTL 輸入為低電平時(shí)NPN 管截止、PNP 管導(dǎo)通輸出端被拉到接近正電源電壓。這個(gè)電路本質(zhì)上是一個(gè)推挽反相器。它能實(shí)現(xiàn) TTL 到 RS232 的邏輯反向和電平搬移前提是你手頭有 12V 和 -12V 兩路電源。實(shí)際產(chǎn)品如果想省掉 -12V 電源也可以用電荷泵產(chǎn)生負(fù)壓但那本質(zhì)上又回到了 MAX232 的內(nèi)部原理。我個(gè)人的建議是如果只是做實(shí)驗(yàn)、學(xué)原理三極管電路可以幫助你理解電平轉(zhuǎn)換的本質(zhì)但如果做產(chǎn)品或者調(diào)試穩(wěn)定性要求較高的工業(yè)設(shè)備直接選 MAX232/SP3232/MAX3232 這類集成芯片外圍元器件少、一致性好、故障率低。4.4 方案三使用 USB 轉(zhuǎn)串口小板調(diào)試在開發(fā)階段最常用的是 USB 轉(zhuǎn)串口調(diào)試方案。這里要區(qū)分兩類產(chǎn)品一類是“USB 轉(zhuǎn) TTL”常見主控是 CH340、CH341、CP2102、FT232。它輸出的是 TTL 電平不能直接連接 RS232 設(shè)備只能連接單片機(jī)或 TTL 接口外圍模塊。另一類是“USB 轉(zhuǎn) RS232”常見做法是在 USB 轉(zhuǎn) TTL 芯片后面再加一個(gè) MAX232 之類的 RS232 收發(fā)器最終輸出到 DB9 座子。這類產(chǎn)品的 TXD 在空閑時(shí)測(cè)出來才是負(fù)電壓。很多調(diào)試器品牌還支持免驅(qū)動(dòng)或自動(dòng)安裝驅(qū)動(dòng)但如果你使用 CH340/CH341 芯片第一次接上電腦后如果驅(qū)動(dòng)沒自動(dòng)裝上可以考慮到芯片官網(wǎng)下載對(duì)應(yīng)系統(tǒng)的驅(qū)動(dòng)FTDI 芯片也在官網(wǎng)提供全平臺(tái)驅(qū)動(dòng)。Windows 下確認(rèn)設(shè)備管理器中能看到 COM 口號(hào)后再用串口助手打開。5. RS232 通信過程與典型調(diào)試驗(yàn)證5.1 一幀數(shù)據(jù)到底長(zhǎng)什么樣RS232 串口通信采用異步幀格式常見配置是 8 個(gè)數(shù)據(jù)位、無校驗(yàn)位、1 個(gè)停止位也就是常說的 8N1。一幀數(shù)據(jù)包括以下部分空閑狀態(tài)線路處于邏輯 1對(duì)應(yīng) RS232 電平就是負(fù)電壓。起始位線路跳變到邏輯 0對(duì)應(yīng)正電壓表示一幀數(shù)據(jù)的開始。數(shù)據(jù)位從最低位 LSB 開始發(fā)送依次發(fā)送 8 個(gè)數(shù)據(jù)位。停止位線路回到邏輯 1持續(xù) 1 位時(shí)間表示一幀結(jié)束。你可以把 9600 波特率下的每一位時(shí)間估算為約 104us而 115200 波特率下每一位時(shí)間約為 8.68us。波特率越高每一位時(shí)間越短對(duì)線纜電容和收發(fā)器驅(qū)動(dòng)能力的要求也越高。發(fā)送一個(gè) ASCII 字符A十六進(jìn)制 0x41二進(jìn)制 01000001時(shí)線路上的電平變化順序?yàn)槠鹗嘉?0) - 數(shù)據(jù)位:1 - 0 - 0 - 0 - 0 - 0 - 1 - 0 - 停止位(1)注意數(shù)據(jù)位是從 LSB 開始發(fā)送所以0x41的最低位 1 最先出現(xiàn)在線上最高位 0 最后出現(xiàn)在線上。5.2 用示波器觀察 RS232 電平調(diào)試 RS232 電平是否正常強(qiáng)烈建議用示波器或者邏輯分析儀直接觀察 TXD 波形。下面是使用示波器時(shí)的判斷要點(diǎn)空閑時(shí)RS232 的 TXD 應(yīng)該是 -3V 到 -15V 之間的負(fù)電壓。發(fā)送數(shù)據(jù)時(shí)起始位會(huì)跳變到 3V 到 15V 之間的正電壓。數(shù)據(jù)位中每一位正負(fù)電平持續(xù)時(shí)間應(yīng)與波特率吻合。例如讓串口持續(xù)發(fā)送 0x55二進(jìn)制 01010101示波器上應(yīng)該看到方波頻率等于波特率的一半。如果發(fā)送 0x01則可以看到單個(gè)低電平脈沖后回到高電平的波形。如果示波器顯示 TXD 空閑時(shí)為 0V或者發(fā)送時(shí)最高只有 3.3V、最低只有 0V說明你的轉(zhuǎn)換電路并沒有真實(shí)輸出 RS232 電平標(biāo)準(zhǔn)基本可以判斷是 TTL 電平不是 RS232 電平。5.3 用 Python 腳本驗(yàn)證串口收發(fā)在沒有邏輯分析儀的情況下也可以直接讓 PC 和單片機(jī)對(duì)發(fā)數(shù)據(jù)來驗(yàn)證鏈路。下面是使用 Python PySerial 庫讀取串口數(shù)據(jù)的示例。# 文件路徑read_serial.py # 在電腦上執(zhí)行前先安裝 pyserialpip install pyserial import serial import time # 根據(jù)實(shí)際設(shè)備管理器中的 COM 口號(hào)修改 ser serial.Serial( portCOM3, # Windows 示例Linux 下可能是 /dev/ttyUSB0 baudrate9600, bytesizeserial.EIGHTBITS, parityserial.PARITY_NONE, stopbitsserial.STOPBITS_ONE, timeout1 ) if ser.is_open: print(f串口 {ser.name} 已打開) # 發(fā)送一幀測(cè)試數(shù)據(jù) ser.write(bHello RS232\r\n) # 讀取來自對(duì)端的數(shù)據(jù) time.sleep(0.1) data ser.read(64) if data: print(收到數(shù)據(jù):, data) else: print(未收到數(shù)據(jù)請(qǐng)檢查接線和電平轉(zhuǎn)換電路) ser.close()Linux 系統(tǒng)下也可以直接用命令行測(cè)試# 查看 USB 轉(zhuǎn)串口設(shè)備節(jié)點(diǎn) ls /dev/ttyUSB* # 設(shè)置串口參數(shù)并發(fā)送數(shù)據(jù) stty -F /dev/ttyUSB0 9600 cs8 -cstopb -parenb echo -en Hello RS232\r\n /dev/ttyUSB0 # 讀取串口數(shù)據(jù)按 CtrlC 退出 cat /dev/ttyUSB0在 Windows 上則推薦使用常見的串口調(diào)試助手比如 SSCOM 工具。打開串口調(diào)試助手時(shí)需要注意以下幾點(diǎn)波特率、數(shù)據(jù)位、停止位、校驗(yàn)位要和設(shè)備端完全一致。勾選“發(fā)送新行”時(shí)很多工具會(huì)在發(fā)送內(nèi)容的最后自動(dòng)添加\r\n也就是回車換行如果設(shè)備需要以回車作為命令結(jié)束標(biāo)志這個(gè)功能很重要。接收區(qū)設(shè)置為文本顯示還是 Hex 顯示要根據(jù)設(shè)備協(xié)議決定如果收到的是非 ASCII 字節(jié)建議切換成 Hex 顯示更直觀。6. RS232 串口常見問題與排查思路本章整理我在調(diào)試 RS232 串口時(shí)遇到的高頻問題按“現(xiàn)象 - 原因 - 解決思路”的順序給出方便有經(jīng)驗(yàn)的開發(fā)者快速對(duì)照。問題現(xiàn)象常見原因解決思路電腦無法識(shí)別 USB 轉(zhuǎn)串口設(shè)備CH340/CH341/FTDI 等驅(qū)動(dòng)未安裝或驅(qū)動(dòng)版本不兼容進(jìn)入設(shè)備管理器查看是否出現(xiàn)未知設(shè)備或黃色感嘆號(hào)到芯片官網(wǎng)下載對(duì)應(yīng)系統(tǒng)驅(qū)動(dòng)打開串口提示“端口被占用”或“無法打開”串口被其他軟件占用或者串口工具未關(guān)閉關(guān)閉正在使用該串口的軟件重新插拔轉(zhuǎn)接器必要時(shí)重啟電腦收發(fā)雙方波特率設(shè)置不同上位機(jī)與設(shè)備波特率不一致確認(rèn)兩邊的波特率、數(shù)據(jù)位、停止位、校驗(yàn)位完全一致包括是否有回車換行收不到任何數(shù)據(jù)TXD 和 RXD 接反沒有共地或沒有完成 TTL/RS232 電平轉(zhuǎn)換用交叉方式重新連接 TTL 信號(hào)檢查 MAX232 供電和電荷泵電容用萬用表確認(rèn) RS232 端空閑電壓為負(fù)電平收到亂碼波特率不匹配、接地不可靠、線纜過長(zhǎng)、主時(shí)鐘偏差大降低波特率選擇更好的 USB 轉(zhuǎn) TTL 芯片檢查雙方 GND 連接縮短線纜長(zhǎng)度電平轉(zhuǎn)換芯片發(fā)燙電源接反、引腳短路、信號(hào)端口被高壓串入斷電后用萬用表測(cè)量 VCC 和 GND 是否短路檢查外部 RS232 線是否帶電反插設(shè)備剛連接時(shí)正常長(zhǎng)時(shí)間運(yùn)行后死機(jī)RS232 線路受外部干擾或地電位差影響產(chǎn)生過壓或浪涌增加 TVS 二極管使用屏蔽線保證通信地可靠必要時(shí)在 RS232 收發(fā)器前端增加隔離方案單片機(jī) 3.3V 與 5V 電平互連收不到數(shù)據(jù)邏輯電平不兼容例如 3.3V 芯片輸出高電平為 3.3V低于 5V TTL 高電平閾值使用電平轉(zhuǎn)換芯片或雙向電平轉(zhuǎn)換模塊完成 3.3V/5V 電壓匹配與某些工業(yè)觸摸屏/PLC 通信不穩(wěn)定偶發(fā)超時(shí)只接了 TX、RX、GND但現(xiàn)場(chǎng)干擾大或設(shè)備要求硬件流控根據(jù)設(shè)備手冊(cè)確認(rèn)是否需要 RTS/CTS 或 DTR/DSR嘗試波特率降到 9600檢查接線端子是否松動(dòng)在排查 RS232 問題時(shí)建議遵循一個(gè)固定的順序先檢查電平是否真的是 RS232 電平再檢查 TX 與 RX 是否交叉接著確認(rèn)參數(shù)是否一致最后才懷疑協(xié)議格式和程序邏輯。如果上來就懷疑代碼很容易在錯(cuò)誤的方向上浪費(fèi)時(shí)間。7. 接口防護(hù)與工程布線建議RS232 在電路板上看似簡(jiǎn)單但一個(gè)沒有防護(hù)的 RS232 接口在工廠現(xiàn)場(chǎng)非常容易被浪涌打壞。下面給出幾條實(shí)用的工程建議。7.1 常用防護(hù)電路怎么加在 RS232 收發(fā)器芯片和 DB9 座子之間可以增加簡(jiǎn)單的防護(hù)電路常見做法是在發(fā)送和接收線上分別串聯(lián)小阻值電阻例如 1kΩ 或 10Ω用于限制瞬間大電流具體阻值需要根據(jù)信號(hào)速率和芯片驅(qū)動(dòng)能力折算。在信號(hào)線對(duì)地之間放置 TVS 二極管把浪涌電壓鉗位在芯片能承受的范圍內(nèi)。在 DB9 外殼和信號(hào)地之間增加高壓電容或放電管減小靜電放電對(duì)內(nèi)部電路的影響。注意很多 RS232 收發(fā)器芯片內(nèi)部已經(jīng)集成了 ESD 保護(hù)如果你的產(chǎn)品使用環(huán)境相對(duì)干凈比如實(shí)驗(yàn)室、辦公設(shè)備就不需要額外做太多防護(hù)如果應(yīng)用在電機(jī)、變頻器等工業(yè)現(xiàn)場(chǎng)還是建議增加 TVS 和良好的接地設(shè)計(jì)。7.2 線纜長(zhǎng)度與布線選擇RS232 標(biāo)準(zhǔn)早期規(guī)定最大傳輸距離約 15 米左右這是在低波特率、良好接地和低噪聲環(huán)境下的參考值。實(shí)際應(yīng)用中如果使用帶屏蔽的線纜并把屏蔽層單端接地在 9600 波特率下跑 15 米以內(nèi)通常問題不大如果提高到 115200 波特率傳輸距離應(yīng)大幅縮短否則會(huì)出現(xiàn)誤碼。布線時(shí)需要優(yōu)先級(jí)最高的幾點(diǎn)兩設(shè)備之間的 GND 一定要連通這是所有電壓判斷的參考點(diǎn)。長(zhǎng)距離布線應(yīng)采用屏蔽雙絞線屏蔽層建議單端接地防止形成地環(huán)路。盡可能讓 RS232 信號(hào)線遠(yuǎn)離電機(jī)驅(qū)動(dòng)線、變頻器輸出線、大電流電纜。在 PCB 上RS232 收發(fā)器盡量靠近 DB9 座子保持 RS232 電平的走線盡量短。8. 最佳實(shí)踐與開發(fā)建議做過多塊帶 RS232 接口的板子之后我總結(jié)出下面幾條對(duì)實(shí)際開發(fā)最有用的實(shí)踐建議。第一設(shè)計(jì)板卡時(shí)把 TTL 測(cè)試點(diǎn)引出來。即使產(chǎn)品外殼上是 DB9 座也最好在 PCB 上預(yù)留 MAX232 前端的 TTL 信號(hào)測(cè)試點(diǎn)方便開發(fā)階段用邏輯分析儀直接抓取單片機(jī)發(fā)出的原始數(shù)據(jù)。如果通信異常先確認(rèn)單片機(jī)側(cè) TTL 數(shù)據(jù)是否正常再檢查 RS232 轉(zhuǎn)換后的信號(hào)就能快速判定問題出在哪一側(cè)。第二RS232 收發(fā)器芯片的電源去耦電容不要省。MAX232 類芯片內(nèi)部電荷泵正常工作需要干凈的電源建議在 VCC 引腳附近放置 0.1uF 陶瓷電容并靠近芯片引腳布置。電荷泵電容的容值和耐壓也需要按芯片手冊(cè)選擇不要隨手把任意電容插上去。第三通信參數(shù)盡量做成可配置項(xiàng)。工業(yè)觸摸屏、PLC 或儀表設(shè)備往往要求不同的波特率或者校驗(yàn)方式把波特率、數(shù)據(jù)位、校驗(yàn)位寫死在程序里會(huì)給后續(xù)調(diào)試帶來很大麻煩。建議使用配置文件或參數(shù)存儲(chǔ)區(qū)保存通信參數(shù)方便現(xiàn)場(chǎng)修改。第四不要盲目追求高速率。RS232 主要用于可靠性優(yōu)先的低速場(chǎng)景常見的 9600、19200 波特率適用于大多數(shù)工業(yè)設(shè)備。如果數(shù)據(jù)量很大、要求高吞吐不如改用 RS485 或者以太網(wǎng)方案。第五對(duì)收發(fā)數(shù)據(jù)要做超時(shí)處理。串口接收程序不能無限等待否則一旦對(duì)端掉線整個(gè)系統(tǒng)會(huì)卡在接收函數(shù)里。工業(yè)場(chǎng)景建議使用接收超時(shí)機(jī)制超時(shí)后主動(dòng)重發(fā)或者上報(bào)鏈路異常。最后要特別注意供電問題。很多 RS232 轉(zhuǎn)接小板直接從 USB 口取電USB 口的 5V 電壓在長(zhǎng)線或帶載能力不足時(shí)會(huì)出現(xiàn)跌落導(dǎo)致 MAX232 輸出幅度不足。調(diào)試時(shí)如果發(fā)現(xiàn)輸出電平比正常低可以換一個(gè)電源質(zhì)量更好的 USB 口或者給轉(zhuǎn)接器單獨(dú)供電測(cè)試。9. 總結(jié)與下一步學(xué)習(xí)方向?qū)懙竭@里RS232 電平、RS232 串口接口、TTL 與 RS232 的轉(zhuǎn)換電路、調(diào)試方法和工程注意事項(xiàng)已經(jīng)全部梳理了一遍。重要的是要記住一個(gè)核心結(jié)論RS232 是一套完整的電氣標(biāo)準(zhǔn)它最大的特點(diǎn)就是負(fù)邏輯、正負(fù)雙極性電壓而單片機(jī)的 UART 默認(rèn)輸出的是 TTL 電平兩者之間必須通過 MAX232 類芯片或獨(dú)立轉(zhuǎn)換電路完成電平搬移和邏輯反向。下一步可以從三個(gè)方向繼續(xù)深入如果做的是板級(jí)通信建議學(xué)習(xí) RS485 與 RS232 的區(qū)別了解差分信號(hào)為什么更適合長(zhǎng)距離、多節(jié)點(diǎn)通信。如果做的是工業(yè)設(shè)備互聯(lián)可以研究 Modbus RTU 協(xié)議在 RS232/RS485 上的應(yīng)用這是工控領(lǐng)域最主流的串口協(xié)議之一。如果做的是單片機(jī)開發(fā)可以繼續(xù)學(xué)習(xí) DMA 空閑中斷接收不定長(zhǎng)數(shù)據(jù)把串口通信從輪詢收數(shù)升級(jí)為高效中斷驅(qū)動(dòng)模式。RS232 雖然古老但掌握它的電平標(biāo)準(zhǔn)、通信時(shí)序和排查思路能幫助你在面對(duì)各種帶“串口”字樣的設(shè)備和模塊時(shí)少踩很多坑。當(dāng)你下次在示波器上看到 TXD 空閑時(shí)穩(wěn)穩(wěn)停在負(fù)電壓附近就能一眼確認(rèn)這才是真正工作在 RS232 電平下的通信鏈路。