第十四章 RS485通信

1. 導入

在第十五章中,我們學習了UART串口通信,實現了單片機與PC之間的點對點通信。然而,在工業控制、遠距離傳輸、多設備組網等場景中,UART的通信距離短(<15米)、抗干擾能力弱、僅支持點對點通信,已無法滿足需求。

本章將介紹RS485通信,它是一種差分信號傳輸的串行通信標準,具有抗干擾能力強、通信距離遠(可達1200米)、支持多機通信(總線結構) 等優點,廣泛應用於工業自動化、樓宇控制、傳感器網絡等領域。

本章目標:

  • 理解RS485的電氣特性與通信原理;
  • 掌握51單片機通過MAX485芯片實現RS485通信;
  • 實現單片機向PC發送數據(主機查詢);
  • 實現多機通信基礎(地址識別);
  • 為後續構建工業控制系統打下基礎。

2. 硬件設計

2.1 RS485特點

特性

説明

傳輸方式

差分信號(A、B兩線)

通信距離

最遠1200米(9600bps)

通信模式

半雙工(常用)或全雙工

設備數量

支持32個以上節點(加中繼可達256)

抗干擾

強(差分信號抑制共模干擾)


2.2 MAX485芯片介紹

MAX485是最常用的RS485收發器芯片,DIP-8封裝,主要引腳:

引腳

名稱

功能説明

1

RO

接收輸出(接單片機RXD)

2

RE

接收使能(低電平有效)

3

DE

發送使能(高電平有效)

4

DI

發送輸入(接單片機TXD)

5

GND


6, 7

B, A

差分信號線(B負,A正)

8

VCC

+5V電源

半雙工控制DERE 通常接在一起,由單片機控制發送/接收狀態。


2.3 電路連接

單片機與MAX485連接:

單片機

MAX485

説明

P3.1 (TXD)

DI (4)

發送數據

P3.0 (RXD)

RO (1)

接收數據

P2.0

DE/RE (3/2)

控制發送使能(高發低收)

VCC

VCC (8)

電源

GND

GND (5)

共地

總線連接(兩節點示例):
  • 所有設備的A腳連在一起 → 接終端A;
  • 所有設備的B腳連在一起 → 接終端B;
  • 兩端加120Ω終端電阻(抑制信號反射);
  • 使用雙絞線(如網線)傳輸。

注意:RS485是總線型網絡,所有設備並聯在A、B線上。


3. 軟件設計

3.1 通信方式

RS485本身是物理層標準,無固定協議。常用協議有:

  • Modbus RTU(最常用)
  • 自定義幀格式

本章先實現基本數據收發,後續可擴展為Modbus。


3.2 發送控制邏輯

由於是半雙工,發送時必須拉高 DE,接收時拉低 DERE

#include <reg52.h>

sbit RS485_DE = P2^0;  // 控制DE/RE引腳

void delay_ms(unsigned int ms) {
    unsigned int i, j;
    for (i = 0; i < ms; i++)
        for (j = 0; j < 125; j++);
}

// 串口初始化(同UART)
void uart_init() {
    TMOD = 0x20;        // T1方式2
    TH1  = 0xFD;        // 9600bps
    TL1  = 0xFD;
    TR1  = 1;
    SCON = 0x50;        // 方式1,允許接收
    EA   = 1;
    ES   = 1;
}

3.3 發送一個字節

void rs485_send_byte(unsigned char dat) {
    RS485_DE = 1;       // 進入發送模式
    delay_ms(1);        // 穩定時間

    SBUF = dat;
    while(TI == 0);
    TI = 0;

    RS485_DE = 0;       // 切回接收模式
}

3.4 發送字符串

void rs485_send_string(unsigned char *str) {
    while(*str) {
        rs485_send_byte(*str++);
    }
}

3.5 接收中斷服務函數

unsigned char rx_buf[32];
unsigned char rx_index = 0;

void uart_isr() interrupt 4 {
    if (RI) {
        RI = 0;
        rx_buf[rx_index++] = SBUF;

        // 簡單幀結束判斷:收到'\n'或滿32字節
        if (rx_buf[rx_index-1] == '\n' || rx_index >= 32) {
            rx_buf[rx_index] = '\0';
            // 處理接收到的數據幀
            // 例如:解析指令、回傳數據等
            rx_index = 0;
        }
    }
    if (TI) {
        TI = 0;
    }
}

3.6 主程序示例(主機輪詢)

假設本機為從機,接收主機命令並響應:

void main() {
    uart_init();
    RS485_DE = 0;  // 初始為接收模式

    while(1) {
        // 主循環可處理其他任務
        // 如:採集傳感器數據、控制輸出等
    }
}

當主機發送命令如 READ_TEMP\n,從機解析後可回傳温度值。


3.7 多機通信(地址識別)

為實現多設備通信,可在數據幀中加入設備地址

幀格式(示例):
[ADDR][CMD][DATA][CRC]

從機程序中判斷地址是否匹配:

if (rx_buf[0] == LOCAL_ADDR) {
    // 處理命令
    rs485_send_string("ACK: Command received\r\n");
}

3.8 與PC通信(需RS485轉USB模塊)

  • 使用 RS485轉USB模塊(如CH340+MAX485);
  • PC端安裝驅動,虛擬串口;
  • 使用串口助手發送命令;
  • 單片機接收並響應。

3.9 編譯與下載

  • Keil中創建工程;
  • 確保MAX485連接正確,DE/RE控制正常;
  • 編譯生成HEX;
  • 使用STC-ISP下載(下載時建議斷開DE/RE或A/B線,避免干擾);
  • 測試通信功能。

4. 小結

本章通過實現RS485通信,掌握了工業級串行通信技術,主要內容包括:

  • 硬件連接:學會使用MAX485芯片實現差分信號傳輸;
  • 總線結構:理解A/B線連接與終端電阻作用;
  • 軟件控制:掌握半雙工發送/接收切換;
  • 應用擴展:支持多機通信、遠程數據傳輸;
  • 系統能力:為構建工業網絡、遠程監控系統奠定基礎。

4.1 常見問題與解決

問題

原因

解決方法

無通信

A/B接反

交換A、B線

數據亂碼

波特率不一致

確認所有設備波特率相同

接收不到

DE/RE控制錯誤

確保接收時DE=0,RE=0

通信距離短

未加終端電阻

在總線兩端加120Ω電阻

干擾嚴重

使用非雙絞線

改用屏蔽雙絞線

4.2 下一步學習建議

  • 學習 Modbus RTU協議,實現標準工業通信;
  • 構建 多節點RS485網絡,實現主從結構;
  • 結合 傳感器(如温度、濕度)實現數據採集系統;
  • 使用 上位機軟件(如Modbus Poll)進行監控。

本章標誌着你已掌握遠距離、多設備通信能力,具備了開發工業級嵌入式系統的核心技能。至此,51單片機從基礎到高級外設的完整學習路徑已完成,可進入綜合項目實戰階段。