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Ω 终端电阻,以消除信号反射。

RS-485 总线拓扑结构 RS-485 总线拓扑结构(带终端电阻) A (D+) B (D-) 120Ω 120Ω Modbus 网关 PLC 智能电表 温控器 变频器 终端电阻必须位于 总线物理两端
常见接线错误: 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
Modbus RTU 数据帧结构 Modbus RTU 数据帧结构(请求帧示例) 地址码 1 字节 功能码 1 字节 数据区 N 字节(可变) CRC 校验 2 字节 ≥ 3.5 字符 ≥ 3.5 字符 ≥ 3.5 字符 ≥ 3.5 字符 ≥ 3.5 字符 帧间间隔 < 3.5 字符时间会导致从站认为帧未结束,造成报文粘连

2.3 CRC 校验(循环冗余校验)

CRC 校验用于检测数据在传输过程中是否发生错误。Modbus RTU 使用 CRC-16 (Modbus 多项式),多项式为 0x8005,初始值为 0xFFFF。校验码占 2 字节,传输时低字节在前,高字节在后。

2.3.1 CRC 计算步骤

  1. 将 16 位 CRC 寄存器初始化为 0xFFFF。
  2. 将帧中第一个字节(地址码)与 CRC 寄存器低 8 位异或,结果存入 CRC 寄存器。
  3. 将 CRC 寄存器右移 1 位,高位补 0。检查移出的最低位:
    • 如果移出位为 1,则将 CRC 寄存器与多项式 0xA001(反转后的 0x8005)异或。
    • 如果移出位为 0,则不进行异或。
  4. 重复步骤 3 共 8 次(处理完一个字节)。
  5. 对帧中所有字节重复步骤 2~4。
  6. 最终 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,导致通信完全中断。
物理层与数据帧关联图 物理层参数 → 数据帧传输链路 物理层参数 波特率 (Baud Rate) 数据位 (Data Bits) 校验位 (Parity) 停止位 (Stop Bits) 终端电阻 (Termination) RS-485 总线 差分信号传输 帧间隔 ≥ 3.5 字符 数据帧结构 地址码 (1 Byte) 功能码 (1 Byte) 数据区 (N Bytes) CRC 校验 (2 Bytes) 低字节在前 参数不匹配 → 帧无法解析 → 通信失败

2.5 本章小结

  • Modbus RTU 物理层以 RS-485 为主流,支持远距离、多节点组网,需正确配置终端电阻。
  • 数据帧由 地址码、功能码、数据区、CRC 校验 四部分组成,帧间间隔必须 ≥ 3.5 字符时间。
  • 功能码 0x03 和 0x04 是厂务数据采集的核心指令,用于读取传感器和仪表数据。
  • CRC 校验采用 CRC-16/Modbus 算法,传输时低字节在前,高字节在后。
  • 网关配置时,串口参数(波特率、校验位、停止位) 必须与从站设备完全一致,否则无法建立通信。