STM32:Modbus-RTU通讯协议

本文详细介绍了Modbus-RTU协议的基本结构,包括设备地址、功能码、数据区和CRC校验的使用,以及各功能码如读开关、读寄存器、写操作的详细步骤和报文示例。掌握这些有助于理解工业设备间通信的标准化过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Modbus是一种串行通信协议,是Modicon公司(现在的施耐德电气 Schneider Electric)于1979年为使用可编程逻辑控制器(PLC)通信而发表。Modbus已经成为工业领域通信协议的业界标准(De facto),并且现在是工业电子设备之间常用的连接方式。


一、Modbus-RTU报文格式

设备地址功能码数据区CRC校验
1个字节1个字节N个字节2 个字节(16 位循环冗余校验码)

注:1 个字节由 8 位二进制组成,即 8 bits。

1. 设备地址

设备地址是每次通讯信息帧的第一个字节,从 0 到 255。这个字节表明由用户设置为该地址的设备将接收由主站发过来的此条信息,每个设备必须有一个唯一的地址,只有符合这个地址的设备才能响应主站回送信息。当从机回送信息时,回送数据的第一个字节也是这个设备的地址。
主站发送的数据当中的设备地址表明将要发送到哪个设备,设备返回的数据当中的设备地址表明此数据来自何处。

2. 功能码

功能码是每次通讯的数据的第二个字节,MODBUS 通讯规约可以定义的功能码的范围为 1 到 127,我们仅采用了其中一部分功能码,具体如下:

功能码(HEX)定义描述
01读开关读取一路或多路开关的状态
03读寄存器读取一个或多个寄存器 (模拟量) 数据
05写单路开关控制一路开关的分或合
06写单个寄存器写入一个寄存器 (模拟量)数据
0F写多路开关控制多路开关的分或合
10写多个寄存器写入多个寄存器 (模拟量)数据

3. 数据区

数据区是主站要写给从站的数据和从站回复主站要读的数据。
数据区的内容以 Big Endian 形式储存,通讯时先发高位字节,后发低位字节。

4. CRC校验

CRC校验是16 位循环冗余校验码,主要用来校验传输数据的准确性。
CRC校验详细介绍

二、功能码详细说明

1. 功能码01:读开关

所有的开关都以二进制位进行编码,每个开关一位,一个字节可以容纳 8 个开关的状态,1 为合状态,0 为分状态。
开关的地址为位编码的,可以理解为地址为 0 的开关在数据区第 1 个字节的 D0 位,地址为 1 的开关在 数据区的第 1 个字节的 D1 位,……地址为 7 的开关在数据区的第 1 个字节的 D7 位,地址为 8 的开关 在数据区的第 2 个字节的 D0 位,地址为 X 的开关,在数据区第 X/8+1 个字节的 D[X%8]位。
主机发送报文格式:

格式长度作用
设备地址1个字节设备地址
功能码1个字节01:读开关状态
起始地址2个字节从哪个地址的开关开始读取开关状态 (起始 bit 位)
开关个数2个字节读取几个开关的状态 (bits 数)
CRC校验码2个字节设备地址、功能码、起始地址、开关个数的 CRC 校验码

从机返回数据报文格式:

格式长度作用
设备地址1个字节设备地址
功能码1个字节01:读开关状态
数据字节数N1个字节要返回多少个字节的数据,每个字节包含 8 开关的状态
数据字节数 N= (开关个数+7)÷8
数据N个字节返回的第 1 个字节的 D0 位为第一个 (起始地址) 开关的状态;
返回的第 1 个字节的 D1 位为第二个 (起始地址+1) 开关的状态;
……
返回的第 N 个字节的 D0 位为第 8N-7 个 (起始地址+8N-8) 开关的状态
返回的第 N 个字节的 D1 位为第 8N-6 个 (起始地址+8N-7) 开关的状态
……
CRC校验码2个字节设备地址、功能码、数据字节数、数据的 CRC 校验码

2. 功能码03:读寄存器

每个寄存器都是两个字节 (16 位二进制数据),高位字节在前,低位字节在后。每个寄存器表示的数据 范围为-32768 到 32767,负数用补码 (two’s complement) 表示。
寄存器的地址编码,可以理解为地址为 0 的寄存器在数据区的第 1 个和第 2 个字节,地址为 1 的寄存 器在数据区的第 3 个和第 4 个字节,地址为 2 的寄存器在数据区的第 5 个和第 6 个字节……
主机发送报文格式:

格式长度作用
设备地址1个字节设备地址
功能码1个字节03:读寄存器
起始地址2个字节从哪个地址的寄存器开始读取数据
寄存器个数2个字节读取几个寄存器的数据 (字节数=寄存器个数×2)
CRC校验码2个字节设备地址、功能码、起始地址、寄存器个数的 CRC 校验码

从机返回数据报文格式:

格式长度作用
设备地址1个字节设备地址
功能码1个字节03:读寄存器
数据字节数N1个字节数据字节数 N=寄存器个数×2
寄存器数据N个字节寄存器个数=数据字节数÷2
返回的第一个字节和第二个字节是第一个 (起始地址) 的寄存器数据
返回的第三个字节和第四个字节是第二个 (起始地址+1) 的寄存器数据
……
CRC校验码2个字节设备地址、功能码、数据字节数、寄存器数据的 CRC 校验码

3. 功能码05:写单路开关

主机发送报文格式:

格式长度作用
设备地址1个字节设备地址
功能码1个字节05:写单路开关
开关的地址2个字节对哪个地址的开关进行控制
控制命令2个字节FF00 为合闸命令,0000 为分闸命令
CRC校验码2个字节设备地址、功能码、开关的地址、控制命令的 CRC 校验码

从机返回数据报文格式:
从机返回的报文与主机发送的报文完全相同。
从机返回这个报文,说明装置接受了遥控命令,开始执行命令,判断是否成功的执行完成了要以读开关的状态等于控制的目标值为准,即读出的开关状 态等于写入的开关状态,认为遥控执行成功的完成了。

4. 功能码06:写单个寄存器

主机发送报文格式:

格式长度作用
设备地址1个字节设备地址
功能码1个字节06:写单个寄存器
寄存器地址2个字节把数据写入哪个寄存器
写入的数据2个字节写入寄存器的数据
CRC校验码2个字节设备地址、功能码、寄存器地址、写入的数据的 CRC 校验码

从机返回数据报文格式:
从机返回的报文与主机发送的报文完全相同。
从机返回这个报文,说明装置接受了写入寄存器的命令, 开始执行命令,判断是否成功的执行完成了写入数据,要以读寄存器的数据等于写入的值为准, 即读出的寄存器数据等于写入的寄存器数据,认为写入执行成功的完成了。

5. 功能码0F:写多路开关

主机发送报文格式:

格式长度作用
设备地址1个字节设备地址
功能码1个字节0F:写多路开关
起始地址2个字节从哪个地址的开关开始进行控制
开关个数2个字节对几个开关进行控制
数据字节数N1个字节写入开关的数据的字节数,即接下来的遥控命令的字节数
数据字节数 N= (开关个数+7)÷8
写入的数据N个字节写入的第 1 个字节的 D0 位为第一个 (起始地址) 开关的状态;
写入的第 1 个字节的 D1 位为第二个 (起始地址+1) 开关的状态;
……
写入的第 2 个字节的 D0 位为第九个 (起始地址+8) 开关的状态
……
CRC校验码2个字节设备地址、功能码、起始地址、开关个数、字节数、数据的 CRC 校验码

从机返回数据报文格式:

格式长度作用
设备地址1个字节设备地址
功能码1个字节0F:写多路开关
起始地址2个字节从哪个地址的开关开始进行控制
开关个数2个字节对几个开关进行控制
CRC校验码2个字节设备地址、功能码、起始地址、开关个数的 CRC 校验码

从机返回这个报文,说明装置接受了遥控命令,开始执行命令,判断是否成功的执行完成了要以读开关 的状态 等于控制的目标值为准,即读出的开关状态等于写入的开关状态,认为遥控执行成功的 完成了。

6. 功能码10:写多个寄存器

主机发送报文格式:

格式长度作用
设备地址1个字节设备地址
功能码1个字节10:写多个寄存器
起始地址2个字节从哪个地址的寄存器开始写入
寄存器个数2个字节对几个寄存器进行写入
数据字节数N1个字节写入寄存器的数据的字节数,即接下来的遥调命令的字节数
数据字节数 N=寄存器个数×2
写入的数据N个字节写入的第一个字节和第二个字节是第一个 (起始地址) 的寄存器数据
写入的第三个字节和第四个字节是第二个 (起始地址+1) 的寄存器数据
CRC校验码2个字节设备地址、功能码、起始地址、寄存器个数、字节数、数据的 CRC 校验码

从机返回数据报文格式:

格式长度作用
设备地址1个字节设备地址
功能码1个字节10:写多个寄存器
起始地址2个字节从哪个地址的寄存器开始写入
寄存器个数2个字节对几个寄存器进行写入
CRC校验码2个字节设备地址、功能码、起始地址、寄存器个数的 CRC 校验码

从机返回这个报文,说明从机接受了遥调命令,开始执行命令,判断是否成功的执行完成了要以读寄存 器的数据等于遥调的目标值为准,即读出的寄存器的数据等于写入寄存器的数据,认为遥调执 行成功的完成了。

三、从机对主机命令的回应

1. 从机对主机的正确命令回应

设备地址功能码数据区CRC校验
1个字节1个字节N个字节2个字节(16 位循环冗余校验码)

从机的功能码和主机下发的功能码相同。

2. 从机对主机的错误命令回应

设备地址功能码数据区CRC校验
1个字节1个字节
最高位置1
1个字节
错误编码
2个字节(16 位循环冗余校验码)

从机功能码=主机功能码|0x80。
错误编码

编码(HEX)含义说明
01无效功能码无法实现的功能
未设置的功能
02无效数据地址起始地址越界
数据个数越界
03无效数据值数据帧个数不对
数据CRC校验出错
写入的数值无效

3. 错误命令回应报文示例

01 81 02 C1 91 收到的功能码为01的命令有错误(81),错误码为 02:地址无效或长度越界 。
01 83 02 C0 F1 收到的功能码为03的命令有错误(83),错误码为 02:地址无效或长度越界。
01 85 03 02 91 收到的功能码为05的命令有错误(85),错误码为 03:写入的数值无效。

三、Modbus-RTU通讯协议报文示例

从机——设备地址为 8
从机——开关状态:0----分,1----合。

地址01234567891011121314151617181920
状态010011000111000011110

从机——寄存器数据

地址01234567891011121314151617181920
数据(DEC)100010010200020020300030030400040040500050050600060060700070070
数据(HEX)03EA0064000A07D000C800140BB8012C001E0FA001900028138801F4003217700258003C1B5802BC0046

1. 功能码01:读开关

查询地址从4到8的5个开关状态:
主机发送数据(HEX):08 01 00 04 00 05 BD 51

格式长度数据(HEX)描述
设备地址1个字节08设备地址:08
功能码1个字节01功能码01:读开关状态
起始地址2个字节00 04起始地址: 0004,先发高位字节 00,后发低位字节 04
开关个数2个字节00 05读取 0005 个开关的状态,先发高位字节 00,后发低位字节 05
CRC校验码2个字节BD 5108 01 00 04 00 05 的 CRC 校验码

从机返回数据(HEX):08 01 01 03 12 15

格式长度数据(HEX)描述
设备地址1个字节08设备地址
功能码1个字节0101:读开关状态
数据字节数N1个字节01接下来有 1 个字节的数据,最多可表示 8 开关的状态
数据1个字节03只查询 5 个开关的状态,D0-D4: 开关状态,D5-D7 无意义
数据 03 用二进制表示等于 00000011
CRC校验码2个字节12 1508 01 01 03 的 CRC 校验码

2. 功能码03:读寄存器

查询地址从2到5的4个寄存器数据:
主机发送数据(HEX):08 03 00 02 00 04 E5 50

格式长度数据描述
设备地址1个字节08设备地址
功能码1个字节0303:读寄存器
起始地址2个字节00 02起始地址: 0002,先发高位字节 00,后发低位字节 02
寄存器个数2个字节00 04读取 0004 个寄存器的数据,先发高位字节 00,后发低位字节 04
CRC校验码2个字节E5 5008 03 00 02 00 04 的 CRC 校验码

从机返回数据(HEX):08 03 08 00 0A 07 D0 00 C8 00 14 50 DF

格式长度数据(HEX)作用
设备地址1个字节08设备地址
功能码1个字节0303:读寄存器
数据字节数N1个字节08接下来有 8 个字节,即 4 个寄存器的数据
寄存器数据8个字节00 0A 07 D0 00 C8 00 14因为查询命令是从地址 2 的寄存器开始查询的,
返回的第一个寄存器的数据就是地址为 2 的寄存器的数据:
00 0A: 地址为 2 的寄存器的数据 = 0x000A,即10
07 D0: 地址为 3 的寄存器的数据 = 0x07D0,即 2000
00 C8: 地址为 4 的寄存器的数据 = 0x00C8,即 200
00 14: 地址为 5 的寄存器的数据 = 0x0014,即 20
CRC校验码2个字节50 DF08 03 08 00 0A 07 D0 00 C8 00 14 的 CRC 校验码

3. 功能码05:写单路开关

对地址为6的开关进行合闸:
主机发送数据(HEX):08 05 00 06 FF 00 6C A2
从机返回数据(HEX):08 05 00 06 FF 00 6C A2

格式长度数据(HEX)作用
设备地址1个字节08设备地址
功能码1个字节0505:写单路开关
开关的地址2个字节00 06开关的地址:0006,先发高位字节 00,后发低位字节 06
控制命令2个字节FF 00开关合闸命令:0xFF00
CRC校验码2个字节6C A208 05 00 06 FF 00 的 CRC 校验码

对地址为6的开关进行分闸:
主机发送数据(HEX):08 05 00 06 00 00 2D 52
从机返回数据(HEX):08 05 00 06 00 00 2D 52

格式长度数据(HEX)作用
设备地址1个字节08设备地址
功能码1个字节0505:写单路开关
开关的地址2个字节00 06开关的地址:0006,先发高位字节 00,后发低位字节 06
控制命令2个字节00 00开关分闸命令:0x0000
CRC校验码2个字节2D 5208 05 00 06 00 00 的 CRC 校验码

4. 功能码06:写单个寄存器

把数据-30写入地址为8的寄存器:
主机发送数据(HEX):08 06 00 08 FF E2 C9 28
从机返回数据(HEX):08 06 00 08 FF E2 C9 28

格式长度数据(HEX)作用
设备地址1个字节08设备地址
功能码1个字节0606:写单个寄存器
寄存器地址2个字节00 08寄存器地址:0008,先发高位字节 00,后发低位字节 08
写入的数据2个字节FF E2写入寄存器的数据 -30 的补码为 0xFFE2,先发高位字节 FF,后发低位字节 E2
CRC校验码2个字节C9 2808 06 00 08 FF E2的 CRC 校验码

5. 功能码0F:写多路开关

对地址为 6 的开关进行合闸置1、对地址为 7 的开关进行分闸置0、对地址为 8 的开关进行合闸置1:
主机发送数据(HEX):08 0F 00 06 00 03 01 05 07 3E

格式长度数据(HEX)作用
设备地址1个字节08设备地址
功能码1个字节0F0F:写多路开关
起始地址2个字节00 06起始地址:0006,先发高位字节 00,后发低位字节 06
开关个数2个字节00 03对 3 个开关进行遥控,先发高位字节 00,后发低位字节 03
数据字节数1个字节01写数据的字节数:1 个字节,最多能表示 8 个开关的状态
写入的数据1个字节05由于写入 3 个开关的状态,D0-D2: 开关状态,D3-D7 无意义 数据 05 用二进制表示等于 00000101
CRC校验码2个字节07 3E08 0F 00 06 00 03 01 05的 CRC 校验码

从机返回数据(HEX):08 0F 00 06 00 03 F5 52

格式长度数据(HEX)作用
设备地址1个字节08设备地址
功能码1个字节0F0F:写多路开关
起始地址2个字节00 06起始地址:0006,先发高位字节 00,后发低位字节 06
开关个数2个字节00 03对 3 个开关进行遥控,先发高位字节 00,后发低位字节 03
CRC校验码2个字节F5 5208 0F 00 06 00 03的 CRC 校验码

6. 功能码10:写多个寄存器

把数据 -20 写入地址为 5 的寄存器,把-3000 写入地址为 6 的寄存器,把 -300 写入地址为 7 的寄存器:
主机发送数据(HEX):08 10 00 05 00 03 06 FF EC F4 48 FE D4 9C 9B

格式长度数据(HEX)作用
设备地址1个字节08设备地址
功能码1个字节1010:写多个寄存器
起始地址2个字节00 05起始地址:0005,先发高位字节 00,后发低位字节 05
寄存器个数2个字节00 03写入 3 个寄存器的数据
数据字节数1个字节06数据的字节数:6 个字节,包括 3 个寄存器的数据
写入的数据6个字节FF EC F4 48 FE D4因为写入命令是从地址 5 的寄存器开始查询的,写入的第一个寄存器的数据就是地址为 5 的寄存器的数据:
FF EC: 地址为 5 的寄存器的数据 = 0xFFEC,即 -20
F4 48: 地址为 6 的寄存器的数据 = 0xF448,即 -3000
FE D4 地址为 7 的寄存器的数据 = 0xFED4,即 -300
CRC校验码2个字节9C 9B08 10 00 05 00 03 06 FF EC F4 48 FE D4的 CRC 校验码

从机返回数据(HEX):08 10 00 05 00 03 90 90

格式长度数据(HEX)作用
设备地址1个字节08设备地址
功能码1个字节1010:写多个寄存器
起始地址2个字节00 05起始地址:0005,先发高位字节 00,后发低位字节 05
寄存器个数2个字节00 03写入 3 个寄存器的数据
CRC校验码2个字节90 9008 10 00 05 00 03的 CRC 校验码
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

根号五

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值