2. Modbus协议基础
Modbus 是工业自动化领域应用最广泛的串行通信协议之一,也是网关集成项目中最常见的南向协议。理解 Modbus 的起源、主从架构、功能码、寄存器类型以及数据模型,是后续实现 Modbus RTU/TCP 网关转换、点位映射和故障排查的基础。本节从协议本质出发,逐层拆解 Modbus 的通信模型与数据组织方式。
一、Modbus 的起源与设计哲学
Modbus 由 Modicon 公司于 1979 年提出,最初用于 PLC 与编程终端之间的串行通信。它的设计目标非常朴素:在一条共享的串行总线上,让一个主设备能够读写多个从设备的离散量或寄存器数据。由于协议简单、帧结构紧凑、实现成本低,Modbus 逐渐成为工业现场的事实标准,并衍生出 Modbus RTU、Modbus ASCII、Modbus TCP 等多种承载形式。
Modbus 的核心哲学是“请求—应答”模型:主设备发起请求,从设备根据请求中的功能码执行操作并返回响应。协议本身不定义数据含义,只定义数据的位置和访问方式,因此同一份寄存器地址在不同设备中可能代表温度、频率或状态字,这要求集成时必须结合设备手册进行点位映射。
关键理解:Modbus 是一种“面向寄存器”的协议,而不是“面向对象”的协议。它只关心“读哪个地址、读几个、写什么值”,不关心数据在业务上代表什么。
二、主从架构与通信模型
Modbus 采用典型的主从(Master/Slave)架构。在串行链路上,同一时刻只能有一个主设备,从设备数量通常为 1~247。主设备主动发起请求,从设备被动响应;从设备之间不会直接通信。这种架构决定了 Modbus 的轮询特性:主站需要按顺序逐个访问从站,因此轮询周期、超时时间和重试次数会直接影响网关的实时性。
在 Modbus TCP 中,主从概念被弱化为 Client/Server,但通信模型仍然是请求—应答。TCP 承载方式使用 MBAP 报文头替代串行链路中的地址和 CRC 校验,使 Modbus 能够运行在以太网上。对于网关集成而言,常见的场景是:网关作为 Modbus TCP Server 接收上位机请求,同时作为 Modbus RTU Master 轮询下位设备,完成协议转换与数据映射。
三、功能码与寄存器类型
Modbus 通过功能码(Function Code)区分操作类型。最常用的功能码包括:01 读线圈、02 读离散输入、03 读保持寄存器、04 读输入寄存器、05 写单个线圈、06 写单个寄存器、15 写多个线圈、16 写多个寄存器。功能码决定了请求报文中数据域的结构,也决定了从设备的响应格式。
寄存器类型是 Modbus 数据模型的核心。传统上使用地址前缀区分四类数据:0x 表示线圈,1x 表示离散输入,3x 表示输入寄存器,4x 表示保持寄存器。其中线圈和离散输入是位数据,输入寄存器和保持寄存器是 16 位字数据。保持寄存器可读可写,输入寄存器只读,这一区别在网关点位配置中必须严格遵守。
| 数据类型 | 地址前缀 | 数据宽度 | 读写权限 | 常用功能码 |
|---|---|---|---|---|
| 线圈 Coil | 0x | 1 bit | 读写 | 01 / 05 / 15 |
| 离散输入 Discrete Input | 1x | 1 bit | 只读 | 02 |
| 输入寄存器 Input Register | 3x | 16 bit | 只读 | 04 |
| 保持寄存器 Holding Register | 4x | 16 bit | 读写 | 03 / 06 / 16 |
四、数据模型与通信模型的关系
Modbus 的数据模型是“扁平”的:所有数据都映射到四张独立的地址表中,每张表最多 65536 个条目。通信模型则定义了如何通过请求—应答访问这些表。主设备发送的请求包含从站地址、功能码、起始地址和数量;从设备根据功能码判断访问哪张表,再根据起始地址和数量读取或写入数据。
在网关集成中,数据模型与通信模型的衔接是核心难点。例如,上位机通过 Modbus TCP 读取保持寄存器 40001~40010,网关需要将其映射为 RTU 侧某从站的 4x 地址区间,并按照 RTU 帧格式重新封装。如果涉及 32 位浮点数或 64 位整数,还需要处理寄存器合并与字节序问题。常见字节序包括 ABCD、CDAB、BADC、DCBA,配置错误会导致数据解析异常。
# Modbus RTU 请求帧示例(读保持寄存器)
从站地址: 01
功能码: 03
起始地址: 00 00
寄存器数: 00 02
CRC: C4 0B
# 响应帧示例
从站地址: 01
功能码: 03
字节数: 04
数据: 00 64 00 C8
CRC: XX XX
五、典型场景与常见误区
假设一个网关项目需要采集 3 台 Modbus RTU 电表的数据,并向上位机提供 Modbus TCP 服务。电表的电压、电流、功率分别存放在保持寄存器 40001、40003、40005 中,均为 32 位浮点数。网关需要配置三条 RTU 轮询任务,分别读取对应寄存器区间,再将结果映射到 TCP 侧的连续地址空间。上位机读取时,网关从缓存中返回数据,而不是实时透传,这样可以避免 TCP 请求与 RTU 轮询的时序冲突。
常见误区:很多初学者认为 Modbus TCP 和 Modbus RTU 只是“换了个物理层”,实际上两者在报文结构、地址模型和事务处理上存在差异。TCP 侧有 MBAP 头和事务标识,RTU 侧有 CRC 校验和 3.5 字符间隔;网关必须完成完整的协议转换,而不是简单转发字节流。
排查建议:当网关采集异常时,先确认从站地址、功能码、起始地址和寄存器数量是否与设备手册一致;再检查字节序和数据类型;最后用串口调试工具或 Modbus 模拟器验证 RTU 链路是否正常。分层排查可以快速定位是配置问题、链路问题还是数据解析问题。