Bootstrap

Modbus 协议基本原理

1、 Modbus简介

Modbus 是由 Modicon(现为施耐德电气公司的一个品牌)在 1979 年发明的,是全球第一个真正
用于工业现场的总线协议。

ModBus 网络是一个工业通信系统,由带智能终端的可编程序控制器和计算机通过公用线路或局部专
用线路连接而成。其系统结构既包括硬件、亦包括软件。它可应用于各种数据采集和过程监控。

为更好地普及和推动 Modbus 在基于以太网上的分布式应用,目前施耐德公司已将 Modbus 协议的
所有权移交给 IDA(Interface for Distributed Automation,分布式自动化接口)组织,并成立了
Modbus-IDA 组织,为 Modbus 今后的发展奠定了基础。

在中国,Modbus 已经成为国家标准,并有专业的规范文档,感兴趣的可以去查阅相关的文件,详情如下:
标准编号为:GB/T19582-2008
文件名称:《基于 Modbus 协议的工业自动化网络规范》
主要有三部分的内容,分别如下:
《GB/T 19582.1-2008 第 1 部分:Modbus 应用协议》
《GB/T 19582.2-2008 第 2 部分:Modbus 协议在串行链路上的实现指南》
《GB/T 19582.3-2008 第 3 部分: Modbus 协议在 TCP/IP 上的实现指南》

2、Modbus协议概述

Modbus是一个主-从模式的通信协议,属于数据链路层上的协议,协议本身不涉及具体的硬件要求。
常见的应用Modbus协议的物理接口有RS-485、RS232、USART等的通信链路中。

Modbus协议中,一个时刻内只允许有一个主机连接于总线,多个从机连接于总线上,通信都是只能由主机发起,从机进行响应。不能从机主动发起通信。

3、Modbus 主从机通信模式

主机和从机之间的通信,可以用两种模式进行:广播通知模式、单播点对点模式。

3.1、单播点对点模式

主机按照从机的明确地址访问相应的从机,从机接到来自主机的请求并处理完请求后,从机会向主机返回一个应答,完成一个通信。

在这种模式,一个 Modbus 事务处理包含 2 个报文:一个来自主机的请求,一个来自从机的应答。

在总线上,每个从机都必须有唯一的从机地址 (1 到 247),这样才能区别于其它节点被独立的寻址。

3.2、广播通知模式

主机向所总线通过广播指令发送请求,所有的从机都要接收来自主机的广播信息。

对于主机广播的请求,从机是没有应答返回的。所有的从机必须要接受主机的广播模写功能。

注意:地址 0 是专门用于主机向各个从机广播数据的。

4、Modbus 地址规则

Modbus 寻址空间有 256 个不同地址。如下图所示:
在这里插入图片描述

地址 0 为广播地址。所有的从机必须识别广播地址。

Modbus 主机本身是没有地址的,只有从机必须要有一个地址。 该地址必须在 Modbus 串行总线上唯一。

248~255作为预留使用的地址。

5、Modbus 的帧格式

Modbus的帧格式按照选择的模式不同帧格式也是有所区别的。

5.1、RTU模式

RTU 模式下的帧格式如下图:
在这里插入图片描述

Modbus RTU 帧总长度最大为 256 字节。

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

8–位二进制,报文中每个 8 位字节含有两个 4 位十六进制字符(0–9, A–F)

每字节的 bit 流:
1 起始位
8 数据位, 首先发送最低有效位
1 位作为奇偶校验
1 停止位

偶校验是要求的, 其它模式 ( 奇校验, 无校验 ) 也可以使用。 为了保证与其它产品的最大兼容性,
同时支持无校验模式是建议的。默认校验模式模式 必须为偶校验。

注 : 使用无校验要求 2 个停止位。

RTU时,每个字符或字节均由此顺序发送(从左到右):
最低有效位 (LSB) . . . 最高有效位 (MSB)
在这里插入图片描述
在这里插入图片描述

5.1.1、RTU模式下的帧通信

由发送设备将 Modbus 报文构造为带有已知起始和结束标记的帧。这使设备可以在报文的开始接收
新帧,并且知道何时报文结束。

不完整的报文必须能够被检测到而错误标志必须作为结果被设置。

在 RTU 模式,报文帧由时长至少为 3.5 个字符时间的空闲间隔区分。
在这里插入图片描述

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

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

注意 : RTU 模式下接收数据时,由于 t1.5 和 t3.5 的时间隔要求的存在,一般在高通信速率下,会导致 CPU 负担加重。因此,在通信速率等于或低于 19200 bps 时,这两个定时必须严格遵守; 对于波特率大于 19200 bps 的情形,应该使用 2 个定时的固定值: 建议的字符间超时时间(t1.5)为 750µs, 帧间的超时时间 (t1.5) 为 1.750ms。

下图表示了对 RTU 传输模式状态图的描述。 “主节点” 和 “子节点” 的不同角度均在相同的图中表
示:
在这里插入图片描述

上面状态图的一些解释:

1)从 “初始” 态到 “空闲” 态转换需要 t3.5 定时超时: 这保证帧间延迟

2)“空闲” 态是没有发送和接收报文要处理的正常状态。

3)在 RTU 模式, 当没有活动的传输的时间间隔达 3.5 个字符长时,通信链路被认为在 “空闲” 态。

4)当链路空闲时, 在链路上检测到的任何传输的字符被识别为帧起始。 链路变为 “活动” 状态。 然后当链路上没有字符传输的时间间个达到 t3.5 后,被识别为帧结束。

5)检测到帧结束后,完成 CRC 计算和检验。然后,分析地址域以确定帧是否发往此设备,如果不是,则丢弃此帧。 为了减少接收处理时间,地址域可以在一接到就分析,而不需要等到整个帧结束。这样,CRC 计算只需要在帧寻址到该节点 (包括广播帧) 时进行。

5.1.2、RTU模式的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。

5.2、ASCII传输模式

当 Modbus 串行链路的设备被配置为使用 ASCII模式通信时,报文中的每个 8 位字节以两个 ASCII 字符发送。
一般在通信链路或者设备无法符合 RTU 模式的定时管理时使用该模式。
ASCII的帧格式如下:
在这里插入图片描述

比如 : 字节 0X5B 会被编码为两个字符 : 0x35 和 0x42 ( ASCII 编码 0x35 =“5”, 0x42 =“B” )。

注 : 由于一个子节需要两个字符,此模式比 RTU 效率低。

ASCII 模式每个字节 ( 10 位 ) 的格式为 :
十六进制,ASCII 字符 0-9, A-F。
1 起始位
7 数据位, 首先发送最低有效位
1 位作为奇偶校验
1 停止位

偶校验是要求的, 其它模式 ( 奇校验, 无校验 ) 也可以使用。 为了保证与其它产品的最大兼容性,
同时支持无校验模式是建议的。默认校验模式模式 必须为偶校验。

注 : 使用无校验要求 2 个停止位。

字符是如何串行传送的:
每个字符或字节均由此顺序发送(从左到右):
最低有效位 (LSB) . . . 最高有效位 (MSB)
在这里插入图片描述
在这里插入图片描述

5.2.1、ASCII的报文帧

在 ASCII 模式, 报文用特殊的字符区分帧起始和帧结束。一个报文必须以一个‘冒号’ ( : ) (ASCII
十六进制 3A )起始,以 ‘回车-换行’ (CR LF) 对 (ASCII 十六进制 0D 和 0A) 结束。

注 : LF 字符可以通过特定的 Modbus 应用命令 (参见 Modbus 应用协议规范) 改变。

对于所有的域,允许传送的字符为十六进制 0–9, A–F (ASCII 编码)。 设备连续的监视总线上的 ‘冒
号’ 字符。当收到这个字符后,每个设备解码后续的字符一直到帧结束。

报文中字符间的时间间隔可以达一秒。如果有更大的间隔,则接受设备认为发生了错误。

特别注意:每个字符子节需要用两个字符编码。因此,为了确保 ASCII 模式 和 RTU 模式在 Modbus 应用级兼容,ASCII 数据域最大数据长度为 (2x252) 是 RTU 数据域 (252) 的两倍。

必然的, Modbus ASCII 帧的最大尺寸为 513 个字符。

ASCII 报文帧的要求在下面的状态图中综合。 “主节点” 和 “子节点” 的不同角度均在相同的图中表
示:
在这里插入图片描述

上面状态图的一些解释:

1)“空闲” 态是没有发送和接收报文要处理的正常状态。

2)每次接收到 “:” 字符表示新的报文的开始。如果在一个报文的接收过程中收到该字符,则当前地报文被认为不完整并被丢弃。而一个新的接收缓冲区被重新分配。

3)检测到帧结束后,完成 LRC 计算和检验。然后,分析地址域以确定帧是否发往此设备,如果不是,则丢弃此帧。 为了减少接收处理时间,地址域可以在一接到就分析,而不需要等到整个帧结束。

5.2.2、ASCII的LRC校验

在 ASCII 模式,包含一个对全部报文内容执行的,基于纵向冗余校验 (LRC - Longitudinal
Redundancy Checking) 算法的错误检验域。LRC 域检验不包括起始“冒号”和结尾 CRLF 对的整个报
文的内容。不管报文有无奇偶校验,均执行此检验。

LRC 域为一个子节,包含一个 8 位二进制值。LRC 值由发送设备计算,然后将 LRC 附在报文后面。
接收设备在接收报文时重新计算 LRC 的值,并将计算结果于实际接收到的 LRC 值相比较。如果两个值不相等,则为错误。

LRC 的计算, 对报文中的所有的连续 8 位字节相加,忽略任何进位,然后求出其二进制补码。执行检
验针对不包括起始“冒号”和结尾 CRLF 对的整个 ASCII 报文域的内容。在 ASCII 模式,LRC 的结果
被 ASCII 编码为两个字节并放置于 ASCII 模式报文帧的结尾,CRLF 之前。

6、Modbus的异常码

MODBUS 事务处理的一般处理过程:
在这里插入图片描述

一旦服务器处理请求,使用合适的 MODBUS 服务器事务建立 MODBUS 响应。根据处理结果,可以建立两种类型响应:

1) 一个正确的 MODBUS 响应:响应功能码 = 请求功能码

2) 一个 MODBUS 异常响应

3)用来为客户机提供处理过程中与被发现的差错相关的信息

4)响应功能码 = 请求功能码 + 0x80

5)提供一个异常码来指示差错原因。

7、Modbus的功能码

7.1、功能码的类别

目前Modbus的功能中可以分为三类:公共功能码、用户定义功能码、保留功能码。
在这里插入图片描述

公共功能码:是已经被定义的功能码。

用户定义功能码:有两个可以由用户定义功能码。范围为: 65 至 72 和十进制 100 至 110。

保留功能码:特殊情况下使用的,并且对公共使用是无效的功能码。

7.2、公共功能码

Modbus中公共功能码的定义如下:
在这里插入图片描述

7.2.1、线圈操作功能码(bit位的操作)

在这里插入图片描述

比如我要读取线圈中的内容。从机地址为 11H,线圈寄存器的起始地址为 0013H,结束地址为 0037H。

需要查询总共 37 个线圈寄存器,主机发送的RTU帧如下:
在这里插入图片描述

从机响应的数据帧如下:
在这里插入图片描述

解析:
线圈 0013H 到线圈 001AH 的状态为 CDH,二进制值为 11001101,该字节的最高字节为线圈
001AH , 最 低 字 节 为 线 圈 0013H 。各线圈状态与数据内容每位相对应。1 代表 ON,0 代表 OFF。 线 圈 001AH 到 线 圈 0013H 的 状态分别为:
在这里插入图片描述

7.2.2、保持寄存器操作功能码

在这里插入图片描述

(1)写多个保持寄存器
写多个保持寄存器使用功能码10H。
比如:从机地址为 11H。保持寄存器的其实地址为 0001H,寄存器的结束地址为 0002H。总共访问 2个寄存器。保持寄存器 0001H 的内容为 000AH,保持寄存器 0002H 的内容为 0102H。

主机请求的RTU帧数据如下:
在这里插入图片描述
在这里插入图片描述

从机返回的响应为:
在这里插入图片描述

(2)读保持寄存器

读保持寄存器使用03H功能码。

比如:从机地址为 11H。保持寄存器的起始地址为 006BH,结束地址为 006DH。

主机发送的RTU请求帧如下:
在这里插入图片描述
在这里插入图片描述

从机的应答如下:
在这里插入图片描述

对嵌入式技术感兴趣的,欢迎关注微信公众号“嵌入式之入坑笔记”,一起学习讨论啊!
在这里插入图片描述

;