4. Modbus 地址空间模型:线圈、离散输入、输入寄存器、保持寄存器的定义与地址范围(0x/1x/3x/4x)
Modbus 协议的核心设计思想之一,是将物理设备中的各类数据抽象为四种标准的数据对象。这四种对象构成了 Modbus 的地址空间模型。理解这个模型是进行设备地址映射与调试的基础,它决定了上位机(如 SCADA、PLC)如何通过功能码访问从站设备中的具体数据点。
4.1 四种数据对象的定义与特性
Modbus 协议定义了四种基本数据对象:线圈(Coil)、离散输入(Discrete Input)、输入寄存器(Input Register)和保持寄存器(Holding Register)。它们的主要区别在于读写属性和数据宽度。
| 数据对象 | 数据宽度 | 读写属性 | 物理意义 | 典型应用 |
|---|---|---|---|---|
| 线圈 (Coil) | 1 位 (Bit) | 可读可写 | 数字量输出 | 继电器、电磁阀、指示灯、电机启停 |
| 离散输入 (Discrete Input) | 1 位 (Bit) | 只读 | 数字量输入 | 按钮、限位开关、光电传感器、急停信号 |
| 输入寄存器 (Input Register) | 16 位 (Word) | 只读 | 模拟量输入 | 温度传感器、压力变送器、液位计、流量计 |
| 保持寄存器 (Holding Register) | 16 位 (Word) | 可读可写 | 模拟量输出/参数 | 变频器频率设定、PID 参数、阀门开度、累计值 |
调试要点: 在调试时,务必先确认目标数据点的读写属性。例如,试图通过“写线圈”功能码去修改一个“离散输入”的值,从站设备会返回异常码(Illegal Data Address 或 Illegal Function),导致通信失败。
4.2 地址范围与寻址约定(0x/1x/3x/4x)
在 Modbus 协议标准中,为了在文档和组态软件中方便区分这四种数据对象,业界形成了基于“前缀 + 偏移地址”的寻址约定。这种表示法并非协议报文中的实际地址,而是逻辑地址。
- 0x 区(线圈): 地址范围通常为 00001 ~ 09999(十进制)。对应功能码:01(读线圈)、05(写单线圈)、15(写多线圈)。
- 1x 区(离散输入): 地址范围通常为 10001 ~ 19999(十进制)。对应功能码:02(读离散输入)。
- 3x 区(输入寄存器): 地址范围通常为 30001 ~ 39999(十进制)。对应功能码:04(读输入寄存器)。
- 4x 区(保持寄存器): 地址范围通常为 40001 ~ 49999(十进制)。对应功能码:03(读保持寄存器)、06(写单寄存器)、16(写多寄存器)。
常见陷阱: 协议报文中的实际地址是“偏移地址”,即从 0 开始。例如,逻辑地址 40001 在报文中的实际地址是 0x0000(十六进制)。组态软件或驱动库通常会自动处理这个偏移,但手动构造报文时,必须使用偏移地址。
下表展示了逻辑地址与报文地址的转换关系:
| 数据对象 | 逻辑地址(PLC 组态) | 报文偏移地址(十六进制) | 报文偏移地址(十进制) |
|---|---|---|---|
| 线圈 | 00001 | 0x0000 | 0 |
| 离散输入 | 10001 | 0x0000 | 0 |
| 输入寄存器 | 30001 | 0x0000 | 0 |
| 保持寄存器 | 40001 | 0x0000 | 0 |
| 保持寄存器 | 40010 | 0x0009 | 9 |
4.3 地址空间模型结构图
下面的 SVG 图清晰地展示了 Modbus 地址空间的四象限模型,以及它们与物理设备 I/O 的对应关系。
4.4 实战中的地址映射原则
在厂务设备(如空调机组、水泵、空压机)的调试中,地址映射通常遵循以下步骤:
- 获取设备点表: 从设备供应商处获取 Modbus 地址映射表(Point Map),这是调试的“地图”。
- 识别数据类型: 根据点表中的“寄存器类型”列,判断该点属于 0x、1x、3x 还是 4x 区。
- 确认数据格式: 对于寄存器(3x/4x),需要确认数据格式(如 16 位无符号、32 位浮点、32 位整数)和字节序(Big-Endian / Little-Endian)。
- 填写组态软件: 在 SCADA 或触摸屏的变量表中,按照逻辑地址(如 40001)或偏移地址(如 0)进行配置。
案例: 某厂务空调系统的“送风温度”点表显示为“3x 区,地址 30005,数据类型 Float”。这意味着:
- 使用功能码 04 读取输入寄存器。
- 报文偏移地址为 4(因为 30005 - 30001 = 4)。
- 需要连续读取 2 个寄存器(16位 * 2 = 32位浮点)。
- 在组态软件中,变量地址填写为 30005 或 40005(取决于软件约定),并选择 Float 类型。
4.5 常见误区与避坑指南
| 误区 | 正确理解 | 后果 |
|---|---|---|
| 认为 40001 在报文中的地址也是 40001 | 报文地址是偏移地址 0x0000 | 通信超时或读取到错误数据 |
| 混淆 3x 和 4x 区的读写属性 | 3x 只读,4x 可读可写 | 写入 3x 区导致异常码返回 |
| 忽略寄存器数据的字节序 | 需确认设备是 Big-Endian 还是 Little-Endian | 读取到的数值(如 32 位浮点)完全错误 |
| 认为所有设备地址都从 00001 开始 | 部分设备地址可能从 0 或 1 开始,需查看点表 | 地址偏移计算错误,导致数据错位 |