MODBUS_RTU 通信协议详解
MODBUS_RTU 该协议是一种基于串行链路(RS232 或 RS485)的开放式通信协议,它使用芯片的串行端口发送和接收数据消息。
一、传输模式
传输模式是指信息帧内一系列独立的数据结构以及用于传输数据的有限规则。MODBUS-RTU协议在Modbus总线上以RTU模式进行通信。消息中的每个8位字节被分成两个4位十六进制字符。每条消息必须连续传输。
编码系统
- 8 位二进制数,十六进制数 0~9,A~F
- 消息中的每个 8 位字段由两个十六进制字符组成。
每字节位数
- 1起始位
- 8 位数据,最低有效位先发送。
- 1 位奇偶校验位,如果没有奇偶校验位则为 0
- 1 个停止位,2 个校验位(无校验)
错误检测域
- CRC(循环冗余校验)
二、 协议
当数据帧到达终端设备时,它通过一个简单的“端口”进入目标设备。设备移除数据帧的“信封”(帧头),读取数据,如果没有错误,则执行数据请求的任务。然后,它将生成的数据添加到获取的“信封”中,并将数据帧返回给发送方。返回的响应数据包含以下内容:终端从设备的地址(Address)、执行的命令(Function)、由执行的命令生成的请求数据(Data)以及校验码(Check)。任何错误都不会返回成功响应。

1)信息框架

Modbus 信息帧的最大允许长度为 256 字节,即 N 的范围大于等于零且小于等于 252。
2)地址栏
消息帧地址字段(消息地址)位于帧的开头,由 8 位组成。有效的从设备地址范围为 0 到 247(十进制)。每个从设备的寻址范围为 1 到 247。主设备将从设备的地址放入信息帧的地址区,并向从设备发送寻址信息。当从设备响应时,它会将自己的地址放入响应消息的地址区,以便主设备能够识别已响应的从设备的地址。
地址 0 是广播地址,所有从站都能识别。在高级网络中使用 Modbus 协议时,不允许使用广播或其他替代方式。

3)函数域
该信息帧的功能字段代码告诉目标终端要执行什么功能。有效代码范围为十进制 1 到 225。有些代码适用于所有控制器,有些代码适用于特定控制器,还有一些代码保留供将来使用。
当主控端向从控端发送信息时,功能码会指示从控端要执行的操作,例如读取一组离散线圈的开/关状态或输入信号,读取一组寄存器的数据,读取从控端的诊断状态,写入线圈(或寄存器),允许从控端下载、记录和确认程序等。
当从设备响应主设备时,其功能码可能指示从设备响应正常,也可能指示发生错误(即未正常响应)。如果响应正常,从设备直接返回原始功能码;如果响应异常,从设备返回一个与原始功能码等效,但最高有效位设置为“1”的功能码。
例如,当主设备请求从设备读取一组保持寄存器时,发送信息的功能码为 0000 0011(十六进制 03)。如果从设备正确接收到请求的操作信息,则返回相同的功能码作为正常响应;如果接收错误,则返回异常响应信息:1000 0011(十六进制 83)。从设备会修改功能码,并在响应消息的数据区添加一个特殊代码,以告知主设备错误类型和异常响应的原因。主设备的应用程序负责处理异常响应。典型的处理流程是,主设备将测试和诊断信息发送给从设备,并通知操作员。
下表列出了所有设备常用的功能代码、其含义及其初始功能。
| 代码 | 姓名 | 行动 |
| 01 | 读取线圈状态 | 获取一组逻辑线圈的当前状态(开/关) |
| 02 | 读取输入状态 | 获取一组开关输入(开/关)的当前状态 |
| 03 | 阅读持仓登记册 | 从一个或多个保持寄存器中检索当前二进制值 |
| 04 | 读取输入寄存器 | 从一个或多个输入寄存器中检索当前二进制值 |
| 05 | 强制单线圈 | 强制逻辑线圈处于开/关状态 |
| 06 | 预设单寄存器 | 将特定的二进制值放入单个寄存器中 |
| 07 | 读取异常状态 | 获取8个内部线圈的开关状态 |
| 15 | 强制多线圈 | 强制开启和关闭一系列连续逻辑线圈 |
| 16 | 预设多个寄存器 | 将一系列特定的二进制值放入一系列多个寄存器中 |
| 17 | 报告从属 ID | 主设备可以判断被寻址从设备的类型以及从设备的运行指示灯状态。 |
4)数据域
数据字段包含终端执行特定功能所需的数据,或终端响应查询而收集的数据。这些数据的内容可以是数值、引用地址或限值。
例如,功能字段代码指示终端读取某个寄存器,而数据字段则指示从哪个寄存器开始读取以及读取多少数据。嵌入的地址和数据会根据从设备的类型和响应能力而变化。如果没有发生错误,从设备发给主机的响应消息将包含请求的数据;如果发生错误,数据中将包含异常代码,以便主机判断并采取下一步行动。数据区的长度可以为“零”,以表示某种特定类型的信息。
5)错误检查字段
该域允许主机和终端在传输过程中检查错误。有时,由于电噪声和其他干扰,数据在从一台设备传输到另一台设备的过程中可能会发生变化。错误检查可以确保主机或终端不会响应在传输过程中发生变化的数据,从而提高系统的安全性和效率。错误检查采用 16 位循环冗余校验 (CRC) 方法。
错误检测字段为 16 位(由两个 8 位字符实现)。错误检测字段的内容是通过对消息内容应用循环冗余检测方法生成的。CRC 字段附加在消息末尾,低字节在前,高字节在后,因此 CRC 的高字节是已发送消息的最后一个字节。
6)字符的连续传输
当消息通过标准 Modbus 系列网络传输时,每个字符或字节都按从左到右的顺序发送:最低有效位 (LSB) … 最高有效位 (MSB)。
比特序列为:
存在均等性

没有平价

三、错误检测
1)奇偶性
用户可以配置控制器采用奇校验、偶校验还是无校验。这将决定每个字符中奇偶校验位的设置方式。
如果指定了奇校验或偶校验,则每个字符的数据位数中会包含“1”的位数(ASCII 模式下为 7 位数据,RTU 模式下为 8 位数据)。例如,RTU 字符帧包含以下 8 位数据:1 1 0 1 0 1,其中“1”的总数为 4。如果使用偶校验,则帧的校验位为 0,因此“1”的总数仍然是 4。如果使用奇校验,则帧的校验位为 1,因此“1”的总数为 5。如果未指定校验位,则传输过程中不会进行校验和检测。
2)结直肠癌检测
CRC校验法用于计算错误校验码,它会检查所有传输的数据。CRC校验法忽略了对消息中单个字符数据的奇偶校验。
循环冗余校验 (CRC) 字段占用两个字节,包含一个 16 位二进制值。CRC 值由发送设备计算并附加到数据帧中。接收设备在接收到数据后重新计算 CRC 值,并将其与接收到的 CRC 字段中的值进行比较。如果两个值不相等,则表示发生了错误。
CRC校验首先将寄存器的全部16位置为“1”,然后将两个相邻的8位字节的数据放入当前寄存器。每个字符仅使用8位数据生成CRC校验值,起始位、停止位和奇偶校验位不计入CRC校验值。
生成 CRC 时,每个 8 位字节都与寄存器的内容进行异或运算,并将结果向低位移动,高位则补零。最低有效位 (LSB) 被移出并检测。如果 LSB 为 1,则将寄存器与预设的固定值进行异或运算。如果 LSB 为 0,则不进行任何操作。
上述过程重复进行,直至完成 8 次移位操作。在移位最后一位(第 8 位)后,将下一个 8 位字节与寄存器的当前值进行异或运算。重复执行其余 8 次移位异或运算。当数据帧中的所有字节都处理完毕后,生成的最终值即为 CRC 值。
生成 CRC 的过程如下:
① 将一个 16 位寄存器预设为 0FFFFH(全 1),称为 CRC 寄存器。
② 将数据帧中的第一个 8 位字节与 CRC 寄存器中的低字节进行异或运算,并将结果存储回 CRC 寄存器。
③ 将 CRC 寄存器向右移动一位,最高位填充 0,最低位移出进行检测。
④ 如果最低位为 0:重复步骤 3(下一次移位)。如果最低有效位为 1:将 CRC 寄存器与预设固定值 (0 A001H) 进行异或运算。
⑤ 重复步骤 3 和 4,直到移位 8 次。这样,就处理完了完整的 8 位数据。
⑥ 重复步骤 2 至 5 处理下一个八位字节,直到所有字节都被处理完毕。
⑦ 最终的 CRC 寄存器值即为 CRC 值。
CRC 值附加到信息后,低位在前,高位在后。










