Modbus-TCP
解决:网络层数据传输错乱问题
2 Modbus TCp 指令说明:
功能码 | 功能 | 寄存器 PLC 地址 | 位操作 / 字操作 | 操作数量 |
---|---|---|---|---|
01H | 读线圈状态 | 00001-09999 | 位操作 (1 字节) | 单个或多个 |
02H | 读离散输入状态 | 10001-19999 | 位操作 (1 字节) | 单个或多个 |
03H | 读保持寄存器 | 40001-49999 | 字操作 (2 字节) | 单个或多个 |
04H | 读输入寄存器 | 30001-39999 | 字操作 (2 字节) | 单个或多个 |
05H | 写单个线圈 | 00001-09999 | 位操作 (1 字节) | 单个 |
06H | 写单个保持寄存器 | 40001-49999 | 字操作 (2 字节) | 单个 |
0FH | 写多个线圈 | 00001-09999 | 位操作 (1 字节) | 多个 |
10H | 写多个保持寄存器 | 40001-49999 | 字操作 (2 字节) | 多个 |
Modbus TCP报文
简单理解Modbus TCP协议内容,就是去掉了Modbus RTU协议本身的CRC校验,增添了MBAP报文。Modbus TCP报文可分为两部分:MBAP+PDU。Modbus TCP的请求/相应如下:
<–MODBUS TCP/IP ADU—>
MBAP报文头 + 功能码 + 数据
<----PDU—>
MBAP 报文头解析:
区域 | 长度 | 描述 | 客户端 | 服务器 |
---|---|---|---|---|
传输标识 | 2字节 | 请求和响应报文的序号 | 请求时生成 | 应答时复制该值 |
协议表示 | 2字节 | Modbus TCP协议默认为0 | 请求时生成 | 应答时复制该值 |
长度 | 2字节 | 从单元表示开始的剩余报文长度 | 请求时生成 | 应答时生产 |
单元标识 | 1字节 | 从机标示(从机地址) | 请求时生成 | 应答时复制该值 |
【注】
(1)传输标识可理解为序列号,防止 Modbus TCP 通信错位,例如后发生的响应先到了主机,而早发生的响应后到主机;
(2)单元标识可理解为从机地址,此时已经不再重要。
Modbus TCP 请求报文格式
类型 | 描述 |
---|---|
MBAP报文头 | 传输标识高字节 |
MBAP报文头 | 传输标识低字节 |
MBAP报文头 | 协议标识高字节 |
MBAP报文头 | 协议标识低字节 |
MBAP报文头 | 长度高字节 |
MBAP报文头 | 长度低字节 |
MBAP报文头 | 单元标识(1字节) |
PDU报文(请求) | 功能码(1字节) |
PDU报文(请求) | 数据区(若干字节,见各功能码描述部分) |
Modbus TCP 响应报文格式
类型 | 描述 |
---|---|
MBAP报文头 | 传输标识高字节 |
MBAP报文头 | 传输标识低字节 |
MBAP报文头 | 协议标识高字节 |
MBAP报文头 | 协议标识低字节 |
MBAP报文头 | 长度高字节 |
MBAP报文头 | 长度低字节 |
MBAP报文头 | 单元标识(1字节) |
PDU报文(请求) | 功能码(1字节) |
PDU报文(请求) | 数据区(若干字节,见各功能码描述部分) |
举例:
带报文头发送
12 21 00 00 00 08 01 03 00 00 00 01 FE D7=
{
12 21 = 传输表示(自定义)
00 00 = 协议标示
00 08 = 长度
01 = 单元标示
03 = 功能码
00 00 00 01 FE D7 = 数据 = {00 = 寄存器起始地址高字节
00 = 寄存器起始地址低字节
00 =寄存器数量高字节
01 = 寄存器数量高字节
FE D7 = CRC 16位低字节校验 } }回复
12 21 00 00 00 05 01 03 02 00 00 = {
MBAP报文头包括:传输标示 :12 21
协议标示 :00 00
长 度 :00 05
单元标示 :01
功能码:03
数据:02 00 00 = {
返回字节数:02
数据1高字节:00
数据1低字节:00
}}