什么是Modbus RTU协议?
Modbus RTU协议是一种允许可编程逻辑控制器(PLC)和计算机之间进行数据交换的通信方式。 电子设备可以使用Modbus协议通过串行线路交换信息。
它已被广泛接受并广泛用于 建筑管理系统 的建设 (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(读)
主机发送: 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代表查询功能,查询传感器的数据。这里要注意的是注意发给从机的功能码是啥,从机就要回复同样的功能码,如果不一样说明这一帧数据有错误
02 - 代表后面数据的字节数,因为上面说到,一个寄存器有2个字节,所以后面的字节数肯定是2*查询的寄存器个数;
19 98 - 寄存器的值是19 98,结合发送的数据看出,01这个寄存器的值为19 98
B2 7E - 循环冗余校验
基本流程:
发送:从机的地址+我要干嘛的功能码+我要查的寄存器的地址+我要查的寄存器地址的个数+校验码
回复:从机的地址+主机发我的功能码+要发送给主机数据的字节数+数据+校验码
功能码0x06(写)
如果我要修改从机的数据呢?那么这个协议有吗,答案是Yes!
主机发送: 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前面为止;
常用功能码详解
常用功能码表格
功能码 | 名称 | 数据类型 | 作用 |
---|---|---|---|
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)响应: