问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

MODBUS RTU协议原理及功能码解析

创作时间:
作者:
@小白创作中心

MODBUS RTU协议原理及功能码解析

引用
CSDN
1.
https://m.blog.csdn.net/xianshengsun/article/details/145207994

第一部分 MODBUS RTU协议原理

1.1 简介

MODBUS是OSI模型第七层上的应用层报文传输协议。它是一个请求/应答协议,并规定了相关的功能码。MODBUS功能码是MODBUS请求应答PDU的元素。(PDU:协议数据单元)

MODBUS通信栈:

MODBUS网络体系结构示例:

MODBUS协议允许在各种网络体系结构内进行简单通信。每种设备(PLC、HMI、控制面板、驱动程序、动作控制、输入/输出设备)都能使用MODBUS协议来启动远程操作。在基于串行链路和以太TCP/IP网络的MODBUS上可以进行相同通信。

MODBUS帧:

主/从站通信时序图:

1.2 RTU传输模式

有两种串行传输模式被定义:RTU模式和ASCII模式。所有设备必须实现RTU模式。

当设备使用RTU (Remote Terminal Unit)模式在MODBUS串行链路通信,报文中每个8位字节包含两个4位十六进制字符。这种模式的主要优点是较高的数据密度,在相同的波特率下比ASCII模式有更高的吞吐率。每个报文必须以连续的字符流传送。

RTU模式每个字节(11位)的格式为:

  • 编码系统:8位二进制
  • 报文中每个8位字节包含两个4位十六进制字符(0-9,A-F)
  • Bits per Byte:1起始位
  • 8数据位,首先发送最低有效位
  • 1位作为奇偶校验
  • 1停止位
  • 默认校验位模式必须为偶校验

RTU模式位序列:

RTU模式位序列(无校验的特殊情况):

RTU帧描述:

CRC(循环冗余校验)

MODBUS RTU帧最大256个字节。

1.3 MODBUS报文帧

由发送设备将MODBUS报文构造为带有已知起始和结束标记的帧。这使设备可以在报文的开始接收新帧,并且知道何时报文结束。不完整的报文必须能够被检测到而错误标志必须作为结果被设置。在RTU模式,报文帧由时长至少为3.5个字符时间的空闲间隔区分。


整个报文帧必须以连续的字符流发送。

如果两个字符之间的空闲间隔大于1.5个字符时间,则报文帧被认为不完整应该被接收节点丢弃。

RTU传输状态图:

上面状态图的一些解释:

  • 从"初始"态到“空闲”态转换需要t3.5定时超时:这保证帧间延迟
  • “空闲”态是没有发送和接收报文要处理的正常状态。
  • 在RTU模式,当没有活动的传输的时间间隔达3.5个字符长时,通信链路被认为在“空闲”态。
  • 当链路空闲时,在链路上检测到的任何传输的字符被识别为帧起始。链路变为"活动"状态。然后,当链路上没有字符传输的时间间个达到t3.5后,被识别为帧结束。
  • 检测到帧结束后,完成CRC计算和检验。然后,分析地址域以确定帧是否发往此设备,如果不是,则丢弃此帧。为了减少接收处理时间,地址域可以在一接到就分析,而不需要等到整个帧结束。这样,CRC计算只需要在帧寻址到该节点(包括广播帧)时进行。

1.4 CRC校验

在RTU模式包含一个对全部报文内容执行的,基于循环冗余校验(CRC - Cyclical Redundancy Checking)算法的错误检验域。CRC域检验整个报文的内容。不管报文有无奇偶校验,均执行此检验。

CRC包含由两个8位字节组成的一个16位值。

CRC域作为报文的最后的域附加在报文之后。计算后,首先附加低字节,然后是高字节。CRC高字节为报文发送的最后一个子节。

附加在报文后面的CRC的值由发送设备计算。接收设备在接收报文时重新计算CRC的值,并将计算结果于实际接收到的CRC值相比较。如果两个值不相等,则为错误。

CRC的计算,开始对一个16位寄存器预装全1。然后将报文中的连续的8位子节对其进行后续的计算。只有字符中的8个数据位参与生成CRC的运算,起始位,停止位和校验位不参与CRC计算。

CRC的生成过程中,每个8位字符与寄存器中的值异或。然后结果向最低有效位(LSB)方向移动(Shift)1位,而最高有效位(MSB)位置充零。然后提取并检查LSB:如果LSB为1,则寄存器中的值与一个固定的预置值异或;如果LSB为0,则不进行异或操作。

这个过程将重复直到执行完8次移位。完成最后一次(第8次)移位及相关操作后,下一个8位字节与寄存器的当前值异或,然后又同上面描述过的一样重复8次。当所有报文中子节都运算之后得到的寄存器中的最终值,就是CRC。

第二部分 MODBUS RTU模式下功能码解析

2.1 Modbus-RTU协议简介

帧结构 = 地址(设备ID) + 功能码 + 数据 + 校验

地址:占1个字节,范围0255,有效范围1247,其他特殊用途 如255为广播地址。

功能码:占1个字节。功能码是MODBUS协议定的。是MODBUS编程两个重要的概念之一(另一个是字符间隔1.5T—判断帧是否完整,字符间隔大于3.5T视为帧结束。),不同的功能码,后面数据格式也不同,从机返回的帧格式也不同。

数据:见后面示例。

校验:CRC校验值。

备注:读线圈返回数据时,1个字节表示8个线圈状态。

比如线圈地址0001-0008这一部分的状态ON-ON-ON-OFF-ON-ON-OFF-OFF,等价11101100。二进制表示为00110111,16进制为0x37.

2.2 部分功能码名词解释

Modbus常用功能码:

线圈寄存器:实际上就可以类比为开关量(继电器状态),每一个bit对应一个信号的开关状态。所以一个byte就可以同时控制8路的信号。比如控制外部8路io的高低。 线圈寄存器支持读也支持写,写在功能码里面又分为写单个线圈寄存器和写多个线圈寄存器。对应上面的功能码也就是:0x01 0x05 0x0f

离散输入寄存器:如果线圈寄存器理解了这个自然也明白了。离散输入寄存器就相当于线圈寄存器的只读模式,他也是每个bit表示一个开关量,而他的开关量只能读取输入的开关信号,是不能够写的。比如我读取外部按键的按下还是松开。所以功能码也简单就一个读的 0x02

保持寄存器:这个寄存器的单位不再是bit而是两个byte,也就是可以存放具体的数据量的,并且是可读写的。一般对应参数设置,比如我我设置时间年月日,不但可以写也可以读出来现在的时间。写也分为单个写和多个写,所以功能码有对应的三个:0x03 0x06 0x10

输入寄存器:这个和保持寄存器类似,但是也是只支持读而不能写,一般是读取各种实时数据。一个寄存器也是占据两个byte的空间。类比我我通过读取输入寄存器获取现在的AD采集值。对应的功能码也就一个 0x04。

(名词解释来源:https://blog.csdn.net/lingshi75/article/details/105991450/)

2.3 部分功能码解析

01功能码 –读线圈状态

主机发送:01 01 00 01 00 08 6C 0C

从机回复: 01 01 01 2F 10 54

主机解析:01 地址(设备ID);

01 功能码;

00 01 代表查询的起始线圈地址,即从0001线圈开始查询。

00 08 查询线圈数量。

6C 0C 循环冗余校验。

从机解析:01 地址(设备ID);

01 功能码;

01 代表后面数据的字节数。

2F 读取以0001线圈开始的8个线圈的状态。0x2F二进制为00101111,对应状态为1111 0100

10 54 循环冗余校验。

02功能码 –-读离散输入寄存器

功能:读离散输入寄存器,位操作,可读单个或多个,类似功能码0X01

03功能码 –-读保持寄存器的值

主机发送:01 03 00 01 00 01 D5 CA

从机回复: 01 03 02 00 01 79 84

主机解析:01 地址(设备ID);

03 功能码;

00 01 代表查询的起始寄存器地址,即从0001寄存器开始查询。

00 01 查询寄存器数量。

D5 CA 循环冗余校验。

从机解析:01 地址(设备ID);

03 功能码;

02 代表后面数据的字节数。

00 01 查询0001寄存器的值。

79 84 循环冗余校验。

04 功能码 –-读输入寄存器

功能:读输入寄存器,字节操作,可读单个或多个,类似功能码0X03

05 功能码 –-写单个线圈

功能:对单个线圈进行写操作,位操作,只能写一个。写入0xFF00表示将线圈置为ON,写入0x0000表示将线圈置为OFF,其它值无效;

主机发送数据:从站地址+功能码+寄存器起始地址+数据值+校验码

从站应答数据:从站地址+功能码+寄存器地址+写入值+校验码

06 功能码 –-写单个保持寄存器

主机发送:01 06 00 02 00 01 E9 CA

从机回复: 01 06 00 02 00 01 E9 CA

主机解析:01 地址(设备ID);

06 功能码;

00 02 代表待写入的起始寄存器地址,即从0002寄存器开始写数据。

00 01 写入的寄存器的值。即给0002寄存器写入0001

E9 CA 循环冗余校验。

从机解析:01 地址(设备ID);

06 功能码;

02 代表后面数据的字节数。

00 01 查询0001寄存器的值。

E9 CA 循环冗余校验。

15 功能码 –-写多个线圈状态

主机发送:01 0F 00 01 00 07 01 6B B2 B9

从机回复: 01 0F 00 01 00 07 45 C9

主机解析:01 地址(设备ID);

0F 功能码;

00 01 代表待写入的起始线圈地址,即从0001线圈开始写数据。

00 07 待写入的线圈的数量。

01 后面写入数据的字节数。

6B写入寄存器的值,即11010110。二进制01101011

B2 B9 循环冗余校验。

从机解析:01 地址(设备ID);

0F 功能码;

00 01 代表待写入的起始线圈地址,即从0001线圈开始写数据。

00 07 待写入的线圈的数量。

45 C9 循环冗余校验。

16功能码 -- 写多个保持寄存器

主机发送:01 10 00 04 00 03 06 00 01 00 00 00 01 5B 55

从机回复: 01 10 00 04 00 03 C1 C9

主机解析:01 地址(设备ID);

10 功能码;

00 04 代表待写入的起始寄存器地址,即从0004寄存器开始写数据。

00 03 待写入的寄存器的数量。

06 后面写入数据的字节数。

0001,0000,0001写入寄存器的值。即给0004,0005,0006寄存器分别写入0001,0000,0001

5B 55 循环冗余校验。

从机解析:01 地址(设备ID);

10 功能码;

00 04 代表待写入的起始寄存器地址,即从0004寄存器开始写数据。

00 03 待写入的的寄存器的数量。

C1 C9 循环冗余校验。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号