
前言:工業現場為什麼還在用 RS485
RS485(正式名稱 TIA-485)由 EIA 定義,是一套差動串列通訊標準。它不新,但工廠、大樓機房、太陽能電廠到現在都還在用,原因只有一個:它很耐操。
兩條絞線拉 1200 公尺還能跑,雜訊同時灌進兩條線也不會影響判讀,一條匯流排可以掛到 32 個節點。這些特性讓它成為 Modbus RTU 等工業協定的標準實體層。
它靠什麼撐過惡劣環境
關鍵在「差動訊號」:邏輯不是看某一條線對地的電壓,而是看 A、B 兩條線的差值。

外界雜訊會同時耦合到 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 最常被搞混的地方:終端電阻只在最遠兩端各一顆(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 時序:整個協定最容易出錯的地方

四個時間點要記牢:t1 拉高 DE、t2 開始送資料、t3 送完、t4 拉低 DE 回到接收。而 t1→t2 與 t3→t4 之間各需要 1~2 ms 的延遲。
為什麼要延遲?因為收發器從高阻抗切換到驅動狀態需要時間。延遲太短的話,資料的頭或尾會被切掉 —— 這正是下一節「最後一兩個 byte 遺失」的成因。
四個現場問題與解法

如果裝置數量超過 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 上寫的底層程式碼可以直接沿用。
文章評論