2. Modbus RTU 协议详解:物理层与数据帧格式
Modbus RTU 是工业现场最主流的串行通信协议之一。要正确配置 Modbus RTU 转 TCP 网关,必须首先理解其物理层规范和数据帧结构。本章将从物理接口、电气特性、帧格式和校验机制四个维度进行深度拆解。
学习提示: 物理层决定了你能传多远、能接多少设备;数据帧格式决定了报文如何被解析。这两部分是网关配置中“接线”和“报文调试”的理论基础。
2.1 物理层:RS-232 与 RS-485
Modbus RTU 在物理层主要运行在两种串行接口上:RS-232 和 RS-485。两者在传输距离、拓扑结构和抗干扰能力上存在显著差异。
| 对比项 | RS-232 | RS-485 |
|---|---|---|
| 传输方式 | 单端不平衡传输 | 差分平衡传输 |
| 最大距离 | 约 15 米(50 英尺) | 约 1200 米(4000 英尺) |
| 最大节点数 | 1 对 1(点对点) | 最多 32 个节点(标准),可扩展至 256 |
| 信号线 | TX、RX、GND(至少 3 线) | A(D+)、B(D-)、GND(可选) |
| 抗干扰能力 | 较弱 | 强(共模抑制) |
| 典型应用 | 近距离调试、单台设备连接 | 厂务总线、多设备组网 |
厂务现场选型建议: 在厂务数据采集场景中,RS-485 是主流。它支持多站挂接(如同时采集多台空调控制器、电表、水表),且传输距离覆盖车间级范围。RS-232 通常仅用于单台 PLC 或上位机的近距离调试。
2.1.1 RS-485 接线拓扑
RS-485 采用总线型拓扑,所有设备并联在 A/B 差分线上。在总线两端必须各接入一个 120Ω 终端电阻,以消除信号反射。
常见接线错误: A/B 线接反会导致通信失败;缺少终端电阻会导致长距离通信数据错位;屏蔽层单端接地可避免地环路干扰。
2.2 数据帧格式
Modbus RTU 的数据帧以二进制形式传输,每个报文由四个基本部分组成:地址码、功能码、数据区和CRC 校验。帧内字节之间没有间隔,帧与帧之间至少保持 3.5 个字符时间的静默间隔。
| 字段 | 长度(字节) | 说明 |
|---|---|---|
| 地址码 | 1 | 从站设备地址,范围 1~247(0 为广播地址) |
| 功能码 | 1 | 指示操作类型(读/写/诊断等) |
| 数据区 | N(可变) | 寄存器地址、数量、数据值等 |
| CRC 校验 | 2 | 循环冗余校验,低字节在前 |
2.2.1 地址码(Slave Address)
地址码标识总线上的目标从站。主站发送请求时,只有地址匹配的从站才会响应。地址 0x00 为广播地址,所有从站接收但不回复。
2.2.2 功能码(Function Code)
功能码定义了对从站的具体操作。以下是厂务数据采集中最常用的功能码:
- 0x01 (Read Coils) — 读取离散量输出/线圈状态
- 0x02 (Read Discrete Inputs) — 读取离散量输入状态
- 0x03 (Read Holding Registers) — 读取保持寄存器(最常用,如读取温度、压力值)
- 0x04 (Read Input Registers) — 读取输入寄存器(只读模拟量)
- 0x06 (Write Single Register) — 写单个保持寄存器
- 0x10 (Write Multiple Registers) — 写多个保持寄存器
厂务采集重点: 功能码 0x03 和 0x04 是采集传感器数据(温度、湿度、流量、电压)的核心指令。功能码 0x06 和 0x10 用于远程控制(如设定空调温度、调节阀门开度)。
2.2.3 数据区(Data Field)
数据区的内容取决于功能码。以最常用的 0x03 读保持寄存器 为例:
- 请求帧数据区: 起始寄存器地址(2 字节,高字节在前) + 寄存器数量(2 字节,高字节在前)
- 响应帧数据区: 数据字节数(1 字节) + 寄存器数据(N 字节,每个寄存器 2 字节,高字节在前)
示例:读取地址为 0x01 的从站,从寄存器 0x0000 开始连续读取 2 个寄存器。
请求帧(主站 → 从站):
地址码: 0x01
功能码: 0x03
起始地址高字节: 0x00
起始地址低字节: 0x00
寄存器数量高字节: 0x00
寄存器数量低字节: 0x02
CRC 低字节: 0xC4
CRC 高字节: 0x0B
响应帧(从站 → 主站):
地址码: 0x01
功能码: 0x03
数据字节数: 0x04
寄存器 0 高字节: 0x00
寄存器 0 低字节: 0x64 (十进制 100)
寄存器 1 高字节: 0x00
寄存器 1 低字节: 0xC8 (十进制 200)
CRC 低字节: 0x3A
CRC 高字节: 0x9F
2.3 CRC 校验(循环冗余校验)
CRC 校验用于检测数据在传输过程中是否发生错误。Modbus RTU 使用 CRC-16 (Modbus 多项式),多项式为 0x8005,初始值为 0xFFFF。校验码占 2 字节,传输时低字节在前,高字节在后。
2.3.1 CRC 计算步骤
- 将 16 位 CRC 寄存器初始化为
0xFFFF。 - 将帧中第一个字节(地址码)与 CRC 寄存器低 8 位异或,结果存入 CRC 寄存器。
- 将 CRC 寄存器右移 1 位,高位补 0。检查移出的最低位:
- 如果移出位为 1,则将 CRC 寄存器与多项式
0xA001(反转后的 0x8005)异或。 - 如果移出位为 0,则不进行异或。
- 重复步骤 3 共 8 次(处理完一个字节)。
- 对帧中所有字节重复步骤 2~4。
- 最终 CRC 寄存器中的值即为校验码,先发送低字节,再发送高字节。
调试技巧: 使用串口调试工具(如 ModScan、Modbus Poll)时,如果收到从站无响应或异常码 0x03(非法数据值),90% 的原因是 CRC 计算错误或地址/功能码不匹配。建议先用工具自带的 CRC 计算器验证报文。
2.4 物理层与数据帧的关联
物理层参数直接影响数据帧的传输质量。在配置网关时,必须确保以下参数与从站设备一致:
| 参数 | 常见值 | 影响 |
|---|---|---|
| 波特率 | 9600 / 19200 / 38400 / 115200 | 决定帧传输速度,波特率越高,帧间隔时间越短 |
| 数据位 | 8 | Modbus RTU 固定为 8 位 |
| 校验位 | 无校验 / 偶校验 / 奇校验 | 必须与从站一致,否则 CRC 校验永远失败 |
| 停止位 | 1 或 2 | 影响帧间隔计算(3.5 字符时间) |
关键提醒: 在配置 Modbus RTU 转 TCP 网关时,网关的串口参数(波特率、校验位、停止位)必须与所连接的从站设备完全一致。一个常见的故障场景是:网关默认设置为 9600/8/N/1,而现场电表设置为 19200/8/E/1,导致通信完全中断。
2.5 本章小结
- Modbus RTU 物理层以 RS-485 为主流,支持远距离、多节点组网,需正确配置终端电阻。
- 数据帧由 地址码、功能码、数据区、CRC 校验 四部分组成,帧间间隔必须 ≥ 3.5 字符时间。
- 功能码 0x03 和 0x04 是厂务数据采集的核心指令,用于读取传感器和仪表数据。
- CRC 校验采用 CRC-16/Modbus 算法,传输时低字节在前,高字节在后。
- 网关配置时,串口参数(波特率、校验位、停止位) 必须与从站设备完全一致,否则无法建立通信。