# 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](https://modbus.org/specs.php) - MThings 使用手册: `Tools/MThings/MThings使用手册.pdf`