MODBUS协议报文详解
MODBUS是一种串行通信协议,是Modicon公司(现在的施耐德电气Schneider Electric)于1979年为使用可编程逻辑控制器(PLC)通信而发表。Modbus已经成为工业领域通信协议的业界标准(De facto),并且现在是工业电子设备之间常用的连接方式。

基础信息

报文长度

串行链路上第一个 MODBUS 执行的长度约束限制了 MODBUS PDU 大小(最大 RS485ADU=256字节)。

因此,对串行链路通信来说,MODBUS PDU=256-服务器地址(1 字节)-CRC(2 字节)=253字节。

从而:

RS232 / RS485 ADU = 253 字节+服务器地址(1 byte) + CRC (2 字节) = 256 字节。

TCP MODBUS ADU = 249 字节+ MBAP (7 字节) = 256 字节。

操作对象

操作对象 描述
线圈 相当于开关,在MODBUS中可读可写,数据只有00和01
离散量 输入位,开关量,在MODBUS中只读
输入寄存器 只能从模拟量输入端改变的寄存器,在MODBUS中只读
保持寄存器 用于输出模拟量信号的寄存器,在MODBUS中可读可写

功能码

注: 异常码为功能码+0x80

功能码 异常码 描述
0x01 0x81 读线圈
0x05 0x05 写单个线圈
0x0F 0x0F 写多个线圈
0x02 0x02 读离散量输入
0x04 0x04 读输入寄存器
0x03 0x03 读保持寄存器
0x06 0x06 写单个保持寄存器
0x10 0x10 写多个保持寄存器

MODBUS TCP

2301031508.png

报文结构

MBAP报文头

长度(字节) 示例 描述
事务元标识符 2 0x00 0x00 MODBUS 请求/响应事务处理的识别码,可以解释为报文的序列号,由于我们测试使用的Modbus Poll客户端是一直发送数据,所以每发送一次数据标识符就加一。服务器接收时会把这个数据原封返回。
协议标识符 2 0x00 0x00 0=MODBUS 协议
长度 2 0x00 0x00 表示从单元标识符开始后面数据的长度。如:00 06表示后面有0x06个字节长度的数据。
单元标识符 1 0x01 串行链路或其它总线上连接的远程从站的识别码,相当于设备的地址。一般为01。

PDU (帧结构)

长度(字节) 示例 描述
功能码 1 0x01 modbus的功能码列
数据 0~248 0x00 受限于ADU256字节上限

示例报文解读

读取01-03号线圈值

发送响应

2301031612.png

抓包确认

2301031610.png

2301031611.png

报文解析

TX(发送): 08 80 00 00 00 06 01 01 00 01 00 03

报文 描述
08 80 事务标识符
00 00 Modbus TCP协议标识
00 06 剩余报文长度
01 单元标识符
01 功能码(读线圈)
00 01 00 03 指令数据,此处代表从1开始读3个

RX(响应): 08 80 00 00 00 04 01 01 01 05

报文 描述
08 80 事务标识符
00 00 Modbus TCP协议标识
00 04 剩余报文长度
01 单元标识符
01 功能码(读线圈)
01 05 此处01代表有效数据长度1字节,05=0101,反向得出1,3线圈true

MODBUS RTU

2301041130.png

报文结构

地址域 功能码 数据 CRC校验
1字节 1字节 0-252字节 2字节

地址域

Modbus 寻址空间有 256 个不同地址。

0 1~247 248~255
广播地址 子节点单独地址 保留地址

地址 0 保留为广播地址。 所有的子节点必须识别广播地址。

Modbus 主节点没有地址, 只有子节点必须有一个地址。 该地址必须在 Modbus 串行总线上唯一。

PDU (帧结构)

长度(字节) 示例 描述
功能码 1 0x01 modbus的功能码列
数据 0~248 0x00 受限于ADU256字节上限

CRC校验

校验码:Modbus通讯采用CRC-16循环冗余错误校验 ,冗余循环码CRC包含2个字节,即16位二进制。

CRC计算方法是:

1、 加载一值为0xFFFF的16位寄存器,此寄存器为CRC寄存器。

2、 把第一个8位二进制数据(即通讯信息帧的第一个字节)与16位的CRC寄存器的相异或,异或的结果仍存放于该CRC寄存器中。

3、 把CRC寄存器的内容右移一位,用0填补最高位,并检测移出位是0还是1。

4、 如果移出位为零,则重复第三步(再次右移一位);如果移出位为1,CRC寄存器与0xA001进行异或。

5、 重复步骤3和4,直到右移8次,这样整个8位数据全部进行了处理。

6、 重复步骤2和5,进行通讯信息帧下一个字节的处理。

7、 将该通讯信息帧所有字节按上述步骤计算完成后,得到的16位CRC寄存器的高、低字节进行交换

8、 最后得到的CRC寄存器内容即为:CRC校验码。

示例报文解读

读取01-03号线圈值

发送响应

2301061600.png

报文解析

TX(发送): 01 01 00 01 00 03 2d cb

报文 描述
01 地址域,此处代表发送到1号从机
01 功能码(读线圈)
00 01 00 03 指令数据,此处代表从1开始读3个
2d cb CRC校验

在线校验截图,高低位反转得到2d cb

2301061601.png

RX(响应): 01 01 01 05 91 8b

报文 描述
01 地址域,此处代表1号从机响应
01 功能码(读线圈)
01 05 此处01代表有效数据长度1字节,05=0101,反向得出1,3线圈true
91 8b CRC校验

2301061602.png

MODBUS ASCII

起始符 地址域 功能码 数据 LRC校验 结束符
1字节 2字节 2字节 0-2*252字节 2字节 2字节

报文结构

在 ASCII 模式, 报文用特殊的字符区分帧起始和帧结束。一个报文必须以一个冒号(: ASCII 十六进制 3A )起始, 以回车-换行 (CR LF ASCII 十六进制 0D 和 0A) 结束。

注 : LF 字符可以通过特定的 Modbus 应用命令 (参见 Modbus 应用协议规范) 改变。

对于所有的域,允许传送的字符为十六进制 0–9, A–F (ASCII 编码)。 设备连续的监视总线上的起始符。 当收到:这个字符后,每个设备解码后续的字符一直到帧结束。

报文中字符间的时间间隔可以达一秒。如果有更大的间隔,则接受设备认为发生了错误。

起始符&结束符

报文位 十六进制 备注
起始符 0x3A :
结束符 0x0D 0x0A \r\n

LRC校验

纵向冗余校验(LRC)为一个字节,含有 8 位二进制值。LRC 由发送设备计算,并附加 LRC 到 报文。接收设备在接收文时计算 LRC, 并将计算的结果与在 LRC 接收到的实际值相比较,如果两 个值不相等,则结果为错。

LRC 的计算, 对报文中的所有的连续 8 位字节相加,忽略任何进位,然后求出其二进制补码。 LRC 为一个 8 位域,那么每个会导致值大于 255 新的相加只是简单的将域的值在零”回绕”。因为没 有第 9 位,进位被自动放弃。

生成一个 LRC 的过程为:

1.不包括起始”冒号”和结束 CRLF 的报文中的所有字节相加到一个 8 位域,故此进位被丢弃。

2.从 FF (全 1)十六进制中减去域的最终值,产生 1 的补码(二进制反码)。

3.加 1 产生二进制补码.

其他

原始数据同RTU模式数据,进行bin2hex操作,0xAA => 0x61 0x61 (aa), 因此在ASCII模式下,地址域、功能码、数据长度翻倍

示例报文解读

暂无相关设备模拟


Last modified on 2023-01-03