目标:这篇文档只作为 RS485 入门和项目面试复习使用,不展开复杂的现场总线协议、隔离电源设计和 EMC 认证细节。重点记住:RS485 是什么、A/B 怎么接、为什么常用半双工、终端电阻和偏置电阻做什么、方向控制怎么处理、常见问题怎么排查。
来源:围绕 RS485 主题整理的学习笔记,仅供参考。
1. 先用一句话理解 RS485
RS485 是一种采用平衡差分信号传输、抗干扰强、适合远距离多节点通信的电气层标准;工程中最常见的是两线半双工,也可采用四线全双工。
它常配合 MCU 的 UART 使用:MCU 侧仍然按 UART 的字节和波特率收发;RS485 收发器把 UART 的单端逻辑电平转换成总线上的差分信号。
MCU UART RS485 收发器 RS485 总线
+---------+ +-----------------+
| TX ---- | ----------> | DI A | ---------- A
| ---- RX | <---------- | RO B | ---------- B
| GPIO | ---------> | DE /RE |
+---------+ +-----------------+
GND/COM 不是 RS485 差分信号线;仅在系统需要建立参考地或等电位连接时,按设计另行连接。详见 4.1 要不要接 GND。
关键点:RS485 规定的是物理层电气特性,不规定具体数据内容。Modbus RTU、厂家私有协议等可以跑在 RS485 上,但 RS485 不等于 Modbus。
它最典型的特点是:
- MCU 的 UART 不能直接接到
A/B,需要 RS485 收发器。
常见用途:
简单记法:
A/B:一对差分总线线,不是 MCU 的 TX/RX。DI:Driver Input,收发器发送输入,通常接 MCU TX。RO:Receiver Output,收发器接收输出,通常接 MCU RX。/RE:Receiver Enable,低有效接收使能。
2. RS485 在嵌入式项目里做什么
RS485 解决的不是“UART 能不能发字节”,而是 UART 在复杂现场能不能传得更远、更稳,以及能不能让多个节点共用一条通信总线。
以主机读取多个传感器为例:
- RS485 收发器被切到发送状态,把 UART 单端逻辑电平转换成 A/B 差分信号。
- 主机确认最后一个数据位和停止位发送完成后,及时释放总线并切回接收状态。
也就是说,RS485 更像一条共享的双线道路:
3. RS485 为什么抗干扰、能传更远
RS485 使用差分传输。发送器驱动 A/B 形成差分电压;接收器根据 A、B 两线之间的电压差判断逻辑状态。
单端信号:看某根线相对 GND 的电平
差分信号:看 A 与 B 之间的电压差
外部干扰同时耦合到 A、B 两根线时,
接收器主要看两线之差,干扰会被大幅抵消。
直白理解:
两个人同时被环境噪声影响时,单独听其中一个人容易听错;比较两个人声音的差别,反而更容易分辨原来的信息。
注意:
- 差分传输不是完全不怕干扰,屏蔽、双绞线、接地和终端匹配仍然重要。
- 距离越长,通常需要越低的波特率;速率和距离不能同时无限提高。
- 经典工程经验中,在良好线缆、正确终端匹配等条件下,低速(通常不高于
9600 bps)可到约 1200 m;这不是 RS485 标准保证值。高速时距离应明显缩短,实际能力取决于收发器、线缆、拓扑和现场干扰等因素。
4. A/B 到底怎么接
最基本的连接规则是同一差分极性相连。若两端厂家的定义一致,通常表现为同名线相连:
主机 A -------------------- 从机 A
主机 B -------------------- 从机 B
但 RS485 最大的坑是:不同芯片、模块和厂家的 A/B 标号可能不一致。 有的把“非反相端”叫 A,有的模块却把它标成 B 或 D+。因此不能只机械相信字母。
实际排查原则:
- 优先看芯片数据手册或模块说明中的
A/B、D+/D- 定义。 - 在点对点、单节点或已隔离的验证环境中,两端能发送但完全收不到时,可在断电后尝试对调其中一端的 A/B 以验证极性;不宜在复杂多节点现场总线上盲目交换。
- 不要把 A/B 当作 UART 的 TX/RX;若厂家极性定义一致,RS485 总线通常同名直连,不是交叉连接。
4.1 要不要接 GND
RS485 的有效信号是差分电压,但收发器仍有允许的共模电压范围。两端地电位差过大时,即使 A/B 正确,也可能超出收发器范围而通信失败甚至损坏器件。
通常做法:
- 短距离、同一供电系统:常会同时连接
A、B 和信号地/COM。 - 不同供电系统或地电位差可能较大:使用隔离型 RS485 收发器,或按设备手册设计参考地和浪涌保护。
- 不要把“RS485 只要两根线”理解成任何场景都绝对不能或不需要处理地线问题。
5. RS485 半双工和全双工
项目里最常见的是两线制半双工 RS485:所有节点共用同一对 A/B,同一时间只能有一个节点发送。
两线制半双工:
主机 ---- A/B 总线 ---- 从机 1
|--- 从机 2
|--- 从机 3
同一时刻:只能一个节点驱动总线,其他节点接收。
为什么常见半双工:
- 常见主从协议天然由主机发起、从机应答,适合轮流说话。
四线制也可以实现全双工:一对线专门主机发给从机,另一对线专门从机回给主机。它常用于点对点通信,也可用于特定多节点主从网络;但多个从机若共享返回方向,同一时刻仍只能由一个从机驱动,必须由协议避免冲突。因此,它不等于多从机都能在总线上同时全双工通信。四线制布线更多、拓扑和设备支持要求更高,项目中远少于两线制。
6. RS485 收发器与方向控制
MCU UART 的 TX/RX 是全双工接口,而常见两线 RS485 总线是半双工,所以要由收发器的使能脚控制“当前是发送还是接收”。
以常见 MAX485 类收发器为例:
| | |
|---|
DI | | |
RO | | |
DE | | MCU GPIO 或 UART 的 RS485 方向控制 |
/RE | | |
A/B | | |
常见接法是将 DE 和 /RE 绑在同一个 GPIO:
发送流程:
- 等待 UART 线路发送完成(最后一个停止位已发到线上),而不是只等发送寄存器空。以 STM32 为例,前者通常是
TC(Transmission Complete),后者通常是 TXE。 - GPIO 拉低,关闭发送驱动器、释放总线并进入接收。
伪代码:
void rs485_send(const uint8_t *buf, int len)
{
rs485_set_tx_enable(true);
uart_write(UART1, buf, len);
uart_wait_transmission_complete(UART1); // 等最后一个停止位真正发完
rs485_set_tx_enable(false);
}
最容易出错的点:
- 切回接收太早:最后几个字节或停止位没发完,报文尾部丢失。
- 一直处于发送状态:本机或其他节点无法正常回复,总线被占用。
- 回复切换太慢:从机很快应答时,主机可能漏掉开头几个字节。
- 中断/DMA 发送完成判断错误:DMA 搬运完成不等于 UART 已经把最后一位发到线上。
有些 MCU UART 外设支持硬件 RS485 模式,能自动控制方向脚。这能减少软件切换时序问题,但仍需确认极性、发送完成时机和硬件连接。
7. 总线拓扑、终端电阻和偏置电阻
7.1 总线要怎么布线
RS485 推荐使用“手拉手”的总线拓扑,而不是星形连接。各节点本质上是并接在同一对 A/B 主干线上,并非由前一个节点转发数据。
推荐:主干总线
主机 ---- 从机 1 ---- 从机 2 ---- 从机 3
不推荐:星形
从机 1
|
主机 ----------+---------- 从机 2
|
从机 3
原因:长支线和星形分叉会产生信号反射,波特率高或线长长时更容易出现偶发丢包、CRC 错误和波形振铃。
经验:
- 远距离或强干扰环境可用屏蔽双绞线,并按系统规范处理屏蔽层接地。
7.2 终端电阻做什么
当线缆较长、速率较高时,信号到总线末端会反射。终端电阻用于匹配线缆特性阻抗,吸收反射能量。
常见做法:
- 在总线两个物理末端的 A/B 之间各接一个终端电阻。
- 电阻常用约
120 Ω,实际应接近线缆特性阻抗并参考设备手册。
主机端 从机 3 端
A ───────────┬── 从机 1 ───── 从机 2 ───────┬─────────── A
│ │
[120 Ω] [120 Ω]
│ │
B ───────────┴───────────────────────────────┴─────────── B
注意:
- 不是每个节点都加 120 Ω;全部加会使总线负载过重、差分幅度变小。
- 短距离、低波特率系统有时能不加终端电阻,但不要据此忽略规范设计。
- 很多模块带可选 120 Ω 跳帽,只有处于总线末端的模块才打开。
7.3 偏置电阻做什么
当所有节点都关闭发送驱动器时,A/B 总线可能没有确定的差分空闲状态(即使装有终端电阻,差分电压也可能接近 0 V)。传统接收器此时可能受噪声影响而误判,出现假起始位或乱码。偏置电阻用于把空闲总线拉到一个确定状态,这也叫 fail-safe bias。
一般原则:
- 有些现代收发器自带失效保护,外部偏置需求会降低;仍应看器件手册和现场测试。
- 哪根线上拉、哪根线下拉取决于具体收发器的 A/B 极性定义和所需空闲状态,不能机械套用。
- 不要让多个节点随意重复加偏置,否则会增加负载、改变总线电平。
8. RS485 通信参数和协议
RS485 只定义电气层,实际通信仍要约定 UART 参数和上层协议。
常见 UART 参数:
9600 8N1
含义:9600 波特率、8 数据位、无校验、1 停止位。
工业仪表也常见:
9600 8E1
即 8 数据位、偶校验、1 停止位。双方参数必须完全一致。
一个可靠的多节点协议需要同时约定帧格式与通信时序/事务规则。
帧格式通常至少包括:
通信时序/事务规则通常还要约定:
以 Modbus RTU 为例:它是常见的 RS485 上层协议,但并不是所有 RS485 设备都使用它。看到 RS485 接口时,要先确认设备的帧格式、地址、波特率、校验方式和应答超时,不能默认能直接互通。
9. 多节点通信怎么避免冲突
RS485 两线半双工只是提供共享线路,不会自动仲裁谁先发。因此系统必须靠上层协议避免冲突。
最常见的是主从轮询:
主机发给从机 1 -> 从机 1 回复
主机发给从机 2 -> 从机 2 回复
主机发给从机 3 -> 从机 3 回复
规则通常是:
- 从机不能随意主动上报,除非协议专门设计了仲裁或时隙机制。
- 主机确认 UART 线路发送完成后必须释放总线,并留出收发切换和从机响应时间。
如果两个节点同时发送:
- 两个发送驱动级可能产生异常驱动电流(总线争用)并导致数据错误;现代器件通常具有一定限流或短路保护,但持续争用仍应避免。
- 故障通常表现为偶发 CRC 错、超时、某些节点随机离线。
10. RTOS 中 RS485 收发的常见处理
RS485 的接收方法本质上沿用 UART:低速可轮询,普通场景常用中断 + 环形缓冲区,高速或不定长报文可用 DMA + 空闲中断。
RS485 比普通 UART 多出的核心是:发送方向控制、请求应答时序和总线独占。
一个常见任务模型:
业务任务 -> RS485 请求队列 -> RS485 通信任务 -> UART/收发器
|
+-> 等待回复、校验、通知业务任务
伪代码:
void rs485_task(void *arg)
{
rs485_request_t *req;
int rx_len;
while (1) {
rtos_queue_recv(rs485_req_queue, &req, WAIT_FOREVER);
rs485_send(req->tx_buf, req->tx_len);
rx_len = uart_receive_frame(req->rx_buf, req->rx_max_len, req->timeout_ms);
if (rx_len > 0) {
if (protocol_check_frame(req->rx_buf, rx_len)) {
req->result = RS485_OK;
} else {
req->result = RS485_PROTOCOL_ERROR;
}
} else {
req->result = RS485_TIMEOUT;
}
rtos_sem_release(req->done_sem); // 所有终止路径都通知等待方
}
}
设计注意:
- 一个半双工总线通常由一个通信任务串行管理,避免多个任务同时操作方向脚和 UART。
- 中断/DMA 回调只快速收数据和通知任务,不在中断里做完整协议解析。
- 发送完成要等 UART 线路发送完成;以 STM32 为例通常检查
TC。DMA 完成回调后通常还要继续等待 UART 的最后一位发送完毕。 - 只有明确确认接收缓存中是历史无效数据时才能清理;将
uart_rx_flush() 作为通用发送前流程可能丢失合法报文。 - 需要有请求超时、重试次数和 CRC/帧错误统计,便于发现现场问题。
- 无论成功、校验失败还是超时,都要写入明确的请求结果并通知等待任务;否则等待方可能发生死锁。
- 上例在队列中传递请求指针,确保通信任务写入的
result 对提交请求的业务任务可见;实际实现还要保证请求对象在通知前始终有效。 - 广播报文通常没有从机回复,不能按普通请求等待应答。
11. RS485 不通怎么排查
建议按“供电和收发器 → A/B 极性 → 方向控制 → 参数与协议 → 总线质量”的顺序排查。
11.1 先确认基础硬件
检查点:
- 收发器供电是否正常,TTL 电平是否匹配 3.3V/5V MCU。
DI 是否接 MCU TX,RO 是否接 MCU RX。- A/B 是否接到同一对总线,连接器定义是否与设备手册一致。
11.2 A/B 极性不确定怎么办
现象通常是:设备看起来都正常,但完全没有回复或持续乱码。
检查方法:
- 若定义确实不清楚,可仅在点对点、单节点或已隔离的验证环境中,对调其中一端的 A/B 线再测试;复杂多节点现场总线不宜盲目交换。
11.3 看方向控制时序
如果主机能发但收不到从机回复,重点检查:
用逻辑分析仪观察 MCU 侧的 UART_TX、UART_RX、DE 等数字时序;用示波器(必要时配合差分探头)观察 A/B 差分总线的幅值、反射和振铃,通常能很快定位问题。
11.4 再确认通信参数和协议
检查点:
11.5 最后检查总线和干扰
检查点:
- 总线是否采用手拉手拓扑,是否有过长支线或星形分叉。
- 两个物理末端是否正确配置终端电阻,是否每个节点都误加了 120 Ω。
- 线缆是否使用双绞线,是否与强电、变频器电缆长期并行。
- 是否存在地电位差、浪涌或雷击环境,需要隔离和保护。
12. 常见问题和直白回答
12.1 RS485 和 UART 是什么关系
UART 定义字节怎么按波特率串行收发;RS485 定义这些比特如何在 A/B 差分线上传输。MCU 通常用 UART 外设加 RS485 收发器实现 RS485 通信。
12.2 RS485 为什么常见半双工
常见两线 RS485 让多个节点共享一对 A/B 线。为了避免多个节点同时驱动总线产生冲突,同一时刻通常只能一个节点发送,所以是半双工。
12.3 RS485 的 A/B 是不是要交叉接
一般不是。总线侧通常是 A 接 A、B 接 B;但不同厂商的 A/B 命名可能相反,必须以设备手册定义和实际测试为准。
12.4 终端电阻为什么是 120 Ω,装几个
120 Ω 是常见双绞线特性阻抗附近的经验值,用于抑制反射。通常只装在总线两个物理末端,中间节点不装。具体阻值和是否需要应参考线缆、速率和设备手册。
12.5 偏置电阻有什么用
当所有节点都不发送时,A/B 总线可能没有确定的差分空闲状态。偏置电阻让总线空闲电平保持确定,减少噪声造成的误触发和乱码。整条总线通常只保留一组偏置。
12.6 为什么 RS485 发完收不到回复
先查方向控制。发送完成后必须等最后一位真正发完,再关闭发送驱动器并切回接收;如果 DE 一直有效或切换太慢,总线会被本机占用或漏收从机开头的数据。
12.7 RS485 能挂多少节点、能传多远
没有一个脱离条件的固定答案。节点数受收发器单位负载、电气负载和拓扑影响;距离受波特率、线缆、终端匹配和干扰环境影响。传统收发器常按 32 个单位负载估算(假设每个节点均按 1 个单位负载计算),现代低单位负载器件可支持更多;工程上应按器件手册和现场测试确定。
13. 高频易错点
| |
|---|
| RS485 是物理层,Modbus RTU 是可运行在其上的协议之一 |
| RS485 总线通常 A 接 A、B 接 B,但须确认厂家定义 |
| 差分信号仍受共模范围限制,地电位差和参考地要按系统设计处理 |
| |
| |
| DMA 完成不等于最后一位已在线上发完,还要等 UART 线路发送完成(STM32 等平台常称 TC) |
| |
| 长线、高速和强干扰场景更需要双绞线、拓扑、终端和隔离设计 |
14. 最简记忆版
只想快速记住,可以背下面几句:
- RS485 是差分物理层,常由 UART + RS485 收发器实现。
- 总线侧应连接同一差分极性;若厂家定义一致,通常是
A -> A、B -> B,但最终一定要看设备手册。 - MCU 需要通过
DE、/RE 控制收发方向;发送后要等 UART 线路发送完成(STM32 等平台常称 TC)再释放总线。 - 长线高速时,总线两个物理末端通常各加一个约
120 Ω 终端电阻。 - 偏置电阻用于保证总线空闲状态,整条总线通常只保留一组。
- RS485 不等于 Modbus;还要确认波特率、校验、地址、帧格式和 CRC。
- 不通先查 A/B 极性、方向控制、串口参数、地址协议和终端/偏置。