基础信息
报文长度
串行链路上第一个 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
报文结构
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号线圈值
发送响应
抓包确认
报文解析
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
报文结构
地址域 | 功能码 | 数据 | 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号线圈值
发送响应
报文解析
TX(发送): 01 01 00 01 00 03 2d cb
报文 | 描述 |
---|---|
01 | 地址域,此处代表发送到1号从机 |
01 | 功能码(读线圈) |
00 01 00 03 | 指令数据,此处代表从1开始读3个 |
2d cb | CRC校验 |
在线校验截图,高低位反转得到2d cb
RX(响应): 01 01 01 05 91 8b
报文 | 描述 |
---|---|
01 | 地址域,此处代表1号从机响应 |
01 | 功能码(读线圈) |
01 05 | 此处01代表有效数据长度1字节,05=0101,反向得出1,3线圈true |
91 8b | CRC校验 |
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