modbus rtu通讯协议格式详解

  Modbus RTU(Remote Terminal Unit)协议是工业自动化领域应用最广泛的现场总线通信协议之一。它以其结构简单、易于实现、可靠性高而著称,构成了众多工业控制系统(如PLC、DCS、SCADA)与传感器、执行器、仪表等设备之间数据交换的基石。要深入理解其工作原理和进行高效的开发调试,透彻掌握其通信帧格式是关键。本详解将从协议概述、帧结构、各字段定义、校验机制及时序要求等多个维度,对Modbus RTU协议格式进行全面剖析。

  一、 协议概述与基本特性

  Modbus RTU是一种主从式、串行通信协议,由Modicon公司(现属施耐德电气)于1979年提出,现已成为业界事实标准。

  •   通信模式:采用主从(Master-Slave)架构。网络中只有一个主站(Master),负责发起所有通信请求;一个或多个从站(Slave)则被动响应主站的请求。从站之间不能直接通信。
  •   物理层:通常运行在RS-485物理接口上,也支持RS-232.RS-485因其差分信号传输、抗干扰能力强、支持多点通信(一条总线上可挂接多个设备)和长距离传输(可达1200米)等优点,成为Modbus RTU最常用的物理介质。
  •   数据表示:采用二进制编码,数据传输效率高于其兄弟协议Modbus ASCII。整个数据帧作为一个连续的二进制流进行传输。
  •   协议定位:需要明确区分,Modbus RTU是应用层协议,定义了数据的组织方式和含义;而RS-485/232是物理层和链路层协议,定义了电气特性和比特流传输方式。两者协同工作,共同完成通信任务。
lora

  二、 RTU帧整体结构

  Modbus RTU协议的核心在于其严谨的帧格式。一帧完整的RTU报文由四个固定部分顺序构成,总长度为 n + 5 字节(其中n为数据域的字节数)。其通用结构如下表所示:

字段长度(字节)描述示例值(以读取保持寄存器为例)
从机地址 (Slave Address)1标识目标从站设备的网络地址。0x01 (表示寻址1号从站)
功能码 (Function Code)1指示从站需要执行的操作类型(如读、写)。0x03 (读取保持寄存器)
数据域 (Data Field)N (可变)包含请求的参数或响应的数据内容,具体结构由功能码决定。0x00 0x01 0x00 0x02 (请求:起始地址0x0001.读取2个寄存器)
CRC校验 (CRC-16)2循环冗余校验码,用于验证帧传输的完整性。0x85 0x39 (示例值)

  帧的界定:与Modbus ASCII使用冒号(:)和回车换行(CR/LF)作为帧首尾定界符不同,Modbus RTU帧没有起始和结束字符。它依靠传输线上的空闲时间来界定一帧的开始与结束。

  帧起始:在总线空闲(无数据传输)时间达到 至少3.5个字符的传输时间(T3.5)‍ 后,第一个接收到的字节即被视为新帧的起始。

  帧结束:最后一个字节(CRC校验码的第二个字节)传输完毕后,总线再次进入 超过3.5个字符时间(T3.5)‍ 的空闲状态,即表示本帧结束。

  帧内连续性:帧内的 字符间隔必须小于1.5个字符的传输时间(T1.5)‍ ,以确保接收方将其识别为一个连续的帧。

  这种基于时间的帧界定方式是RTU模式高效且无额外字节开销的关键,但也对主从设备的串口时序处理提出了精确要求。

  三、 帧各字段详解

  1. 从机地址 (Slave Address)

  作用:这是报文的第一字节,用于网络设备寻址。主站通过此字段指定要与哪个从站通信。从站在响应时,也会将自己的地址填入此字段,以便主站识别响应来源。

  取值范围

  0 (0x00) :广播地址。主站向地址0发送的报文,网络上的所有从站都会接收并执行(如果功能码支持),但从站不会对广播报文作出响应

  1 – 247 (0x01 – 0xF7) :有效的单播从站地址。每个从站必须在网络中配置一个唯一的地址。

  248 – 255 (0xF8 – 0xFF) :保留地址,通常未定义或用于特殊用途。

  2. 功能码 (Function Code)

  作用:紧随地址域之后,是定义操作类型的核心字段。它告诉从站是读取数据还是写入数据,以及操作哪种类型的数据对象(如线圈、寄存器)。

  编码规则

  占用1字节,标准定义的有效范围为 1 – 127 (0x01 – 0x7F) 。

  当从站正常执行主站请求时,响应报文中的功能码与请求报文中的相同

  当从站因故(如非法地址、非法数据值、设备故障等)无法处理请求时,它会返回一个异常响应。异常响应的功能码是 原请求功能码值加上0x80(即最高位置1)‍ ,同时会在数据域中携带一个异常代码以说明错误原因。例如,对0x03(读寄存器)的异常响应功能码为0x83.

  功能码分类与常见类型

  公共功能码:由Modbus组织明确定义和文档化,保证唯一性。

  用户自定义功能码:范围65-72和100-110.供设备制造商实现非标准功能。

  保留功能码:因历史原因被某些厂商占用,不作为公共功能。

  以下是部分最常用的公共功能码:

功能码(十进制/十六进制)名称操作对象作用
01 (0x01)读取线圈状态线圈(Coils)读取一个或多个线圈(可读写布尔量)的ON/OFF状态。
02 (0x02)读取离散量输入离散输入(Discrete Inputs)读取一个或多个离散输入(只读布尔量)的ON/OFF状态。
03 (0x03)读取保持寄存器保持寄存器(Holding Registers)最常用。读取一个或多个保持寄存器(可读写16位字)的内容。
04 (0x04)读取输入寄存器输入寄存器(Input Registers)读取一个或多个输入寄存器(只读16位字)的内容。
05 (0x05)写单个线圈线圈(Coils)强制一个线圈为ON或OFF。
06 (0x06)写单个寄存器保持寄存器(Holding Registers)写入一个值到一个保持寄存器中。
15 (0x0F)写多个线圈线圈(Coils)强制多个线圈为ON或OFF。
16 (0x10)写多个寄存器保持寄存器(Holding Registers)写入多个值到连续的保持寄存器中。

  3. 数据域 (Data Field)

  作用:这是一个长度可变的字段,其具体内容和结构完全由功能码决定。它包含了执行请求所需的参数或返回的请求结果。

  请求帧中的数据域:通常包含操作的起始地址和数量等信息。

  示例(功能码0x03 – 读保持寄存器)‍ :数据域为4字节,前2字节为起始地址(例如 0x00 0x01 表示寄存器地址1),后2字节为寄存器数量(例如 0x00 0x02 表示读取2个寄存器)。地址和数据均采用 大端字节序(Big-Endian)‍ ,即高字节在前。

  响应帧中的数据域:在成功响应中,通常以一个字节计数开头,后面跟着请求的数据。

  续上例:若成功读取2个寄存器(共4字节数据),响应帧的数据域可能为:0x04(字节计数,表示后面有4个数据字节)0x12 0x34 0x56 0x78(两个寄存器的值:0x1234 和 0x5678)。

  4. 循环冗余校验 (CRC-16)

  作用:位于帧尾的2字节CRC校验码,是确保数据传输完整性准确性的核心机制。发送设备计算整个报文(从地址域到数据域)的CRC值并附加在帧尾;接收设备重新计算所收报文的CRC值,并与接收到的CRC值进行比较。若两者不一致,则表明传输过程中发生了错误,该帧应被丢弃。

  算法与特性

  Modbus RTU采用 CRC-16 校验算法,其生成多项式为 X¹⁶ + X¹⁵ + X² + 1 (对应十六进制 0x8005.但计算时需进行位序处理) 。

  计算时,CRC寄存器的初始值为 0xFFFF 。

  计算范围涵盖地址、功能码和所有数据域字节,但不包括串行通信中的起始位、停止位和奇偶校验位。

  字节顺序:计算出的16位CRC值,在帧中传输时是 低字节在前(Little-Endian)‍。例如,计算出的CRC值为0x3985.则在线上传输的顺序为 0x85(低字节),然后是 0x39(高字节)。

  优化实现:在实际编程中,常采用查表法来加速CRC计算,即预先计算好所有256个可能字节输入对应的CRC部分值并存储在数组中,通过查表代替逐位计算,显著提升效率。

  四、 传输时序与物理层参数

  为了确保RTU帧能被正确解析,除了帧格式本身,还必须遵守严格的时序和串口参数配置。

  1. 字符帧格式 (每字节的封装)

  每个字节在串行线上传输时,被封装在起始位和停止位之间。

  起始位:1位。

  数据位:通常为8位

  校验位:可选。可以是 奇校验(Odd)、偶校验(Even)或无校验(None)‍。默认常用偶校验

  停止位:当使用偶校验或无校验时,通常为1位;当使用无校验时,有时要求为2位以提供更好的帧同步。

  2. 波特率 (Baud Rate)

  通信主站和所有从站必须设置为相同的波特率,否则无法解码。

  常见波特率有:1200. 2400. 4800. 9600, 19200. 38400. 57600. 115200等。9600 bps是最常见且兼顾距离与可靠性的默认选择。波特率越高,通信速率越快,但对线路质量和距离的要求也越苛刻。

  帧间与帧内时序(再次强调,因其至关重要):

  T1.5 (帧内字符间隔) :帧内连续两个字节的间隔时间必须 < 1.5个字符传输时间

  T3.5 (帧间空闲间隔) :两帧之间的总线空闲时间必须 > 3.5个字符传输时间,以此作为帧分隔符。

  字符时间计算:字符时间取决于波特率和字符帧格式。例如,在9600波特率、8数据位、偶校验、1停止位(即8E1)的配置下,一个字符共11位(1+8+1+1)。传输一个字符所需时间为:(1 / 9600) * 11 ≈ 1.1458 ms。因此,T3.5 ≈ 4.01 ms。当波特率 >= 19200时,T3.5通常被固定为1750μs。

  五、 总结

  Modbus RTU协议通过其简洁而严谨的四段式帧结构(地址、功能码、数据、CRC),结合基于时间间隔的帧界定可靠的CRC-16校验,在嘈杂的工业环境中实现了稳定高效的数据通信。理解其格式细节,特别是地址范围、功能码含义、数据域的组织方式以及CRC的计算和传输顺序,是进行设备集成、协议开发和故障诊断的基础。在实际应用中,务必确保所有网络设备采用一致的波特率、数据位、校验位和停止位设置,并正确处理T3.5和T1.5时序,这是建立可靠Modbus RTU通信的前提。

滚动至顶部
Baidu
map