Modbus RTU协议是一种基于串行通信(通常采用RS-485物理层)的工业现场总线协议,采用主从(Master/Slave)架构,通过紧凑的二进制数据帧(包含地址码、功能码、数据段和CRC校验)实现主站与多达247个从站设备之间的高效、可靠数据交换,以其简单、开放和抗干扰能力强而成为工业自动化领域中应用最广泛的通信协议之一。
一、 Modbus RTU协议概述
Modbus RTU (Remote Terminal Unit) 协议是一种广泛应用于工业自动化领域的串行通信协议,由Modicon公司于1979年开发(现属施耐德电气)。它主要用于可编程逻辑控制器(PLC)、传感器、执行器、变频器等工业设备之间的数据交换。

该协议采用主从(Master-Slave)架构。通信过程由主设备(如PLC、监控计算机)发起请求,从设备(如传感器、仪表)接收请求并执行相应操作,然后将响应结果返回给主设备。从设备不能主动发起通信。
Modbus RTU 协议具有简单易用、可靠高效、开放开源、兼容性强等优点,广泛应用于工业控制系统、楼宇自动化(BMS)、能源管理、智能家居等领域。
二、 Modbus RTU 报文帧结构详解
Modbus RTU 报文以一种特定的帧格式在串行线路上传输,以确保数据的准确性和完整性。一个完整的RTU报文帧通常由起始、地址、功能码、数据、CRC校验、结束等部分组成。
以下是报文帧的标准结构:
| 组成部分 | 长度 | 说明 |
|---|---|---|
| 帧起始 (Start) | 至少 3.5 个字符时间的静默间隔 | 线路空闲时间大于等于3.5个字符时间,表示一个新帧的开始。 |
| 设备地址 (Address) | 1 字节 (8位) | 标识目标从设备的唯一地址。 |
| 功能码 (Function) | 1 字节 (8位) | 指示要执行的操作类型。 |
| 数据 (Data) | N 字节 (N * 8位) | 根据功能码不同,包含请求或响应的具体数据,如寄存器地址、数据值等。 |
| CRC校验 (CRC Check) | 2 字节 (16位) | 循环冗余校验,用于检测数据传输过程中的错误。 |
| 帧结束 (End) | 至少 3.5 个字符时间的静默间隔 | 线路空闲时间大于等于3.5个字符时间,表示帧的结束。 |
1. 帧起始与结束 (Start & End)
Modbus RTU 协议通过时间间隔来界定帧的起始和结束,而不是使用特定的起始或结束字符。
帧起始:当线路空闲(静默)时间超过 3.5 个字符时间时,后续的第一个字节被视为新帧的开始。
帧结束:一个帧结束后,线路必须再次进入静默状态,且时长不小于 3.5 个字符时间,以标志着该帧的结束。
帧完整性:在报文传输过程中,如果两个字符之间的间隔超过了 1.5 个字符时间,则接收设备会认为此帧不完整并将其丢弃。
2. 设备地址 (Address)
地址域占用 1个字节(8位) ,用于区分连接到同一总线上的不同从设备。
有效的从机地址范围是 1 到 247。
地址 0 被保留用作广播地址。主设备发送地址为0的报文时,总线上所有的从设备都会接收并执行命令,但不需要返回响应。
地址范围 248 到 255 被保留,通常不用于设备地址。
3. 功能码 (Function Code)
功能码占用 1个字节(8位) ,用于告诉从设备要执行什么操作。
功能码分为公共功能码、用户自定义功能码和保留功能码。常用的公共功能码如下:
| 功能码 | 名称 | 作用 |
|---|---|---|
| 01 (0x01) | 读取线圈状态 | 读取从设备一组线圈输出的ON/OFF状态。 |
| 02 (0x02) | 读取离散输入状态 | 读取从设备一组离散量输入的ON/OFF状态。 |
| 03 (0x03) | 读取保持寄存器 | 读取从设备一组保持寄存器的当前值(可读写)。 |
| 04 (0x04) | 读取输入寄存器 | 读取从设备一组输入寄存器的当前值(只读)。 |
| 05 (0x05) | 写单个线圈 | 强制设置一个线圈输出为ON或OFF状态。 |
| 06 (0x06) | 写单个寄存器 | 向从设备的某个保持寄存器写入一个值。 |
| 15 (0x0F) | 写多个线圈 | 强制设置多个线圈输出为ON或OFF状态。 |
| 16 (0x10) | 写多个寄存器 | 向从设备的多个保持寄存器写入连续的值。 |
4. 数据域 (Data)
数据域是可变长度的,其具体格式和内容取决于功能码。
在主站请求报文中,数据域通常包含:
要读取或写入的寄存器/线圈的起始地址(占用2字节)。
要读取或写入的寄存器/线圈的数量(占用2字节)。
要写入的数据值。
在从站响应报文中,数据域通常包含:
响应的字节数。
实际读取到的寄存器/线圈的数据值。
5. 循环冗余校验 (CRC Check)
CRC校验域占用 2个字节(16位) ,位于报文末尾,用于检测报文在传输过程中是否因噪声或干扰而发生错误。
Modbus RTU协议使用的是 CRC-16 (IBM) 算法,多项式为 0xA001(即 X^16 + X^15 + X^2 + 1)。
发送端计算整个报文(地址、功能码、数据域)的CRC值,并将其附加到报文后面,低字节在前,高字节在后。
接收端收到报文后,会用同样的算法对接收到的报文(地址、功能码、数据域)重新计算CRC值,并将其与接收到的CRC值进行比较。如果两者不相等,则表明数据传输有误,接收端会丢弃该报文。
CRC-16 算法实现步骤(查表法效率更高,此处介绍标准计算法):
预置一个16位寄存器为 0xFFFF。
将报文中的第一个字节(地址域)与CRC寄存器的低8位进行 异或(XOR) 运算,结果放回CRC寄存器。
CRC寄存器右移一位,最高位补0.
检查刚移出的最低位:
如果最低位为1.则将CRC寄存器与多项式 0xA001 进行异或运算。
如果最低位为0.则不移位,直接进行下一步。
重复步骤3和4.共 8次,处理完一个字节的所有位。
重复步骤2到5.处理报文中的下一个字节(功能码域、数据域),直到所有字节处理完毕。
最终得到的CRC寄存器值即为该报文的CRC校验码。
三、 典型报文应用示例
假设一个主站需要从地址为 01 的从站,读取从起始地址 0x0000 开始的 2个保持寄存器(功能码 03)。
1. 主站请求报文(十六进制表示)
| 字段 | 数据 (Hex) | 说明 |
|---|---|---|
| 从站地址 | 01 | 目标从设备的地址。 |
| 功能码 | 03 | 读取保持寄存器。 |
| 起始地址高字节 | 00 | 要读取的寄存器的起始地址(0x0000)。 |
| 起始地址低字节 | 00 | |
| 寄存器数量高字节 | 00 | 要读取的寄存器数量(2个)。 |
| 寄存器数量低字节 | 02 | |
| CRC校验低字节 | C0 | 对 01 03 00 00 00 02 进行CRC-16计算得到的校验码,低字节在前。 |
| CRC校验高字节 | 0B |
完整请求报文:01 03 00 00 00 02 C0 0B
2. 从站正常响应报文
假设从站的两个保持寄存器(地址0x0000和0x0001)中分别存储了值 0x00A1 和 0x00B2.则响应报文如下:
| 字段 | 数据 (Hex) | 说明 |
|---|---|---|
| 从站地址 | 01 | 响应来自地址01的从站。 |
| 功能码 | 03 | 确认是读取保持寄存器的响应。 |
| 返回字节数 | 04 | 返回的数据共有4个字节。 |
| 寄存器1数据高字节 | 00 | 第一个寄存器的值(0x00A1)。 |
| 寄存器1数据低字节 | A1 | |
| 寄存器2数据高字节 | 00 | 第二个寄存器的值(0x00B2)。 |
| 寄存器2数据低字节 | B2 | |
| CRC校验低字节 | xx | 对 01 03 04 00 A1 00 B2 进行CRC-16计算得到的校验码。 |
| CRC校验高字节 | xx |
完整响应报文:01 03 04 00 A1 00 B2 xx xx
四、 应用场景与注意事项
应用场景:Modbus RTU 广泛用于连接现场传感器、执行器与PLC;在远程监控与故障诊断系统中传输设备实时数据;以及作为不同厂商设备间系统集成和数据共享的“桥梁”。
通信媒介:主要基于 RS-485 接口,具有长距离、高抗干扰能力,也支持 RS-232/RS-422.
参数配置:通信前,主、从设备必须预先配置一致的通信参数,如波特率(如9600. 19200)、数据位(通常为8)、校验位(无、奇或偶校验)和停止位。
抗干扰性:CRC校验机制确保了数据的完整性。在工业环境中,应使用屏蔽双绞线,并注意终端电阻的正确配置,以进一步增强抗干扰能力。
限制:协议本身没有安全认证机制,如用户认证或加密,因此在涉及安全关键的应用中需要额外的保护措施。同时,串行通信的速率相对于现代以太网协议较低。
通过以上详尽的解析,希望能帮助您全面理解 Modbus RTU 报文的构成、原理及其在实际中的应用。如果您有特定的报文分析需求,欢迎进一步提问。
