Modbus RTU 协议

发布时间 2023-10-07 11:09:48作者: emanlee

Modbus RTU 协议

 

一、简介

MODBUS RTU协议是一种开放的、主要基于串行链路(RS232C或RS485)的通信协议,也有在TCP或者UDP方式下使用这种标准通信协议的,名称中的RTU是英文 "Remote Terminal Unit"的缩写,即"远程终端设备",支持多种电气接口,如RS-232、RS-485等,还可以在各种介质上传送,如双绞线、光纤、无线等,目前,支持Modbus的厂家超过400家,支持Modbus的产品超过600种。

二、主站(Master)和从站(Slave)

在Modbus RTU协议里,通讯的双方被称为“主站”和“从站”。主站会向从站发出查询或者写入命令然后从站被动接收命令然后根据功能码和寄存器号反馈相应的数据结果或者执行写入命令,一个485网络里理论上最多可以挂254个从站,实际应用中考虑线路损耗和干扰一般不会超过100个,否则建议用以太网通讯。

 

三、modbus rtu协议格式

modbus rtu数据帧(ADU)由地址+PDU+校验组成;帧格式简单、紧凑,通俗易懂,用户使用容易,厂商开发简单。

数据格式如下:

 

 

四、寄存器分类

Modbus寄存器分为四种,如表4.1所示:

表4.1 寄存器分类

 

 

五、功能码介绍

Modbus中常用的功能码有8个,可以分为位操作和字操作两类,如表5.1所示:

表5.1 常用功能码

 

 

六、读线圈寄存器(01H)

功能码01H读取Modbus从机中线圈寄存器的状态,可以是单个寄存器,或者多个连续的寄存器。

6.1 发送

假设从机地址为01H,读取的线圈寄存器的起始地址为0017H,读取38个寄存器,指令如表6.1所示:

表6.1 读线圈寄存器指令:

 

6.2 响应

各线圈的状态与数据内容的每个bit对应,1代表ON,0代表OFF。如果查询的线圈数量不是8的倍数,则在最后一个字节的高位补0。

表6.2.1 读线圈状态的返回结果

 

其中,第一个字节CDH对应线圈0017H到001E的状态,转为二进制是11001101,其中bit0对应0017H,bit7对应001E,如表6.2.2所示

表6.2.2 线圈0017H到001EH的状态

 

最后一个字节为1BH,对应线圈0037H到003CH的状态,转为二进制是00011011,其中bit0对应0037H,bit5对应003CH,其余两位用0填充,如表6.2.3所示:

表6.2.3 线圈0037H到003CH的状态

 

7 读离散输入寄存器(02H)

功能码02H读取Modbus从机中离散输入寄存器的状态,可以是单个寄存器,或者多个连续的寄存器。

7.1 发送

假设从机地址为01H,读取的离散输入寄存器的起始地址为00C4H,读取22个寄存器,指令如表7.1所示:

表7.1 读离散输入寄存器指令:

 

7.2 响应

各个离散输入寄存器的状态与数据内容的每个bit对应,1代表ON,0代表OFF。如果查询的线圈数量不是8的倍数,则在最后一个字节的高位补0。

表7.2.1 读离散输入寄存器的返回结果

 

其中,第一个字节ACH对应00C4H到00CBH寄存器的状态,转为二进制是10101100,其中bit0对应00C4H,bit7对应00CB,如表7.2.2所示:

表7.2.2 寄存器00C4H到00CBH的状态

 

最后一个字节为35H,对应寄存器00D4H到00D9H的状态,转为二进制是00110101,其中bit0对应00D4H,bit5对应00D9H,其余两位用0填充,如表7.2.3所示:

表7.2.3 寄存器00D4H到00D9H的状态

 

8 读保持寄存器(03H)

功能码03H读取Modbus从机中保持寄存器的数据,可以是单个寄存器,或者多个连续的寄存器。

8.1 发送

假设从机地址为01H,读取的保持寄存器的起始地址为006BH,读取3个寄存器,指令如表8.1所示:

表8.1 读保持寄存器指令:

 

 01 03 00 00 00 02 c4 0b

 

8.2 响应

每个保持寄存器的长度为2个字节。保持寄存器之间,低地址寄存器先传输,高地址寄存器后传输。单个保持寄存器,高字节数据先传输,低字节数据后传输。

表8.2.1 读保持寄存器的返回结果

 

9 读输入寄存器(04H)

功能码04H读取Modbus从机中输入寄存器的数据,可以是单个寄存器,或者多个连续的寄存器。

9.1 发送

假设从机地址为01H,读取的保持寄存器的起始地址为0008H,读取2个寄存器,指令如表9.1所示:

表9.1 读输入寄存器指令:

 

9.2 响应

每个输入寄存器的长度为2个字节。输入寄存器之间,低地址寄存器先传输,高地址寄存器后传输。单个输入寄存器,高字节数据先传输,低字节数据后传输。

表9.2.1 读输入寄存器的返回结果

 

10 写单个线圈寄存器(05H)

功能码05H写单个线圈寄存器,FF00H请求线圈处于ON状态,0000H请求线圈处于OFF状态。

10.1 发送

假设从机地址为01H,线圈寄存器的地址为00ACH,使其处于ON状态的指令如表10.1所示:

表10.1 写单个线圈指令:

 

10.2 响应

如果写入成功,返回发送的指令,即010500ACFF004C1B。

11 写单个保持寄存器(06H)

功能码06H写单个保持寄存器。

11.1 发送

假设从机地址为01H,保持寄存器的地址为0001H,数据位0003H,指令如表11.1所示:

表11.1 写单个保持寄存器指令:

 

11.2 响应

如果写入成功,返回发送的指令,即010600010003980B。

12 写多个线圈寄存器(0FH)

功能码0FH写多个线圈寄存器。如果对应的数据位为1,表示线圈状态为ON;如果对应的数据位为0,表示线圈状态为OFF。线圈寄存器之间,低地址寄存器先传输,高地址寄存器后传输。单个线圈寄存器,高字节数据先传输,低字节数据后传输。如果写入的线圈寄存器的个数不是8的倍数,则在最后一个字节的高位补0。

12.1 发送

假设从机地址为01H,线圈寄存器的起始地址为0013H,写入10个寄存器,指令如表12.1.1所示:

表12.1.1 写入多个线圈寄存器指令

 

其中,CDH对应线圈0013H到001AH的内容,01H对应线圈001B到001CH的内容,未使用位用0填充。

此时,线圈寄存器的内容如表12.1.2所示:

表12.1.2 线圈寄存器0013H到001CH的内容

 
 

12.2 响应

如果写入成功,返回写入的寄存器数量,如表12.2所示:

表12.2 写多个线圈寄存器的返回结果

 

=================================================================================

modbus功能码定义和样例


modbus完整支持很多功能码,但是实际在应用的时候常用的也就那么几个。具体如下:

  • 0x01: 读线圈寄存器(DO)

  • 0x02: 读离散输入寄存器(DI)

  • 0x03: 读保持寄存器(AI)

  • 0x04: 读输入寄存器(AO)

  • 0x05: 写单个线圈寄存器

  • 0x06: 写单个保持寄存器

  • 0x0f: 写多个线圈寄存器

  • 0x10: 写多个保持寄存器

 

保持寄存器:这个寄存器的单位不再是bit而是两个byte,也就是可以存放具体的数据量的,并且是可读写的。比如我我设置时间年月日,不但可以写也可以读出来现在的时间。写也分为单个写和多个写,所以功能码有对应的三个:0x03 0x06 0x10

“03”保持型寄存器读取

 

=================================================================================

REF

https://baijiahao.baidu.com/s?id=1753063829187804723&wfr=spider&for=pc

https://blog.csdn.net/zhangwen_x/article/details/106918604