What is Modbus RTU protocol?
Slave address 0x01, hold register start address 0x0032, read 2 hold registers
它已被广泛接受并广泛用于 建筑管理系统 的建设 (BMS) 和工业自动化系统(IAS)。 它的易用性,可靠性以及它是开源的,并且可以在任何设备或应用程序中免费使用。
该协议由Modicon®于1979年开发和发布,用于其可编程逻辑控制器。 它使用主/从架构构建,并支持使用RS232 / RS485 / RS422协议的串行设备。 Modbus通常用于多个仪器和控制设备将信号传输到中央控制器或系统以收集和分析数据的情况。 工业自动化和监督控制和数据采集 (SCADA) 系统通常采用Modbus协议。
Modbus RTU代表什么?
Modbus RTU(远程终端单元)是原始Modbus规范中定义的两种传输模式之一。 这两种模式是Modbus RTU和ASCII,它们都设计用于支持RS232,RS485和RS422协议的串行设备。 Modbus RTU的一个显着特点是它使用二进制编码和强大的CRC错误检查。 Modbus RTU是Modbus协议的实现,最常用于工业应用和自动化生产设施。
Modbus RTU如何工作?
Modbus协议基本上是一个处理来自电子设备的请求和响应的系统。 主/从体系结构与主设备请求一起使用,这些请求由从设备响应。
什么是Modbus RTU主站?
Modbus RTU主站是从连接的从站设备请求信息的中央设备。 自动化生产系统中的中央控制器可以扮演Modbus RTU主站的角色。 Modbus实现有一个主服务器。 主设备从从设备获取信息,也可以写入从设备的寄存器。
什么是Modbus RTU从站?
Modbus RTU从站是响应主设备请求的设备。 它无法启动信息传输,并且在响应主服务器发出的请求之前处于保持模式。
Modbus协议的核心是被称为的组件 协议数据单元 (PDU). PDU由功能代码和数据组成,无论使用何种Modbus传输模式,都可以一致地构建。 功能代码指定主站请求的数据。
在Modbus RTU传输模式中,附加信息包裹在PDU周围以创建完整的应用数据单元(ADU)。 在信号流中和功能代码之前,在Modbus RTU模式下,发送1字节的从ID以识别应满足请求的从设备。 附加到PDU的是2字节CRC,确保发送和接收正确数量的字节。
Modbus设备支持四个数据表,用于促进设备之间的通信。 它们是离散输入,离散输出(线圈),输入寄存器和保持寄存器。 寄存器执行不同的功能,并不是每个设备都包含在内。 在某些情况下,只有保持寄存器用于I / O功能。
| 领域 | 访问 | 尺寸 | 描述 |
|---|---|---|---|
| 离散输入 | 只读 | 1位 | 用作输入 |
| 线圈输出 | 读/写 | 1位 | 用于控制离散 |
| 输入寄存器 | 只读 | 16位 | 用于输入 |
| 持有寄存器 | 读/写 | 16位 | 用于各种事物,包括输入,输出,配置数据等。 |
功能代码指示主设备如何与从设备ID中指定的从设备进行交互。 根据发送的功能代码,主设备可以读取从机的一个寄存器,或写入它们。
当从站接收到包含请求中的错误的数据包时,它们会返回错误代码。 对于诸如非法功能请求,指定从站无法访问的非法寄存器地址以及指示从设备忙或已经发生故障的消息等问题,将返回错误代码。
Modbus RTU要求您在启动通信时知道或定义波特率,字符格式(8位无奇偶校验等)和从站ID等参数。 任何这些参数不匹配都会导致您的通信尝试失败。
下面让我们详细解释一下Modbus RTU数据报文:
帧结构
帧结构 = 地址 + 功能吗 + 数据 + 校验
地址: 占用一个字节,范围0-255,其中有效范围是1-247,其他有特殊用途,比如255是广播地址(广播地址就是应答所有地址,正常的需要两个设备的地址一样才能进行查询和回复)。
功能码:占用一个字节,功能码的意义就是,知道这个指令是干啥的,比如你可以查询从机的数据,也可以修改数据,所以不同功能码对应不同功能。
数据:根据功能码不同,有不同结构,在后续的实例中有说明。
校验:为了保证数据不错误,增加这个,然后再把前面的数据进行计算看数据是否一致,如果一致,就说明这帧数据是正确的,我再回复;如果不一样,说明你这个数据在传输的时候出了问题,数据不对的,所以就抛弃了。
下面通过功能码03和06解释详细解释一下:
功能码0x03(读)
Host sends: 01 03 00 00 00 01 84 0A
Reply from the machine: 01 03 02 19 98 B2 7E
那么这一组数据是什么意思呢?
从上面的结构图中,可以看出,主机发送的数据大致是 地址+功能码+数据+校验;
所以解析如下:
发送数据解析

01 - address,That's the address of your sensor
03 - function code,03Representative query function,Query sensor data
00 00 - Representing the starting register address of the query.Explanation from 0x0000Start Query。Here we need to clarify the following:,ModbusStore data in registers,Retrieve the values of different variables by querying registers,One register address corresponds to 2-byte data
00 01 - Representative queried a register.Combining with the previous 00 00,The meaning is to query 1 register value starting from 0
84 0A - Cyclic redundancy check,ismodbusThe verification formula,Starting from the first byte until before 84;回复数据解析

01 - address,That's the address of your sensor
03 - Function code,03Representative query function,Query sensor data。What should be noted here is what the function code sent to the slave is,You need to reply with the same function code from the machine,If they are different, it means there is an error in this frame of data
02 - The number of bytes representing the subsequent data,Because it was mentioned earlier,A register has 2 bytes,So the number of bytes behind it must be 2*Number of registers queried;
19 98 - The value of the register is 19 98,Based on the data sent, it can be seen that,01The value of this register is 19 98
B2 7E - Cyclic redundancy check
基本流程:
发送:从机的地址+我要干嘛的功能码+我要查的寄存器的地址+我要查的寄存器地址的个数+校验码
回复:从机的地址+主机发我的功能码+要发送给主机数据的字节数+数据+校验码
功能码0x06(写)
如果我要修改从机的数据呢?那么这个协议有吗,答案是Yes!
Host sends: 01 06 00 00 00 01 48 0A
Reply from the machine: 01 06 00 00 00 01 48 0A发送数据解析

01-The slave address that the host wants to query
06-function code,06Representing the modification of a single register function,The modifications are somewhat different,Modifying one register and modifying multiple registers;
00 00-Representing the modified starting register address.Explanation from 0x0000Start.
00 01-The modified value represents 00 01.Combining with the previous 00 00,The meaning is to modify the value of register 0 to 00 01;
48 0A-Cyclic redundancy check,ismodbusThe verification formula,Starting from the first byte until before 48;回复数据解析

01-Return the host's own address from the slave,This indicates that this is the slave machine checked by the host
06-function code,Representing the modification of a single register function,What function code does the host send,What function code must be returned from the machine;
00 00-Representing the modified starting register address.Explanation is 0x0000.
00 01-The modified value represents 00 01.Combining with the previous 00 00,The meaning is to modify the value of register 0 to 00 01;
48 0A-Cyclic redundancy check,ismodbusThe verification formula,Starting from the first byte until before 48;常用功能码详解
常用功能码表格
| 功能码 | 名称 | 数据类型 | 作用 |
|---|---|---|---|
| 0x01 | 读线圈寄存器 | 位 | 取得一组逻辑线圈的当前状态(ON/OFF) |
| 0x02 | 读离散输入寄存器 | 位 | 取得一组开关输入的当前状态(ON/OFF) |
| 0x03 | 读保持寄存器 | 整型、浮点型、字符型 | 在一个或多个保持寄存器中取得当前的二进制值 |
| 0x04 | 读输入寄存器 | 整型、浮点型 | 在一个或多个输入寄存器中取得当前的二进制值 |
| 0x05 | 写单个线圈寄存器 | 位 | 强置一个逻辑线圈的通断状态 |
| 0x06 | 写单个保持寄存器 | 整型、浮点型、字符型 | 把具体二进制值装入一个保持寄存器 |
| 0x0F | 写多个线圈寄存器 | 位 | 强置一串连续逻辑线圈的通断 |
| 0x10 | 写多个保持寄存器 | 整型、浮点型、字符型 | 把具体的二进制值装入一串连续的保持寄存器 |
01H-读线圈状态
1)描述:读从机线圈寄存器,位操作,可读单个或者多个;
2)发送指令:
假设从机地址位0x01,寄存器开始地址0x0023,寄存器结束抵制0x0038,总共读取21个线圈。协议图如下:

3)响应:
返回数据的每一位对应线圈状态,1-ON,0-OFF,如下图;

上表中data1表示0x0023-0x002a的线圈状态,data1的最低位代表最低地址的线圈状态,可以理解为小端模式;
data2表示地址0x002b-0x0033的线圈状态,如下表:

data3表示地址0x0034-0x0038的线圈状态,不够8位,字节高位填充为0,如下表:

02H-读离散输入状态
1):读离散输入寄存器,位操作,可读单个或多个,协议类似功能码0X01协议,此处省;
03H-读保持寄存器
1)描述:读保持寄存器,字节指令操作,可读单个或者多个;
2)发送指令:
从机地址0x01,保持寄存器起始地址0x0032,读2个保持寄存器

3)响应:

数据存储顺序

04H-读输入寄存器
1)描述:读输入寄存器,字节指令操作,可读单个或者多个;
2)发送指令:同03H;
3)响应:同03H;
05H-写单个线圈
1)描述:写单个线圈,位操作,只能写一个,写0xff00表示设置线圈状态为ON,写0x0000表示设置线圈状态为OFF
2)发送指令:
设置0x0032线圈为ON;

3)响应:
同发送指令;
06H-写单个保持寄存器
1)描述:写单个保持寄存器,字节指令操作,只能写一个;
2)发送指令:
写0x0032保持寄存器为0x1232;

3)响应:同发送指令;
0F-写多个线圈
1)描述:写多个线圈寄存器。若数据区的某位值为“1”表示被请求的相应线圈状态为ON,若某位值为“0”,则为状态为OFF。
2)发送指令:
线圈地址为0x04a5,写12个线圈,

上图中DATA1为0x0c,表示:

DATA2为0x02,不够8位,字节高位填充0:

3)响应:

10H-写多个保持寄存器
1)描述:写多个保持寄存器,字节指令操作,可写多个;
2)发送指令:
保持寄存器起始地址为0x0034,写2个寄存器4个字节的数据;

3)响应:

Leave a Reply