0x01 初识ModBus
Modbus串行通信协议是一种Modicon公司(现施耐德电气)于1979年使用可编程逻辑控制器(PLC)通信发表。Modbus该协议已成为工业通信协议的行业标准,是工业电子设备之间常用的连接方式。
Modbus协议可以成为工业领域应用最广泛的协议和行业标准,具有以下特点 :
- 免费:这是最大的前提,任何产品都是一样的,只有免费才能获得早期最大的使用。
- 简单:Modbus协议帧格式简单紧凑,用户易于理解,制造商易于集成。
- 接口:Modbus协议只是一种规定,属于应用层的协议,不仅可以应用于串口(485/232/422),还可以在以太网、光纤、蓝牙传输。
0x02 ModBus报文分析
地址码 | 功能码 | 发送数据 | CRC校验码 |
---|---|---|---|
1byte | 1byte | n byte | 2byte |
地址码为通讯传送的第一个字节。这个字节表明由用户设定地址码的从机将接收由主机发送来的信息。并且每个从机都有具有唯一的地址码,并且响应回送均以各自的地址码开始。主机发送的地址码表明将发送到的从机地址,而从机发送的地址码表明回送的从机地址。地址码为0时,为广播地址,所有从机均能识别,从站不做应答。
通信传输的第二个字节。ModBus通讯规约定义功能码为1到127。作为主机请求发送,通过功能码告诉从机执行什么动作。作为从机响应,如果从机发送的功能代码最高为1(即功能代码大于127),则表示从机没有响应操作或发送错误。如果从机发送的功能代码与从主机发送的功能代码相同,则表示从机已响应主机操作。比如功能码:0000003(03)H),如果机器正常执行,返回相同的功能代码,如果异常,返回1万3(83H)。
: 数据区是根据不同的功能码而不同。数据区可以是实际数值、设置点、主机发送给从机或从机发送给主机的地址。例如,功能码告诉从机读取寄存器的值,则数据区必需包含要读取寄存器的起始地址及读取长度。对于不同的从机,地址和数据信息都不相同。
同TCP/IP 的CRC同样,验证是为了确保数据传输没有错误而设置的。计算和验证的内容包括除验证位置事故外的所有内容,即地址代码、功能代码和数据。
0x03 ModBus常用功能码
了解Modbus常用功能码是必要的,只有了解相关功能码,才能深入分析Modbus协议的相关操作和具体功能。
功能码 | 描述 | PLC地址范围 | 寄存器地址范围 | 操作单位 | 操作数量 |
---|---|---|---|---|---|
0x01 | 读取线圈寄存器 | 00001-99999 | 0x0000-0xFFFF | 按bit操作 | 1或n |
0x02 | 读离散输入寄存器 | 10001-19999 | 0x0000-0xFFFF | 按bit操作 | 1或n |
0x03 | 读保持寄存器 | 40001-49999 | 0x0000-0xFFFF | 按byte操作 | 1或n |
0x04 | 读取输入寄存器 | 30001-39999 | 0x0000-0xFFFF | 按byte操作 | 1或n |
0x05 | 写一个线圈寄存器 | 00001-99999 | 0x0000-0xFFFF | 按bit操作 | 1 |
0x06 | 写单个寄存器 | 40001-49999 | 0x0000-0xFFFF | 按byte操作 | 1 |
0x0F | 写多个线圈寄存器 | 00001-99999 | 0x0000-0xFFFF | 按bit操作 | 1 |
0x10 | 写多个保持寄存器 | 40001-49999 | 0x0000-0xFFFF | 按byte操作 | 1 |
0x04 Modbus寄存器解读
从以上功能码可以看出,有线圈寄存器、离散输入寄存器、维护寄存器和输入寄存器四种相关寄存器。
事实上,它可以类比为开关量(继电器状态)bit对应信号的开关状态。byte可同时控制8路信号。例如,控制外部8路io的高低。 线圈寄存器支持阅读和写作,写在功能码中分为写单个线圈寄存器和写多个线圈寄存器。对应上述功能码为:0x01 0x05 0x0f 。
离散输入寄存器相当于线圈寄存器的只读模式,它也是每个bit表示一个开关量,他的开关量只能读取输入的开关信号,不能写。例如,我读取外部按钮或松开。所以功能代码也很简单 0x02 。
寄存器的单位不再是bit而是两个byte,也就是说,它可以存储特定的数据量,并且可以读写。一般来说,相应的参数设置,如我设置的时间、月份和日期,不仅可以写作,还可以读取当前的时间。写作也分为单个写作和多个写作对应的三个:0x03 0x06 0x10 。
和保持寄存器类似,但是也是只支持读而不能写,一般是读取各种实时数据。一个寄存器也是占据两个byte的空间。 对应的功能码是:0x04。
0x05 Modbus 协议举例分析
主机请求: 01 03 00 00 00 01 84 0A
从机回复: 01 03 02 12 34 B5 33
相关解析:
#主机请求数据解析
01:PLC地址
03:功能码,查询保持寄存器
00 00:代表查询的寄存器的起始地址
00 01:代表查询的寄存器的结束地址
84 0A:循环冗余校验码
#从机回复数据解析
01:PLC地址
03:功能码,与主机请求相同,说明执行成功
02:代表后面寄存器的数据的字节数,一个寄存器有两个字节,所以这里的字节数肯定是查询的寄存器个数的2倍
12 34:寄存器的值
B5 33: 循环冗余校验码
主机请求: 01 06 00 00 00 01 48 0A
从机回复: 01 06 00 00 00 01 48 0A
相关解析:
# 主机请求数据解析
01:PLC地址
06:功能码,单个保持寄存器写入
00 00:要被写入发寄存器的地址
00 01:被写入的内容,也就是在寄存器00 00的位置写入数据 00 01
48 0A:循环冗余校验码
#从机回复
01:PLC地址
06:响应功能码,与请求中的相同,说明执行成功
00 00:被写入的地址
00 01:被写入的数据
48 0A:校验码
主机请求: 01 10 00 00 00 02 04 11 22 33 44 42 5A
从机回复: 01 10 00 00 00 02 41 C8
相关解析:
# 主机请求解析
01:PLC地址
10:功能码,多个保持寄存器写入
00 00:被写入的寄存器的起始地址
00 02:代表被修改的寄存器的数量
04:代表别修改的总字节数
11 22 33 44:将要修改的值
42 5A:校验码
#从机回复数据解析:
01:PLC地址
10:功能码
00 00:寄存器中被写入的地址
00 02:说明被修改的寄存器数量
41 C8:校验码
0x06 参考内容
- https://blog.csdn.net/CAI____NIAO/article/details/124344164
- https://xw.qq.com/cmsid/20220328A0872C00
- https://blog.csdn.net/qq_36958104/article/details/124193794
- https://www.163.com/dy/article/G5P36B0R0538S33I.html