第十五章 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
。
c
#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 发送一个字节
c
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 发送字符串
c
void rs485_send_string(unsigned char *str) {
while(*str) {
rs485_send_byte(*str++);
}
}
3.5 接收中断服务函数
c
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 主程序示例(主机轮询)
假设本机为从机,接收主机命令并响应:
c
void main() {
uart_init();
RS485_DE = 0; // 初始为接收模式
while(1) {
// 主循环可处理其他任务
// 如:采集传感器数据、控制输出等
}
}
当主机发送命令如
READ_TEMP\n
,从机解析后可回传温度值。
3.7 多机通信(地址识别)
为实现多设备通信,可在数据帧中加入设备地址。
帧格式(示例):
c
[ADDR][CMD][DATA][CRC]
从机程序中判断地址是否匹配:
c
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单片机从基础到高级外设的完整学习路径已完成,可进入综合项目实战阶段。