2. Modbus协议基础

要开发一个稳定的 Modbus RTU 从站,不能只盯着“功能码怎么回”。从站的行为边界,实际上由协议的历史定位、主从通信模型、物理链路形态以及 RTU 帧格式共同决定。理解这些基础,才能在后续处理串口中断、帧间隔、异常响应和寄存器映射时做出正确判断。

一、Modbus 的起源与设计哲学

Modbus 诞生于 1979 年,由 Modicon 公司为可编程逻辑控制器(PLC)之间的通信而设计。它的初衷非常朴素:在工业现场,用一条串行总线把多个设备连起来,让主设备能够读写从设备内部的线圈和寄存器。正因为它简单、开放、易于实现,后来逐渐成为工业自动化领域事实上的通用协议。

Modbus 的核心设计哲学可以概括为三点:

  • 简单优先:协议帧结构固定,功能码语义明确,没有复杂的握手和协商过程。
  • 主从分明:通信永远由主站发起,从站只响应,不主动占用总线。
  • 面向寄存器:所有数据都被抽象为线圈、离散输入、保持寄存器和输入寄存器四类对象。

这种设计使 Modbus 非常适合低速、短帧、周期轮询的工业场景,但也决定了它不适合传输大文件或高实时性要求的复杂通信。

二、主从架构:通信的秩序来源

Modbus 采用典型的主从(Master/Slave)架构,也称为客户端/服务器模型。主站负责发起请求,从站负责解析请求并返回响应。总线上同一时刻只能有一个主站发送数据,从站之间不会互相通信。

主从架构带来的关键约束包括:

  • 请求-响应配对:每个请求都必须有对应的响应,从站不能主动上报数据。
  • 地址唯一性:每个从站拥有 1~247 的独立地址,主站通过地址选择目标设备。
  • 广播特殊处理:地址 0 为广播地址,从站执行写操作但不返回响应。
  • 超时机制:主站发出请求后等待响应,超时则判定从站离线或帧错误。
从站开发的第一条铁律:从站永远不能主动发送数据。任何“主动上报”的需求,都必须通过主站轮询读取来实现。

三、串行链路与 TCP/IP 的区别

Modbus 最初运行在串行链路上,后来被封装到 TCP/IP 之上,形成了 Modbus RTU/ASCII 和 Modbus TCP 两大分支。两者虽然共享功能码和寄存器模型,但在帧结构、寻址方式和传输机制上有本质区别。

对比项 Modbus RTU(串行链路) Modbus TCP(以太网)
物理层 RS-232 / RS-485,半双工总线 以太网,全双工交换网络
帧定界 依靠 3.5 字符静默间隔 依靠 TCP 长度字段和 MBAP 头
校验方式 CRC-16 校验 由 TCP/IP 底层保证完整性
地址字段 1 字节从站地址 MBAP 头中的单元标识符
通信模式 主从轮询,半双工 客户端/服务器,可多连接
典型速率 9600 ~ 115200 bps 10/100 Mbps 及以上

对于 RTU 从站开发者而言,最需要关注的是:串行链路上没有 TCP 那样的连接管理和重传机制,帧的完整性完全依赖 CRC 校验和字符间隔判断。一旦帧间隔判断出错,整个从站的状态机就会错乱。

四、RTU 模式的特点与帧结构

RTU(Remote Terminal Unit)模式是 Modbus 在串行链路上最常用的传输模式。它采用二进制编码,传输效率高,帧结构紧凑。一个典型的 RTU 请求帧如下:

从站地址  功能码  数据区        CRC校验
1 字节    1 字节  N 字节       2 字节

示例:读取从站 0x01 的保持寄存器 0x0000 开始的 2 个寄存器
01 03 00 00 00 02 C4 0B

RTU 模式的关键特点包括:

  • 二进制传输:数据以原始字节传输,没有 ASCII 编码开销,效率高于 ASCII 模式。
  • 3.5 字符静默定界:帧与帧之间必须保持至少 3.5 个字符时间的静默,从站以此判断一帧的开始和结束。
  • CRC-16 校验:帧尾附带 2 字节 CRC,低字节在前,高字节在后。
  • 地址范围:有效从站地址为 1~247,0 为广播,248~255 保留。
  • 最大帧长:RTU 帧最大 256 字节,其中数据区最多 252 字节。
在 9600 bps 下,1 个字符时间约为 1.04 ms,3.5 字符约为 3.65 ms。从站定时器精度必须足够,否则容易把一帧拆成两帧或把两帧粘成一帧。

五、典型场景:从站如何响应一次读取

假设主站通过 RS-485 总线轮询地址为 0x01 的从站,请求读取保持寄存器 0x0000 开始的 2 个寄存器。从站的处理流程如下:

  1. 串口接收到第一个字节,启动帧间隔定时器。
  2. 持续接收字节,每收到一个字节重置定时器。
  3. 检测到 3.5 字符静默,判定一帧接收完成。
  4. 校验从站地址是否为 0x01,若不是则丢弃。
  5. 计算 CRC,若校验失败则丢弃,不返回任何响应。
  6. 解析功能码 0x03,检查寄存器地址和数量是否合法。
  7. 从寄存器映射区读取数据,组装响应帧。
  8. 计算响应帧 CRC,通过串口发送。

如果寄存器地址越界,从站应返回异常响应,功能码最高位置 1,并附带异常码 0x02(非法数据地址)。

异常响应示例:
01 83 02 C0 F1

01    从站地址
83    功能码 0x03 | 0x80
02    异常码:非法数据地址
C0 F1 CRC 校验

六、常见误区与复盘

在 RTU 从站开发初期,以下误区非常常见:

  • 误区一:收到完整帧才处理。RTU 没有长度字段,必须依靠静默间隔判断帧边界,不能等“收满多少字节”再处理。
  • 误区二:CRC 错误也回响应。CRC 校验失败的帧必须静默丢弃,否则会破坏总线上的请求-响应秩序。
  • 误区三:广播请求也回响应。地址 0 的广播写请求,从站执行后不能返回任何数据。
  • 误区四:忽略字符间隔。同一帧内字符间隔超过 1.5 字符时间,应判定帧错误并丢弃。
  • 误区五:把 TCP 思维带入串口。串行链路没有连接、没有重传、没有流控,从站必须自己维护帧状态机。
从站开发中最难调试的问题往往不是功能码逻辑,而是帧边界判断。建议在串口接收中断中同时维护“字节超时”和“帧超时”两个定时器,并用示波器或串口分析仪观察实际波形。

总结来看,Modbus RTU 从站的开发基础可以归纳为:理解主从秩序,明确串行链路与 TCP 的差异,掌握 RTU 帧结构和静默定界机制。只有把这些基础打牢,后续的寄存器映射、异常处理和性能优化才有稳定的落脚点。

Modbus RTU 主从通信与帧结构 主站 Master 发起请求 / 轮询 等待响应 / 超时判定 从站 Slave 地址 0x01 解析 / 校验 / 响应 RS-485 半双工总线 请求帧:01 03 00 00 00 02 C4 0B 响应帧:01 03 04 00 0A 00 14 ... RTU 帧结构(二进制编码) 从站地址 1 字节 功能码 1 字节 数据区 N 字节(≤252) CRC-16 2 字节 低字节在前 帧间隔定界:3.5 字符静默 帧 1 ≥3.5T 静默 帧 2 帧边界