Modbus RTU
Modbus RTU(Remote Terminal Unit)是一种在工业环境中广泛使用的串行通信协议。它基于Modbus协议的一种实现,通过串行线(如RS-232或RS-485)进行通信,主要用于设备间的简单通信。由于其开放性、简单性和广泛的支持,Modbus RTU成为了工业通信中的事实标准之一。
基本概念
Modbus RTU帧结构:每个Modbus RTU消息帧以设备地址开始,后跟功能码、数据、以及一个循环冗余检查(CRC)校验码结束。设备地址标识了网络上的特定设备,功能码指定了要执行的操作(如读取数据、写入数据等),数据部分包含了指令或指令的回复,CRC校验码用于检测传输错误。
主站/从站模式:Modbus RTU采用主站/从站(或主从)模式。在任何给定的Modbus网络中,有一个设备充当主站,负责发起请求。其余设备作为从站,响应主站的请求。每个从站设备都有一个唯一的地址。
串行通信:Modbus RTU通过串行通信端口进行数据传输,典型的接口是RS-232或RS-485。RS-485尤其受到欢迎,因为它支持长距离通信和多设备网络。
帧结构
RTU 帧由从机地址、功能码、数据和 CRC 组成,完整帧最多 256 字节。RS485 是电气接口标准,不规定这里的功能码和寄存器含义。
| 字段 | 长度 | 说明 |
|---|---|---|
| 从机地址 | 1 字节 | 单播地址为 1~247;0 为广播地址,从机不返回响应 |
| 功能码 | 1 字节 | 指定读取或写入的数据类型 |
| 数据 | 按功能码变化 | 请求中可包含起始地址和数量,响应中可包含字节数与寄存器值 |
| CRC | 2 字节 | 对前面全部字节计算,低字节先发送 |
同一串行总线上由一个主站发起请求,不应让多个主站同时轮询。RTU 通过静默时间划分帧;串行规范规定帧间至少间隔 3.5 个字符时间,在波特率高于 19200 时推荐使用固定的 1.75 ms 帧间隔。实际还需给从机处理与链路传输留出时间。
功能码
Modbus RTU定义了一系列功能码,用于读取和写入数据,以及进行设备控制。这些功能码包括但不限于:
- 读取线圈状态(01):读取从站的一组数字输出(线圈)的状态。
- 读取输入状态(02):读取从站的一组数字输入的状态。
- 读取保持寄存器(03):读取从站的一组保持寄存器中的值,这些寄存器可以由主站读写。
- 读取输入寄存器(04):读取从站的一组输入寄存器中的值,这些寄存器只能由主站读取。
- 写单个线圈(05):写一个数字输出(线圈)的状态。
- 写单个寄存器(06):写单个保持寄存器的值。
通信流程
- 请求:主站发送一个请求给从站,请求中包括从站的地址、一个功能码、以及根据所请求操作的需要可能包含的数据。
- 处理:从站接收到请求后,解析功能码并执行相应的操作。
- 响应:从站处理完请求后,回送一个响应给主站。响应可能包含所请求的数据或执行操作的结果。
- 错误处理:如果请求不能被正确执行,从站会返回一个错误响应,其中包含错误码指示问题所在。
从机通常是传感器、执行器或 PLC 等现场设备。下文报文是用于解释编码规则的构造示例,CRC 已按文中的算法计算;不代表某个型号的实际寄存器定义。
常用从机类型
- 温度传感器:用于测量温度,通常会通过保持寄存器或输入寄存器提供测量值。
- 电机控制器:用于控制电机的启动、停止和速度调节,可能会使用线圈进行开/关控制和保持寄存器来设置参数。
- PLC:可编程逻辑控制器,用于自动化控制生产过程,可以通过Modbus RTU读写其输入/输出接口和参数设置。
- 变频器:用于调节电机的速度,通过读写保持寄存器来设置和读取运行参数。
功能码的请求与回复例子
读取保持寄存器(功能码03)
请求:从主站读取从站保持寄存器的值。例如,主站请求从一个PLC(设备地址为01)的保持寄存器开始,读取3个寄存器的值。
请求报文示例:
01 03 00 64 00 03 44 1401:从站地址。03:功能码,表示读取保持寄存器。00 64:起始寄存器地址(100)。00 03:要读取的寄存器数量(3个)。44 14:CRC校验码。
回复:从站回复所请求的保持寄存器的值。
回复报文示例:
01 03 06 00 0A 01 2B 00 0C C8 8501:从站地址。03:功能码。06:字节计数(读取3个寄存器,每个寄存器2字节,共6字节)。00 0A:第一个寄存器的值(10)。01 2B:第二个寄存器的值(299)。00 0C:第三个寄存器的值(12)。C8 85:CRC校验码。
写单个寄存器(功能码06)
请求:主站设置从站单个保持寄存器的值。例如,主站设置一个温度控制器(设备地址为02)的目标温度。
请求报文示例:
02 06 00 01 04 D2 5A A402:从站地址。06:功能码,表示写单个寄存器。00 01:寄存器地址(1)。04 D2:要写入的值(1234,假设这是一个温度值)。5A A4:CRC校验码。
回复:从站确认写入的寄存器地址和值。
回复报文示例:
02 06 00 01 04 D2 5A A4- 报文结构与请求相同,确认已正确写入值。
这些例子展示了Modbus RTU协议中请求与回复报文的结构和含义。通过这些例子,可以看到Modbus RTU协议在工业通信中的灵活性和实用性,允许主站与从站之间进行高效的数据交换。
通信设置
Modbus RTU通信设置包括波特率(例如9600或19200 bps)、数据位(通常是8位)、停止位(1或2位)、以及奇偶校验(无、奇校验或偶校验)。这些参数必须在通信设备间事先协商一致。
应用场景
Modbus RTU广泛应用于各种工业自动化系统,如PLC(可编程逻辑控制器)、温度控制器、变频器、传感器网络等。它使得不同制造商的设备能够通过标准化方式互相通信,极大地促进了工业设备的兼容性和互操作性。
实际接入可参考 RS485/Modbus 设备通过 DTU 透传接入,完成属性定义、寄存器配置和定时读取。需要将多个从机分别管理时,参考 Modbus 云网关。
寄存器地址、字节序和倍率
设备手册中的 40001 常用来标识第一个保持寄存器,其报文地址通常为 0;也有手册直接给出从 0 开始的偏移地址。应先确认手册采用哪种记法,不要对所有地址统一减一。功能码 03 和 04 对应不同的数据区,即使地址相同也不能混用。
单个寄存器为 16 位,协议中的寄存器值高字节先传输。32 位整数或浮点数需要两个寄存器,其跨寄存器排列由设备手册定义,不能从“支持 Modbus”推断。CRC 的低字节先传输与寄存器数值的字节序是两回事。
倍率同样由设备定义。例如手册规定温度单位为 0.1 ℃,原始值 253 才表示 25.3 ℃;不要给所有温度设备套用这个比例。有符号整数与无符号整数也应分别处理。
相关文档
- 在 Modbus 寄存器设置 中配置数据类型和字节序
- 使用 设备消息调试 核对原始报文与解析结果
CRC16 校验计算
Modbus RTU 使用初始值 0xFFFF,下面采用右移算法和反向多项式 0xA001。输入为不含 CRC 的报文字节,不能直接对十六进制文本的字符编码计算。
function modbusCRC16(bytes) {
let crc = 0xFFFF;
for (const byte of bytes) {
crc ^= byte;
for (let bit = 0; bit < 8; bit++) {
crc = (crc & 1) ? (crc >>> 1) ^ 0xA001 : crc >>> 1;
}
}
return [crc & 0xFF, (crc >>> 8) & 0xFF]; // 发送顺序:低字节、高字节
}
modbusCRC16([0x01, 0x03, 0x00, 0x64, 0x00, 0x03]); // [0x44, 0x14]CRC 能检查传输错误,但不能证明寄存器地址、数据类型或倍率正确。
异常响应与排错
异常响应将原功能码的最高位置为 1,再返回异常码。例如,以下构造报文表示读取保持寄存器时遇到非法数据地址:
01 83 02 C0 F1其中 83 对应请求功能码 03,02 为异常码,C0 F1 为 CRC。常见异常码包括 01(非法功能)、02(非法数据地址)、03(非法数据值)和 04(从站设备故障)。无响应与异常响应需要区别排查。
| 现象 | 优先检查 |
|---|---|
| 完全无响应 | 接线、供电、串口参数、从机地址,以及是否有多个主站同时发送 |
| CRC 不通过 | 是否完整收帧,是否误把 HEX 文本当原始字节,串口参数是否一致 |
| 返回异常码 02 | 寄存器地址记法、读取范围,以及功能码对应的数据区 |
| 有响应但数值异常 | 有符号类型、跨寄存器字节序、倍率和单位 |
| DTU 在线但属性不更新 | 查询任务是否执行,自定义数据流和寄存器映射是否一致 |