二、ModBus协议解析

在这里插入图片描述

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),则表明从机没有响应操作或发送出错,如果从机发送的功能码与从主机发送来的功能码一样,则表明从机已响应主机进行操作。例如:功能码:00000003(03H),如果从机正常执行,则返回相同功能功能码,如果异常则返回10000003(83H)。

数据区: 数据区是根据不同的功能码而不同。数据区可以是实际数值、设置点、主机发送给从机或从机发送给主机的地址。例如,功能码告诉从机读取寄存器的值,则数据区必需包含要读取寄存器的起始地址及读取长度。对于不同的从机,地址和数据信息都不相同。

CRC校验: 同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 协议举例分析

1、保持寄存器数据读取

主机请求: 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: 循环冗余校验码

2、单个保持寄存器写入

主机请求: 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:校验码

3、多个保持寄存器写入

主机请求: 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

猜你喜欢

转载自blog.csdn.net/qq_45590334/article/details/125220090