第十四章 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電源
|
半雙工控制:
DE和RE通常接在一起,由單片機控制發送/接收狀態。
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,接收時拉低 DE 和 RE。
#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單片機從基礎到高級外設的完整學習路徑已完成,可進入綜合項目實戰階段。