modbusTCP通讯过程
一、协议介绍
Modbus TCP 是 Modbus 协议在 TCP/IP 网络上的扩展实现。它基于 Modbus 传统的请求 - 响应模式,通过 TCP/IP 网络传输数据

二、功能码
什么是功能码?
拿王者荣耀的英雄技能举例.当你想英雄使用1技能时,使用 01 功能码(游戏实际是按下1技能的按键)
所以,功能码就是区分协议中不同功能的标识。发送不同的功能码,协议会根据不同的功能码来就行相应的响应
| 功能码 | 技能 |
|---|---|
| 01 | 1技能 |
| 02 | 2技能 |
| 03 | 3技能 |
2.1 功能码
字(Word):1 字 = 16 位 = 2 字节
字节(byte):1 字节 = 8 位
位(bit):计算机中最小的信息单位,1 位表示 0 或 1。
| 功能码 | 名称 | 位/字操作 | 操作数量 |
|---|---|---|---|
| 01 | 读线圈状态 | 位 | 单个/多个 |
| 02 | 读离散输入状态 | 位 | 单个/多个 |
| 03 | 读保持寄存器 | 字 | 单个/多个 |
| 04 | 读输入寄存器 | 位 | 单个/多个 |
| 05 | 写单个线圈 | 位 | 单个 |
| 06 | 写单个保持寄存器 | 字 | 单个 |
| 15 | 写多个线圈 | 位 | 多个 |
| 16 | 写多个保持寄存器 | 字 | 多个 |
从表格中可以看到,对线圈都是位操作;对寄存器都是字操作。
三、报文结构
报文构成
| MBAP Header | Function code | data |
|---|
3.1 MBAP 报文头说明
| Transaction identifier | Protocol identifier | Length | Unit identifier |
|---|---|---|---|
| 2 byte | 2 byte | 2 byte | 1 byte |
| 匹配请求响应 | 固定为0 (modbusTCP) | 后续的字节长度 | 标识从站设备 |
| 0 ~ 65535 | 0x00 | 0 ~ 65535 |
3.2 读保持寄存器报文
请求报文结构:
| 传输标识 | 协议标识 | 字节长度 | 从机标识 | 功能码 | 起始寄存器地址 | 从起始寄存器开始读寄存器数量 |
|---|---|---|---|---|---|---|
| 2 byte | 2 byte | 2 byte | 1 byte | 1 byte | 2 byte | 2 byte |
响应报文结构:
| 传输标识 | 协议标识 | 字节长度 | 从机标识 | 功能码 | 数据长度 | 寄存器数据 |
|---|---|---|---|---|---|---|
| 2 byte | 2 byte | 2 byte | 1 byte | 1 byte | 2 byte | 2 * 数据长度 byte |
读寄存器地址位 00 的数据 报文示例
Tx--0193 : 00 00 00 00 00 06 01 03 00 00 00 01
Rx--0194: 00 00 00 00 00 05 01 03 02 00 c8
读寄存器地址位 00 01 04 06 的数据 报文示例
Tx--0023 : 00 00 00 00 00 06 01 03 00 00 00 07
Rx--0024: 00 00 00 00 00 11 01 03 0e 00 c8 00 64 00 00 01 f4 01 f4 00 7d 00 7d
在这个示例中。可以发现即使不读 02 03 05的数据,报文请求也会把其包含。
再看另一个 读寄存器地址位 00 01 04 06 的数据 报文
Tx--0001 : 00 00 00 00 00 06 01 03 00 00 00 02
Rx--0002: 00 00 00 00 00 07 01 03 04 00 c8 00 64
Tx--0000 : 01 00 00 00 00 06 01 03 00 04 00 01
Rx--0001: 01 00 00 00 00 05 01 03 02 01 f4
Tx--0001 : 02 00 00 00 00 06 01 03 00 06 00 01
Rx--0002: 02 00 00 00 00 05 01 03 02 00 7d
但是这个报文,却是把地址没有连在一起的寄存器分开来读,这是为什么呢?因为我把单帧最大寄存器数设置成了2
3.3 写单个保持寄存器 0x06
请求报文结构:
| 传输标识 | 协议标识 | 字节长度 | 从机标识 | 功能码 | 寄存器地址 | 控制下发数据 |
|---|---|---|---|---|---|---|
| 2 byte | 2 byte | 2 byte | 1 byte | 1 byte | 2 byte | 2 byte |
响应报文结构:
| 传输标识 | 协议标识 | 字节长度 | 从机标识 | 功能码 | 寄存器地址 | 控制下发数据 |
|---|---|---|---|---|---|---|
| 2 byte | 2 byte | 2 byte | 1 byte | 1 byte | 2 byte | 2 byte |
报文示例:
Tx--0001 : 00 00 00 00 00 06 01 06 00 00 00 02
Rx--0002: 00 00 00 00 00 06 01 06 00 00 00 02
3.4 写多个寄存器 0x10
请求报文:
| 传输标识 | 协议标识 | 字节长度 | 从机标识 | 功能码 | 寄存器起始地址 | 寄存器数量 | 字节长度 | 控制下发数据 |
|---|---|---|---|---|---|---|---|---|
| 2 byte | 2 byte | 2 byte | 1 byte | 1 byte | 2 byte | 2 byte | 1 byte | 字节长度 byte |
响应报文结构:
| 传输标识 | 协议标识 | 字节长度 | 从机标识 | 功能码 | 寄存器地址 | 寄存器数量 |
|---|---|---|---|---|---|---|
| 2 byte | 2 byte | 2 byte | 1 byte | 1 byte | 2 byte | 2 byte |
从站报文示例:
Rx:000104-06 00 00 00 00 09 01 10 00 03 00 01 02 00 7B
Tx:000105-06 00 00 00 00 06 01 10 00 03 00 01
四、报文异常处理

浙公网安备 33010602011771号