3. Modbus RTU协议详解:物理层、帧结构与主从站通信模型

好,咱们今天来啃Modbus RTU这块硬骨头。说实话,在我刚入行那会儿,Modbus RTU几乎是每个工业项目的标配。哪怕到了现在,各种花里胡哨的工业协议满天飞,Modbus RTU依然是最基础、最可靠的那一个。你想想看,一个协议能活三十多年,肯定有它的道理。

3.1 物理层:RS-232与RS-485

Modbus RTU的物理层,说白了就是两根线的事儿。但这两根线,选对了是神器,选错了就是噩梦。

3.1.1 RS-232:点对点的老将

RS-232,大家应该都见过,就是电脑后面那个九针串口。它的特点是:

  • 传输距离短:一般不超过15米。我在一个老旧工厂里见过有人硬拉了30米,结果数据全是乱码。
  • 点对点通信:一个串口只能接一个设备。说白了就是一对一聊天。
  • 电压信号:用-15V到+15V的电压差来表示0和1。抗干扰能力一般。

我个人习惯,RS-232只用在调试阶段,或者设备距离很近(比如机柜内部)的场景。真要拉长线,还是得看RS-485。

3.1.2 RS-485:工业现场的主力军

RS-485才是工业现场的王者。它的优势很明显:

  • 传输距离远:理论1200米。我实际项目中用过800米,稳定得很。
  • 支持多节点:一条总线上可以挂32个设备(用中继器还能更多)。
  • 差分信号:用两根线(A和B)的电压差来传输。抗干扰能力比RS-232强太多了。
小技巧:RS-485布线时,记得在总线两端各加一个120欧姆的终端电阻。我曾经在一个项目中忘了加,结果总线反射导致通信时好时坏,排查了整整两天才找到原因。

3.2 帧结构:Modbus RTU的数据包长什么样

Modbus RTU的帧结构,其实很简单。它就像一封信,有地址、有内容、有校验。咱们来拆开看看。

字段 长度 说明
地址码 1字节 设备地址,范围1-247
功能码 1字节 告诉设备要做什么
数据区 N字节 具体的数据内容
CRC校验 2字节 循环冗余校验,确保数据完整

3.2.1 地址码:设备的身份证

地址码就是设备的门牌号。主站发消息时,只有地址匹配的从站才会响应。地址范围是1到247,0是广播地址(所有设备都收,但不回复)。

嗯,这里要注意:地址不能重复。我见过一个项目,两个设备都设成了地址1,结果主站一读数据,两个设备同时回复,总线直接乱套了。

3.2.2 功能码:告诉设备做什么

功能码是Modbus的核心。常用的就那么几个:

  • 0x01:读取线圈状态(读DO)
  • 0x02:读取离散输入(读DI)
  • 0x03:读取保持寄存器(读AO)
  • 0x04:读取输入寄存器(读AI)
  • 0x05:写单个线圈(写DO)
  • 0x06:写单个寄存器(写AO)
  • 0x0F:写多个线圈
  • 0x10:写多个寄存器

我个人最常用的是0x03和0x06。读取传感器数据用0x03,设置参数用0x06。简单粗暴,够用。

3.2.3 数据区:真正的数据在这里

数据区的内容取决于功能码。比如读寄存器时,数据区包含起始地址和读取数量。写寄存器时,数据区包含地址和要写入的值。

举个例子,读取地址为0的保持寄存器,读2个:

请求帧:01 03 00 00 00 02 C4 0B
响应帧:01 03 04 00 01 00 02 79 85

这里01是地址,03是功能码,00 00是起始地址,00 02是读取数量,C4 0B是CRC校验。响应帧里04表示后面有4个字节数据,00 01和00 02就是读到的两个寄存器的值。

3.2.4 CRC校验:数据的守护神

CRC校验是Modbus RTU的保命符。它用16位的循环冗余校验,确保数据在传输过程中没被篡改。

计算CRC的步骤:

  1. 初始化CRC寄存器为0xFFFF
  2. 对每个字节,与CRC寄存器低8位异或
  3. 右移一位,如果移出的位是1,则与0xA001异或
  4. 重复8次,处理下一个字节
  5. 最终结果就是CRC值,低字节在前,高字节在后
避坑指南:我曾经在一个项目中,CRC计算总是对不上。排查了半天,发现是字节序搞反了。Modbus RTU的CRC是低字节在前,高字节在后。这个顺序千万别搞错!

3.3 主从站通信模型:一问一答的规矩

Modbus RTU的通信模型,说白了就是主站问,从站答。主站只有一个,从站可以有多个。主站不发话,从站不能主动说话。

通信流程是这样的:

  1. 主站发送请求帧(包含从站地址、功能码、数据、CRC)
  2. 所有从站都收到这个帧,但只有地址匹配的那个才会处理
  3. 从站处理完,发送响应帧给主站
  4. 主站收到响应,解析数据

如果从站没收到请求,或者请求有错误,从站会发送异常响应。异常响应的功能码是请求功能码加0x80,数据区是异常码。

常见的异常码:

  • 01:非法功能码
  • 02:非法数据地址
  • 03:非法数据值
  • 04:从站设备故障
注意:主站发送请求后,需要等待从站响应。如果超时没收到响应,主站应该重发请求。超时时间一般设为100-500毫秒,具体看总线上设备数量和数据量。

嗯,说到超时,我记得有个项目,总线上挂了20多个设备,主站轮询一圈要好几秒。结果有个设备响应特别慢,经常超时。后来我把超时时间从100毫秒改成了500毫秒,问题就解决了。所以啊,超时时间不是固定的,得根据实际情况调整。

好了,Modbus RTU的核心内容就这些。物理层选RS-485,帧结构记住地址码、功能码、数据区、CRC校验,通信模型就是主站问从站答。掌握了这些,你就能搞定90%的Modbus RTU项目了。