
Modbus是一种串行通信协议,是Modicon公司(现在的施耐德电气 Schneider Electric)于1979年为使用可编程逻辑控制器(PLC)通信而发表。Modbus已经成为工业领域通信协议的业界标准(De facto),并且现在是工业电子设备之间常用的连接方式。 一、Modbus-RTU报文格式 ![]() 注:1 个字节由 8 位二进制组成,即 8 bits。 1. 设备地址 设备地址是每次通讯信息帧的第一个字节,从 0 到 255。这个字节表明由用户设置为该地址的设备将接收由主站发过来的此条信息,每个设备必须有一个唯一的地址,只有符合这个地址的设备才能响应主站回送信息。当从机回送信息时,回送数据的第一个字节也是这个设备的地址。 主站发送的数据当中的设备地址表明将要发送到哪个设备,设备返回的数据当中的设备地址表明此数据来自何处。 2. 功能码 功能码是每次通讯的数据的第二个字节,MODBUS 通讯规约可以定义的功能码的范围为 1 到 127,我们仅采用了其中一部分功能码,具体如下: ![]() 3. 数据区 数据区是主站要写给从站的数据和从站回复主站要读的数据。 数据区的内容以 Big Endian 形式储存,通讯时先发高位字节,后发低位字节。 4. CRC校验 CRC校验是16 位循环冗余校验码,主要用来校验传输数据的准确性。 二、功能码详细说明 1. 功能码01:读开关 所有的开关都以二进制位进行编码,每个开关一位,一个字节可以容纳 8 个开关的状态,1 为合状态,0 为分状态。 开关的地址为位编码的,可以理解为地址为 0 的开关在数据区第 1 个字节的 D0 位,地址为 1 的开关在 数据区的第 1 个字节的 D1 位,……地址为 7 的开关在数据区的第 1 个字节的 D7 位,地址为 8 的开关 在数据区的第 2 个字节的 D0 位,地址为 X 的开关,在数据区第 X/8+1 个字节的 D[X%8]位。 主机发送报文格式: ![]() 从机返回数据报文格式: ![]() 2. 功能码03:读寄存器 每个寄存器都是两个字节 (16 位二进制数据),高位字节在前,低位字节在后。每个寄存器表示的数据 范围为-32768 到 32767,负数用补码 (two’s complement) 表示。 寄存器的地址编码,可以理解为地址为 0 的寄存器在数据区的第 1 个和第 2 个字节,地址为 1 的寄存 器在数据区的第 3 个和第 4 个字节,地址为 2 的寄存器在数据区的第 5 个和第 6 个字节…… 主机发送报文格式: ![]() 从机返回数据报文格式: ![]() 3. 功能码05:写单路开关 主机发送报文格式: ![]() 从机返回数据报文格式: 从机返回的报文与主机发送的报文完全相同。 从机返回这个报文,说明装置接受了遥控命令,开始执行命令,判断是否成功的执行完成了要以读开关的状态等于控制的目标值为准,即读出的开关状 态等于写入的开关状态,认为遥控执行成功的完成了。 4. 功能码06:写单个寄存器 主机发送报文格式: ![]() 从机返回数据报文格式: 从机返回的报文与主机发送的报文完全相同。 从机返回这个报文,说明装置接受了写入寄存器的命令, 开始执行命令,判断是否成功的执行完成了写入数据,要以读寄存器的数据等于写入的值为准, 即读出的寄存器数据等于写入的寄存器数据,认为写入执行成功的完成了。 5. 功能码0F:写多路开关 主机发送报文格式: ![]() 从机返回数据报文格式: ![]() 从机返回这个报文,说明装置接受了遥控命令,开始执行命令,判断是否成功的执行完成了要以读开关 的状态 等于控制的目标值为准,即读出的开关状态等于写入的开关状态,认为遥控执行成功的 完成了。 6. 功能码10:写多个寄存器 主机发送报文格式: ![]() 从机返回数据报文格式: ![]() 从机返回这个报文,说明从机接受了遥调命令,开始执行命令,判断是否成功的执行完成了要以读寄存 器的数据等于遥调的目标值为准,即读出的寄存器的数据等于写入寄存器的数据,认为遥调执 行成功的完成了。 三、从机对主机命令的回应 1. 从机对主机的正确命令回应 ![]() 从机的功能码和主机下发的功能码相同。 2. 从机对主机的错误命令回应 ![]() 从机功能码=主机功能码|0x80。 错误编码 ![]() 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----合。 ![]() 从机——寄存器数据 ![]() ![]() 1. 功能码01:读开关 查询地址从4到8的5个开关状态: 主机发送数据(HEX):08 01 00 04 00 05 BD 51 ![]() 从机返回数据(HEX):08 01 01 03 12 15 ![]() 2. 功能码03:读寄存器 查询地址从2到5的4个寄存器数据: 主机发送数据(HEX):08 03 00 02 00 04 E5 50 ![]() 从机返回数据(HEX):08 03 08 00 0A 07 D0 00 C8 00 14 50 DF ![]() 3. 功能码05:写单路开关 对地址为6的开关进行合闸: 主机发送数据(HEX):08 05 00 06 FF 00 6C A2 从机返回数据(HEX):08 05 00 06 FF 00 6C A2 ![]() 对地址为6的开关进行分闸: 主机发送数据(HEX):08 05 00 06 00 00 2D 52 从机返回数据(HEX):08 05 00 06 00 00 2D 52 ![]() 4. 功能码06:写单个寄存器 把数据-30写入地址为8的寄存器: 主机发送数据(HEX):08 06 00 08 FF E2 C9 28 从机返回数据(HEX):08 06 00 08 FF E2 C9 28 ![]() 5. 功能码0F:写多路开关 对地址为 6 的开关进行合闸置1、对地址为 7 的开关进行分闸置0、对地址为 8 的开关进行合闸置1: 主机发送数据(HEX):08 0F 00 06 00 03 01 05 07 3E ![]() 从机返回数据(HEX):08 0F 00 06 00 03 F5 52 ![]() 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):08 10 00 05 00 03 90 90 ![]() |
【2025·STM32峰会】GUI解决方案实训分享5-调通板载的NRF24L01 SPI接口并使用模块进行无线通信(发送和接收)
【2025·STM32峰会】GUI解决方案实训分享2-编译运行TouchGFX咖啡机例程(含桌面仿真)
实战经验 | Keil工程使用NEAI库的异常问题
STM32 ISP IQTune:真正零门槛的免费ISP调整软件
【经验分享】STM32 新建基于STM32F40x 固件库的MDK5 工程
意法半导体MCU双供应链策略,打消中国客户后顾之忧
2024意法半导体工业峰会:赋能智能电源和智能工业,构筑可持续未来
ST推出灵活、面向未来的智能电表通信解决方案,助力能源转型
意法半导体 x Qu-Bit Electronix:推动新一轮的数字声音合成革命
从STM32 MPU产品看嵌入式系统中微处理器的新变化