茜莉娅 Serelia
← Back to the beginning

Modbus初遇

技术笔记

在总线上飞速行驶

Modbus

关于工控上位机的部分,我在学校的时候理解还是比较少的,甚至很少接触过。 最近在实习的时候

ModBus协议

顾名思义,他是一个Bus,叫做Modbus,即总线协议,是一款特殊的协议

它分为以下几种:

  • Modbus-RTU
  • Modbus-ASCII
  • Modbus-TCP

大部分的嵌入式设备都是基于这三种协议中的一种,通常情况下,大部分协议都基于Modbus-RTU的。

通讯方式

Modbus 通常为主从方式通讯,需要分别主站和从站,不能以同步的方式进行通信。总线上每次只有一个数据进行传输,即主机发送,从机应答,主机不发送,总线上就没有数据通信。

Example #1

例如一个总线上有一个主机,多个从机,主机查询其中一个从机,首先必须要得到从机分配地址(这样才能知道哪个从机,而且每个地址必须唯一),分配好地址后,主机开始查询,然后数据下发,从机得到主机发送的数据,然后对应地址的从机回复,主机得到从机数据,这样就是一个主机到从机的通信过程,条理很清晰

Modbus-RTU协议

如果两方要进行通讯,必须要遵守Modbus-RTU 协议。

这是Modbus协议上规定的,且默认模式必须是RTU,ASCII作为选项。

一、帧结构

地址 + 功能码+ 数据 + CRC校验

  • 地址: 占用一个字节,范围0-255,其中有效范围是1-247,其他具有特殊用途,比如255是广播地址(广播地址就是应答所有地址,正常的需要两个设备的地址一样才能进行查询和回复)。
  • 功能码:占用一个字节,功能码的意义就是,知道这个指令的用途,比如你可以查询从机的数据,也可以修改数据,所以不同功能码对应不同功能。
  • 数据body:根据功能码不同,有不同结构,在下面的实例中有说明。
  • CRC校验:为了保证数据不错误,增加这个,然后再把前面的数据进行计算看数据是否一致,如果一致,就说明这帧数据是正确的,我再回复;如果不一样,说明你这个数据在传输的时候出了问题,数据不对的,所以就抛弃了。

Modbus-RTU协议一般我们用的最多功能码就是03和06,大部分都是用modbus来查询传感器上的信息用03查询功能码,如果需要修改传感器寄存器的值就用06修改功能码。

0x03

现在我是主机,我要查询从机地址为01的数据。

那么我要发送以下的数据

主机发送:01 03 00 00 00 01 84 0A
从机回复:01 03 02 19 98 B2 7E

主机发送的数据大致是 地址+功能码+数据+校验;

01-地址,也就是传感器的地址
03-功功能码,03代表查询功能,查询传感器的数据
00 00-代表查询的起始寄存器地址.说明从0x0000开始查询。这里需要说明以下,Modbus把数据存放在寄存器中,通过查询寄存器来得到不同变量的值,一个寄存器地址对应2字节数据
00 01-代表查询了一个寄存器.结合前面的00 00,意思就是查询从0开始的1个寄存器值
84 0A-循环冗余校验,是modbus的校验公式,从首个字节开始到84前面为止;

回复数据解析

01-地址,也就是传感器的地址
03-功能码,03代表查询功能,查询传感器的数据。这里要注意的是Focus on发给从机的功能码是什么,从机就要回复同样的功能码,如果不一样说明这一帧数据有错误
02-代表后面数据的字节数,因为前面说到,一个寄存器有2个字节,所以后面的字节数为是2 * 查询的寄存器个数;
19 98-寄存器的值是19 98,结合发送的数据看出,01这个寄存器的值为19 98
B2 7E-循环冗余校验结果
  • 发送:从机的地址+命令功能码+我要查的寄存器的地址+我要查的寄存器地址的个数+校验码
  • 回复:从机的地址+主机发我命令功能码+要发送给主机数据的字节数+数据+校验码

在这个过程中,主机的地址是隐藏的,因为通讯的目标是从机,从来不需要主机的地址。

0x06

当我要修改从机的内容时,就可以使用0x06功能码。

主机发送: 01 06 00 00 00 01 48 0A
从机回复: 01 06 00 00 00 01 48 0A

诶,怎么发送和回复的命令都是一模一样的。

现在来解析一下

01-主机要查询的从机地址
06-功能码,06代表修改单个寄存器功能,修改有些不同,有修改一个寄存器和修改多个寄存器;
00 00-代表修改的起始寄存器地址.说明从0x0000开始.
00 01-代表修改的值为00 01.结合前面的00 00,意思就是修改0号寄存器值为00 01;
48 0A-循环冗余校验,是modbus的校验公式,从首个字节开始到48前面为止;

回复的指令(一模一样)

01-从机返回给主机自己的地址,说明这就是主机查的从机
06-功能码,代表修改单个寄存器功能,主机发啥功能码,从机就必须回什么功能码;
00 00-代表修改的起始寄存器地址.说明是0x0000.
00 01-代表修改的值为00 01.结合前面的00 00,意思就是修改0号寄存器值为00 01;
48 0A-循环冗余校验,是modbus的校验公式,从首个字节开始到48前面为止;

如果回复的一样,说明这个数据是修改成功的;如果功能码不是06,而是别的,说明从机回复的数据有误,主机可以做相应的处理。

© 泠時月 2026,采用 CC BY 4.0 许可,转载保留署名。

留言 · 0 段对话

© 2026 茜莉娅 · Powered by Serelia 茜莉娅 88x31 徽章

扫码分享

二维码