3. Modbus数据模型
Modbus 之所以能在不同厂商、不同设备之间稳定互通,核心原因之一是它把设备内部的数据抽象成了一套统一的数据模型。无论底层是 PLC、变频器、电表还是温控器,主站看到的都只有四类数据对象:线圈(Coil)、离散输入(Discrete Input)、保持寄存器(Holding Register)和输入寄存器(Input Register)。理解这四类对象的定义、访问方向和地址空间,是后续读写测试、报文分析和故障诊断的基础。
一、四类数据对象的定义
Modbus 数据模型按“位/字”和“可读写/只读”两个维度划分,形成四个相互独立的地址空间。它们不是同一块内存的四个区域,而是四张独立的表,各自有独立的寻址范围。
- 线圈(Coil,0x 区):1 位数据,主站可读可写。通常映射设备的开关量输出,如继电器吸合、指示灯点亮、阀门开闭命令。功能码 01 读、05 写单个、15 写多个。
- 离散输入(Discrete Input,1x 区):1 位数据,主站只读。通常映射设备的开关量输入,如限位开关、按钮状态、故障干接点。功能码 02 读取。
- 保持寄存器(Holding Register,4x 区):16 位数据,主站可读可写。通常映射设备参数、设定值、控制字,如频率给定、PID 目标值。功能码 03 读、06 写单个、16 写多个。
- 输入寄存器(Input Register,3x 区):16 位数据,主站只读。通常映射实时测量值,如电压、电流、温度、转速。功能码 04 读取。
二、四类对象的对比与地址映射
下表从数据宽度、访问权限、典型用途、常用功能码和地址范围五个维度进行对比,便于测试时快速判断该用哪个功能码。
| 数据对象 | 宽度 | 访问权限 | 典型用途 | 常用功能码 | 传统地址范围 |
|---|---|---|---|---|---|
| 线圈 Coil | 1 位 | 读写 | 继电器输出、启停命令 | 01 / 05 / 15 | 00001–09999 |
| 离散输入 Discrete Input | 1 位 | 只读 | 限位、按钮、干接点状态 | 02 | 10001–19999 |
| 输入寄存器 Input Register | 16 位 | 只读 | 电压、电流、温度测量值 | 04 | 30001–39999 |
| 保持寄存器 Holding Register | 16 位 | 读写 | 参数设定、控制字、累计量 | 03 / 06 / 16 | 40001–49999 |
需要特别注意的是地址偏移问题。设备手册常写“40001”,而报文中的起始地址是 0;手册写“40100”,报文中是 99。测试时若读不到数据,首先要核对是否多加了 1 或少加了 1。此外,32 位浮点数或长整型会占用两个连续寄存器,存在高字在前还是低字在前的字节序差异,这也是诊断中的高频问题。
三、测试中的典型读写流程
以一台支持 Modbus RTU 的变频器为例,主站通常按以下顺序操作:先读输入寄存器获取母线电压和输出频率,再读离散输入确认运行/故障状态,然后写保持寄存器设定目标频率,最后写线圈执行启动命令。这个顺序体现了“先观测、后控制”的安全原则。
# 读取输入寄存器(只读测量值),从站地址 1,起始 0,数量 2
请求: 01 04 00 00 00 02 71 CB
响应: 01 04 04 09 C4 13 88 7A 3E
解析: 0x09C4 = 2500 → 母线电压 250.0 V
0x1388 = 5000 → 输出频率 50.00 Hz
# 写单个保持寄存器(设定频率 45.00 Hz = 4500 = 0x1194)
请求: 01 06 00 10 11 94 8C 3A
响应: 01 06 00 10 11 94 8C 3A # 原样回显表示成功
# 写单个线圈(启动,ON)
请求: 01 05 00 00 FF 00 8C 3A
响应: 01 05 00 00 FF 00 8C 3A
从报文可以看出,功能码直接决定了访问哪张表:04 只能读输入寄存器,03 只能读保持寄存器,二者不能混用。若用 03 去读只读测量值,从站通常返回异常码 02(非法数据地址)。
四、常见误区与诊断要点
- 地址偏移:手册 40001 ↔ 报文 0,手册 40100 ↔ 报文 99,差 1 是最常见的“读不到”原因。
- 字序问题:32 位数据可能高字在前(Big-endian)或低字在前(Little-endian),需对照手册确认。
- 功能码错配:用 03 读输入寄存器、用 04 读保持寄存器都会失败,异常码多为 02。
- 数量越界:一次读取的寄存器数量超过从站支持上限,会返回异常码 03。
- 权限误判:把只读测量值当作可写参数下发,写操作被拒绝,需回到数据模型重新分类。
掌握这四类数据对象的定义与区别后,面对任何 Modbus 设备,都可以先查手册确定某个量的对象类型,再选择正确的功能码和地址,最后用报文验证。这一步做扎实,后续的异常码分析、通信超时排查和性能优化都会顺畅很多。