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 字节。
五、典型场景:从站如何响应一次读取
假设主站通过 RS-485 总线轮询地址为 0x01 的从站,请求读取保持寄存器 0x0000 开始的 2 个寄存器。从站的处理流程如下:
- 串口接收到第一个字节,启动帧间隔定时器。
- 持续接收字节,每收到一个字节重置定时器。
- 检测到 3.5 字符静默,判定一帧接收完成。
- 校验从站地址是否为 0x01,若不是则丢弃。
- 计算 CRC,若校验失败则丢弃,不返回任何响应。
- 解析功能码 0x03,检查寄存器地址和数量是否合法。
- 从寄存器映射区读取数据,组装响应帧。
- 计算响应帧 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 帧结构和静默定界机制。只有把这些基础打牢,后续的寄存器映射、异常处理和性能优化才有稳定的落脚点。