7.9 KiB
7.9 KiB
Modbus TCP 协议参考文档
用于 MThings 调试工具配置参考
1. 地址划分
Modbus 协议定义了四种数据类型,每种类型有独立的地址空间:
| 类型 | 代码 | 地址范围 | 功能码 | 数据大小 | 访问 | MThings BLOCK |
|---|---|---|---|---|---|---|
| Coils (线圈) | 0x | 00001-09999 | 01/05/15 | 1 bit | 读/写 | 0 |
| Discrete Inputs (离散输入) | 1x | 10001-19999 | 02 | 1 bit | 只读 | 1 |
| Holding Registers (保持寄存器) | 4x | 40001-49999 | 03/06/16 | 16 bit | 读/写 | 2 |
| Input Registers (输入寄存器) | 3x | 30001-39999 | 04 | 16 bit | 只读 | 3 |
注意: 保持寄存器(Holding Registers)是最常用的类型,MThings 中 BLOCK=2
2. 功能码说明
| 功能码 | 名称 | 说明 |
|---|---|---|
| 01 | Read Coils | 读取线圈状态(位) |
| 02 | Read Discrete Inputs | 读取离散输入状态(位) |
| 03 | Read Holding Registers | 读取保持寄存器(最常用) |
| 04 | Read Input Registers | 读取输入寄存器 |
| 05 | Write Single Coil | 写单个线圈 |
| 06 | Write Single Register | 写单个保持寄存器 |
| 15 | Write Multiple Coils | 写多个线圈 |
| 16 | Write Multiple Registers | 写多个保持寄存器 |
3. 错误码说明
当从站无法正常处理请求时,返回异常响应(功能码最高位置1)
| 代码 | 名称 | 说明 | 原因 | 解决方案 |
|---|---|---|---|---|
| 01 | ILLEGAL_FUNCTION | 非法功能码 | 从站不支持请求的功能码 | 检查功能码是否正确 |
| 02 | ILLEGAL_DATA_ADDRESS | 非法数据地址 | 请求的地址超出有效范围 | 检查起始地址和数量 |
| 03 | ILLEGAL_DATA_VALUE | 非法数据值 | 请求数据包中的值不合法 | 检查写入的数据值 |
| 04 | SLAVE_DEVICE_FAILURE | 从站设备故障 | 从站执行时发生错误 | 检查从站设备状态 |
| 05 | ACKNOWLEDGE | 确认 | 从站需要较长时间处理 | 稍后重新发送请求 |
| 06 | SLAVE_DEVICE_BUSY | 从站设备忙 | 从站正在处理其他命令 | 等待后重试 |
| 08 | MEMORY_PARITY_ERROR | 内存奇偶校验错误 | 从站内存错误 | 检查从站硬件 |
| 0A | GATEWAY_PATH_UNAVAILABLE | 网关路径不可用 | 网关配置错误 | 检查网关配置 |
| 0B | GATEWAY_TARGET_FAILED | 网关目标设备响应失败 | 目标设备未响应 | 检查目标设备是否在线 |
4. Modbus TCP 帧格式
Modbus TCP 在标准 Modbus 帧前添加 MBAP 头:
MBAP 头 (7 字节)
| 字段 | 字节数 | 说明 |
|---|---|---|
| Transaction ID | 2 | 事务标识符,用于匹配请求和响应 |
| Protocol ID | 2 | 协议标识符,Modbus 固定为 0x0000 |
| Length | 2 | 后续字节数(单元标识符 + PDU) |
| Unit ID | 1 | 单元标识符(从站地址),TCP 通常为 0 或 1 |
示例:读取保持寄存器
请求: 读取从站1的地址1000开始的3个寄存器
00 01 00 00 00 06 01 03 03 E8 00 03
│ │ │ │ │ │ │ │ │ │ │ │
│ │ │ │ │ │ │ │ │ │ └──┴── 寄存器数量 (3)
│ │ │ │ │ │ │ │ └──┴────── 起始地址 (1000 = 0x03E8)
│ │ │ │ │ │ │ └─────────── 功能码 (03 = 读保持寄存器)
│ │ │ │ │ │ └────────────── 单元ID (从站地址 1)
│ │ │ │ └──┴───────────────── 长度 (6字节)
│ │ └──┴─────────────────────── 协议ID (0x0000 = Modbus)
└──┴───────────────────────────── 事务ID (0x0001)
响应: 返回3个寄存器的值
00 01 00 00 00 09 01 03 06 00 01 00 00 00 00
│ │ │ │ │ │ │ │ │ │ │ │ │ │ │
│ │ │ │ │ │ │ │ │ │ │ │ │ └──┴── 寄存器3 (0)
│ │ │ │ │ │ │ │ │ │ │ └──┴────── 寄存器2 (0)
│ │ │ │ │ │ │ │ │ └──┴──────────── 寄存器1 (1)
│ │ │ │ │ │ │ │ └───────────────── 字节数 (6)
│ │ │ │ │ │ │ └──────────────────── 功能码 (03)
│ │ │ │ │ │ └─────────────────────── 单元ID (1)
│ │ │ │ └──┴────────────────────────── 长度 (9字节)
│ │ └──┴──────────────────────────────── 协议ID
└──┴────────────────────────────────────── 事务ID
5. 数据类型转换
Modbus 寄存器为 16 位,多字节数据需要多个寄存器:
| 类型 | 寄存器数 | 范围 | 说明 |
|---|---|---|---|
| UINT16 | 1 | 0 ~ 65535 | 无符号16位整数 |
| INT16 | 1 | -32768 ~ 32767 | 有符号16位整数 |
| UINT32 | 2 | 0 ~ 4294967295 | 无符号32位整数 |
| INT32 | 2 | -2147483648 ~ 2147483647 | 有符号32位整数 |
| FLOAT32 | 2 | IEEE 754 | 单精度浮点数 |
Float32 示例
值 50.0 的 IEEE 754 表示:
IEEE 754: 0x42480000
大端序 (Big Endian):
寄存器1 (高位): 0x4248
寄存器2 (低位): 0x0000
6. MThings 配置参数说明
BLOCK (数据区域)
| 值 | 说明 |
|---|---|
| 0 | 线圈 Coils (功能码 01/05/15) |
| 1 | 离散输入 Discrete Inputs (功能码 02) |
| 2 | 保持寄存器 Holding Registers (功能码 03/06/16) |
| 3 | 输入寄存器 Input Registers (功能码 04) |
PrtcTYPE (数据类型)
| 值 | 说明 |
|---|---|
| 1 | UINT16 - 无符号16位整数 |
| 2 | FLOAT32 - 32位浮点数 |
| 3 | INT16 - 有符号16位整数 |
| 4 | UINT32 - 无符号32位整数 |
| 5 | INT32 - 有符号32位整数 |
Size (寄存器数量)
| 值 | 说明 |
|---|---|
| 1 | 1个寄存器 (16位) |
| 2 | 2个寄存器 (32位) |
| 4 | 4个寄存器 (64位) |
ByteOder (字节序)
| 值 | 说明 |
|---|---|
| 0 | 大端序 Big Endian (高字节在前) - 常用 |
| 1 | 小端序 Little Endian (低字节在前) |
WordOder (字序)
| 值 | 说明 |
|---|---|
| 0 | 高字在前 - 常用 |
| 1 | 低字在前 |
ShowType (显示类型)
| 值 | 说明 |
|---|---|
| 0 | 浮点数显示 |
| 1 | 十六进制显示 |
| 2 | 十进制显示 |
| 3 | 二进制显示 |
LinkMode (连接模式)
| 值 | 说明 |
|---|---|
| 0 | TCP Client 模式 |
| 1 | TCP Server 模式 |
7. 常见问题
Q1: 为什么读取的数据全是0?
A: 检查地址是否正确,注意有些设备地址从0开始,有些从1开始。
Q2: 为什么连接超时?
A: 检查IP地址和端口是否正确,防火墙是否放行502端口。
Q3: 为什么浮点数显示不正确?
A: 检查字节序(ByteOder)和字序(WordOder)设置,不同厂商可能使用不同的字节序。
Q4: 返回异常码02是什么意思?
A: 非法数据地址(ILLEGAL_DATA_ADDRESS),请求的地址超出设备有效范围。
Q5: 如何区分功能码03和04?
A:
- 功能码03:读取保持寄存器(Holding Registers),可读写
- 功能码04:读取输入寄存器(Input Registers),只读
8. 参考资料
- Modbus 官方规范: modbus.org
- MThings 使用手册:
Tools/MThings/MThings使用手册.pdf