modbus协议解析
2021-10-25
标准Modbus RTU指令 | ||||||||||||||||
寄存器单元(十进制) | 功能码 | 作用 | 请求及响应格式 | |||||||||||||
线圈寄存器 CoilStatus (00001 - 09999) 1位 读写 |
0x01 | 读线圈 | 指示状态1 = ON,0 = OFF 示例:读取0x0001到0x000A单元的开关状态,现场状态为全开(即全1) | |||||||||||||
请求: | 设备号 | 功能码 | 寄存器起始地址 | 寄存器单元长度 | CRC校验 | |||||||||||
id | 01 | 00 | 00 | 00 | 0A | crcl | crch | |||||||||
响应: | 设备号 | 功能码 | 字节数 | 数据 | CRC校验 | |||||||||||
id | 01 | 02 | FF | 03 | crcl | crch | ||||||||||
0x05 | 写单个线圈 | 十六进制FF 00置状态为ON,十六进制00 00 置状态为OFF 示例:将0x00AD单元状态置为ON/OFF | ||||||||||||||
请求: | 设备号 | 功能码 | 寄存器起始地址 | 置为ON/OFF | CRC校验 | |||||||||||
id | 05 | 00 | AC | FF | 00 | crcl | crch | |||||||||
id | 05 | 00 | AC | 00 | 00 | crcl | crch | |||||||||
响应: | 设备号 | 功能码 | 寄存器起始地址 | 置为ON/OFF | CRC校验 | |||||||||||
id | 05 | 00 | AC | FF | 00 | crcl | crch | |||||||||
id | 05 | 00 | AC | 00 | 00 | crcl | crch | |||||||||
0x0F | 写多个线圈 | 示例:从0x0014开始写入10个状态值,数据内容为2个字节:十六进制CD 01(二进制 1100 1101 0000 0001) | ||||||||||||||
请求: | 设备号 | 功能码 | 寄存器起始地址 | 寄存器单元长度 | 字节数 | 数据 | CRC校验 | |||||||||
id | 0F | 00 | 13 | 00 | 0A | 02 | CD | 01 | crcl | crch | ||||||
响应: | 设备号 | 功能码 | 寄存器起始地址 | 寄存器单元长度 | CRC校验 | |||||||||||
id | 0F | 00 | 13 | 00 | 0A | crcl | crch | |||||||||
离散寄存器 InputStatus (10001 - 19999) 1位 只读 |
0x02 | 读离散输入 | 示例:读取197—218的开关状态,204-197内容为0xAC(即二进制1010 1100),212-205内容为0xDB(即二进制1101 1011),218-213内容为0x35(即二进制0011 0101) | |||||||||||||
请求: | 设备号 | 功能码 | 寄存器起始地址 | 寄存器单元长度 | CRC校验 | |||||||||||
id | 02 | 00 | C4 | 00 | 16 | crcl | crch | |||||||||
响应: | 设备号 | 功能码 | 字节数 | 数据 | CRC校验 | |||||||||||
id | 02 | 03 | AC | DB | 35 | crcl | crch | |||||||||
保持寄存器 Holding Register(40001 - 49999) 16位 读写 |
0x03 | 读保持寄存器 | 示例:读取寄存器108—110的值,108的内容为0x022B(即555),109的内容为0x0000(即0),110的内容为0x0064(即100) | |||||||||||||
请求: | 设备号 | 功能码 | 寄存器起始地址 | 寄存器单元长度 | CRC校验 | |||||||||||
id | 03 | 00 | 6B | 00 | 03 | crcl | crch | |||||||||
响应: | 设备号 | 功能码 | 字节数 | 数据 | CRC校验 | |||||||||||
id | 03 | 06 | 02 | 2B | 00 | 00 | 00 | 64 | crcl | crch | ||||||
0x06 | 写单个寄存器 | 示例:将数据0x0003写入寄存器单元0x0002 | ||||||||||||||
请求: | 设备号 | 功能码 | 寄存器起始地址 | 数据 | CRC校验 | |||||||||||
id | 06 | 00 | 01 | 00 | 03 | crcl | crch | |||||||||
响应: | 设备号 | 功能码 | 寄存器起始地址 | 数据 | CRC校验 | |||||||||||
id | 06 | 00 | 01 | 00 | 03 | crcl | crch | |||||||||
0x10 | 写多个寄存器 | 示例:将数据0x000A和0x0102写入从0x0002开始的两个寄存器单元 | ||||||||||||||
请求: | 设备号 | 功能码 | 寄存器起始地址 | 寄存器单元长度 | 字节数 | 数据 | CRC校验 | |||||||||
id | 10 | 00 | 01 | 00 | 02 | 04 | 00 | 0A | 01 | 02 | crcl | crch | ||||
响应: | 设备号 | 功能码 | 寄存器起始地址 | 寄存器单元长度 | CRC校验 | |||||||||||
id | 10 | 00 | 01 | 00 | 02 | crcl | crch | |||||||||
输入寄存器 Input Register(30001 - 39999) 16位 只读 |
0x04 | 读输入寄存器 | 示例:读取输入寄存器0x0009单元的值,现场数据为0x000A | |||||||||||||
请求: | 设备号 | 功能码 | 寄存器起始地址 | 寄存器单元长度 | CRC校验 | |||||||||||
id | 04 | 00 | 08 | 00 | 01 | crcl | crch | |||||||||
响应: | 设备号 | 功能码 | 字节数 | 数据 | CRC校验 | |||||||||||
id | 04 | 02 | 00 | 0A | crcl | crch | ||||||||||
有人扩展指令(本扩展指令非Modbus RTU标准,仅适用于设备与有人云网络通讯的规则) | ||||||||||||||||
为什么要做扩展指令 | 由于Modbus RTU协议适用于半双工的总线协议,只能一问一答,服务器做主机,接入设备做从机,可以实现主机主动采集和控制。 但由于网络通讯考虑流量、服务器并发量、网络延迟等原因,无法实现类似在总线中毫秒级的轮询读取,而网络通讯属于全双工,能够同时双向对话,故扩展指令提出支持从机状态主动上报的规则。 |
|||||||||||||||
应用场景1 从机主动上报状态 |
如Modbus协议的环境控制器,服务器做主机10分钟轮询采集,但若前端人工主动控制,服务器必须等到下个轮询才能得知状态变化。 利用扩展指令可实现人工主动控制,从机主动上报当前的状态。 注:本协议仅适用于使用有人网络模块自主开发的产品,若在RS-485总线中使用,会造成总线混乱。 |
|||||||||||||||
应用场景2 低功耗通讯上报格式 |
如NB-IoT、Lora这类低功耗通讯方式,低功耗模式仅支持主动向服务器上报,上报后断电断网休眠,此时服务器无法做主机主动采集数据。 利用扩展指令格式主动上报数据解决上述问题,服务器按照Modbus协议解析,完成后面的数据存储、报警、推送等功能。 补充:NB-IoT在高功耗模式下也可支持云端主动下发查询指令。 |
|||||||||||||||
寄存器单元(十进制) | 功能码 | 作用 | 请求及响应格式 | |||||||||||||
线圈寄存器 CoilStatus (00001 - 09999) 1位 读写 |
0x45 | 上报多个线圈 | 示例:从0x0014开始写入10个状态值,数据内容为2个字节:十六进制CD 01(二进制 1100 1101 0000 0001) | |||||||||||||
(格式与写多个线圈相同) | 请求: | 设备号 | 功能码 | 寄存器起始地址 | 寄存器单元长度 | 字节数 | 数据 | CRC校验 | ||||||||
id | 45 | 00 | 13 | 00 | 0A | 02 | CD | 01 | crcl | crch | ||||||
响应: | 设备号 | 功能码 | 寄存器起始地址 | 寄存器单元长度 | CRC校验 | |||||||||||
id | 45 | 00 | 13 | 00 | 0A | crcl | crch | |||||||||
离散寄存器 InputStatus(10001 - 19999) 1位 只读 |
0x42 | 上报多个离散寄存器 | (格式与写多个线圈相同) | |||||||||||||
保持寄存器 Holding Register(40001 - 49999) 16位 读写 |
0x46 | 上报多个保持寄存器 | 示例:将数据0x000A和0x0102写入从0x0002开始的两个寄存器单元 | |||||||||||||
(格式与写多个保持寄存器相同) | 请求: | 设备号 | 功能码 | 寄存器起始地址 | 寄存器单元长度 | 字节数 | 数据 | CRC校验 | ||||||||
id | 46 | 00 | 01 | 00 | 02 | 04 | 00 | 0A | 01 | 02 | crcl | crch | ||||
响应: | 设备号 | 功能码 | 寄存器起始地址 | 寄存器单元长度 | CRC校验 | |||||||||||
id | 46 | 00 | 01 | 00 | 02 | crcl | crch | |||||||||
(暂不支持) 输入寄存器 Input Register(30001 - 39999) 16位 只读 |
(暂不支持) 0x44 |
(暂不支持) 上报多个输入寄存器 |
(暂不支持,格式与写多个保持寄存器相同) | |||||||||||||
注意和补充 | ||||||||||||||||
协议解释: 1、数据、地址、长度等默认大端在前,但CRC校验是小端在前(低字节在前)crcl crch; 2、有人扩展协议仅适用于设备与透传云的网络通讯层; |
||||||||||||||||