0x6A Logbook

0x6A Logbook
Shi6a的筆記本
  1. 首頁
  2. 自動化技巧
  3. 正文

RS485 通訊協定完整教學:從硬體接線到 ESP32/STM32 實作

2026 年 5 月 21 日 1355點熱度 0人點贊 0條評論

RS485 通訊協定完整教學封面

前言:工業現場為什麼還在用 RS485

RS485(正式名稱 TIA-485)由 EIA 定義,是一套差動串列通訊標準。它不新,但工廠、大樓機房、太陽能電廠到現在都還在用,原因只有一個:它很耐操。

兩條絞線拉 1200 公尺還能跑,雜訊同時灌進兩條線也不會影響判讀,一條匯流排可以掛到 32 個節點。這些特性讓它成為 Modbus RTU 等工業協定的標準實體層。

它靠什麼撐過惡劣環境

關鍵在「差動訊號」:邏輯不是看某一條線對地的電壓,而是看 A、B 兩條線的差值。

RS485 差動訊號的判讀方式

外界雜訊會同時耦合到 A 與 B,兩條線一起被抬高,但差值不變 —— 這就是抗共模干擾的來源。加上 1200 公尺的傳輸距離與多站匯流排能力,RS485 在工業現場幾乎沒有對手。

特性 RS485 RS232 TTL UART
訊號方式 差動(平衡) 單端(不平衡) 單端
電壓範圍 ±1.5V ~ ±6V ±3V ~ ±15V 0V ~ 3.3V/5V
最大距離 1200m 15m 1~3m
最大速率 50Mbps(短距) 115.2kbps 取決於 MCU
多站能力 最多 256 個 點對點 點對點
共模電壓 -7V ~ +12V N/A N/A
收發器 IC MAX485 / MAX3485 MAX232 內建於 MCU
典型應用 工業網路、Modbus 舊式 PC COM Port 晶片間通訊

三者的定位可以這樣記:RS232 是 PC 時代的遺產、TTL UART 是晶片之間用的、RS485 才是現場的主力。

硬體接線:兩種電阻,位置完全不同

RS485 多站匯流排拓撲

終端電阻與偏壓電阻的擺放位置

這兩種電阻是 RS485 最常被搞混的地方:終端電阻只在最遠兩端各一顆(A 到 B 之間,120 Ω),偏壓電阻則在主站端(A 拉 Vcc、B 拉 GND)。中間節點什麼都不用加。

收發器晶片:MCU 不能直接接匯流排

MCU 的 UART 輸出的是 TTL 電平,不能直接接到 RS485 的 A/B 線上,中間一定要有一顆收發器:

晶片 電壓 速率 腳位
MAX485 5V 2.5Mbps 8-pin DIP/SOIC
MAX3485 3.3V 12Mbps 8-pin DIP/SOIC
MAX1487 5V 2.5Mbps 8-pin(高 ESD)
SN65HVD3082E 5V 20Mbps 8-pin(低功耗)

對 ESP32 這種 3.3 V 系統,MAX3485 是首選(不需要電平轉換);STM32 F1 這類 5 V 容忍的腳位則可以直接用 MAX485。

收發器的選擇流程

腳位定義也要記住,尤其是那兩個控制腳:

腳位 名稱 說明
1 RO Receiver Output → MCU RX
2 RE Receiver Enable (Low = 啟用接收)
3 DE Driver Enable (High = 啟用發送)
4 DI Driver Input ← MCU TX
5 GND 接地
6 A Non-inverting output/input (D+)
7 B Inverting output/input (D-)
8 Vcc 電源(MAX485: 5V / MAX3485: 3.3V)

因為 RS485 是半雙工,收與送不能同時進行。實務上會把 DE 與 RE 接在一起由一個 GPIO 控制:HIGH 進發送模式、LOW 回接收模式。

ESP32 + MAX3485 實作

ESP32 MAX3485
GPIO17 (TX2) DI (Pin 4)
GPIO16 (RX2) RO (Pin 1)
GPIO4 DE + RE (Pin 2&3)
3.3V Vcc (Pin 8)
GND GND (Pin 5)
#include <HardwareSerial.h>

#define TX2_PIN 17
#define RX2_PIN 16
#define RS485_CTRL 4   // DE/RE 控制腳

HardwareSerial rs485(2);  // UART2

void setup() {
  Serial.begin(115200);
  pinMode(RS485_CTRL, OUTPUT);
  digitalWrite(RS485_CTRL, LOW); // 預設接收模式

  rs485.begin(9600, SERIAL_8N1, RX2_PIN, TX2_PIN);
}

void rs485_send(const uint8_t* data, size_t len) {
  digitalWrite(RS485_CTRL, HIGH);  // 切換到發送模式
  delay(1);                         // 等待電晶體穩定
  rs485.write(data, len);
  rs485.flush();                    // 等待資料發送完畢
  delay(1);
  digitalWrite(RS485_CTRL, LOW);   // 回到接收模式
}

void loop() {
  if (rs485.available()) {
    uint8_t buf[64];
    size_t len = rs485.readBytes(buf, 64);
    
    Serial.print("收到 ");
    Serial.print(len);
    Serial.println(" bytes:");
    for (size_t i = 0; i < len; i++) {
      Serial.printf("0x%02X ", buf[i]);
    }
    Serial.println();

    // 回傳相同資料(Loopback 測試)
    rs485_send(buf, len);
  }
}

STM32 + MAX485 實作

STM32 端在 CubeMX 設定 USART2 為非同步、9600 8N1,另外配一個 GPIO 當 DE/RE 控制:

#define RS485_CTRL_PORT GPIOA
#define RS485_CTRL_PIN  GPIO_PIN_0

#define RS485_TX_MODE()  HAL_GPIO_WritePin(RS485_CTRL_PORT, RS485_CTRL_PIN, GPIO_PIN_SET)
#define RS485_RX_MODE()  HAL_GPIO_WritePin(RS485_CTRL_PORT, RS485_CTRL_PIN, GPIO_PIN_RESET)

void RS485_Send(uint8_t* data, uint16_t len) {
  RS485_TX_MODE();
  HAL_Delay(1);
  HAL_UART_Transmit(&huart2, data, len, HAL_MAX_DELAY);
  HAL_Delay(1);
  RS485_RX_MODE();
}

void RS485_Receive_IT(void) {
  RS485_RX_MODE();
  static uint8_t rx_byte;
  HAL_UART_Receive_IT(&huart2, &rx_byte, 1);
}

// 在回呼函數中處理收到的資料
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
  if (huart->Instance == USART2) {
    static uint8_t rx_buf[64];
    static uint16_t idx = 0;
    
    rx_buf[idx++] = rx_byte;
    
    // 遇到換行或緩衝區滿,處理一筆完整訊息
    if (rx_byte == '
' || idx >= 64) {
      RS485_Send(rx_buf, idx);  // 回傳(Loopback)
      idx = 0;
    }
    
    HAL_UART_Receive_IT(&huart2, &rx_byte, 1);
  }
}

DE/RE 時序:整個協定最容易出錯的地方

DE/RE 控制與差動訊號時序

四個時間點要記牢:t1 拉高 DE、t2 開始送資料、t3 送完、t4 拉低 DE 回到接收。而 t1→t2 與 t3→t4 之間各需要 1~2 ms 的延遲。

為什麼要延遲?因為收發器從高阻抗切換到驅動狀態需要時間。延遲太短的話,資料的頭或尾會被切掉 —— 這正是下一節「最後一兩個 byte 遺失」的成因。

四個現場問題與解法

RS485 四個常見問題

如果裝置數量超過 32 個,別急著懷疑線材 —— 先看收發器的負載單位:

負載單位與可接裝置數

而「最後一兩個 byte 遺失」幾乎可以百分之百確定是 DE 切換時序問題。解決方式很單純:flush 或 HAL_UART_Transmit() 返回後,務必延遲 2 ms 以上再拉低 DE。想省掉這個麻煩,也可以改用內建自動方向控制的型號(如 MAX13487、ADM2483)。

總結

RS485 是工業通訊的基石,五個重點:

  • 差動訊號是它的核心:看 A、B 的差值,不看對地電壓
  • 兩種電阻各司其職:終端電阻在最遠兩端、偏壓電阻在主站端
  • MCU 一定要接收發器:3.3 V 系統選 MAX3485,5 V 容忍選 MAX485
  • 半雙工要靠 DE/RE 切換:切換後留 1~2 ms,別省這個延遲
  • 節點數受負載單位限制:需要更多就換 1/4 UL、1/8 UL 或加中繼器

學會 RS485 之後,下一步就是 Modbus RTU —— 它是建立在這個實體層之上的應用層協定,廣泛用在 PLC、感測器與工業儀表。你在 ESP32 與 STM32 上寫的底層程式碼可以直接沿用。

標籤: RS485 工業通訊 教學
最後更新:2026 年 9 月 30 日

shi6a

這個人很懶,什麼都沒留下

點贊
< 上一篇
下一篇 >

文章評論

razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
取消回覆

COPYRIGHT © 2026 0x6A Logbook. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang