Modbus功能码详解
创作时间:
作者:
@小白创作中心
Modbus功能码详解
引用
1
来源
1.
https://www.modbus.cn/27934.html
Modbus功能码是Modbus协议中通信事务处理的基础,主要用于实现主从设备之间的数据读写操作。本文详细介绍了Modbus协议中的各类功能码,包括其分类、具体功能和使用场景。
概述
Modbus功能码占用一个字节,取值范围是1127(即0x010x7F)。同时,使用功能码+0x80表示异常状态,即129~255代表异常码。
在Modbus标准协议中,一共规定了三类Modbus功能码:
- 公共功能码
- 被明确定义的功能码;
- 保证唯一性;
- 由Modbus协会确认,并提供公开的文档;
- 可进行一致性测试;
- 包括协议定义的功能码和保留将来使用的功能码。
- 用户自定义功能码
- 有两个用户自定义功能码区域,分别是6572和100110;
- 用户自定义,不保证唯一性。
- 保留功能码
- 保留功能码是因为历史遗留原因,某些公司的传统产品上现行使用的功能码不作为公共使用。
本教程主要介绍公共功能码,下表展示了Modbus协议中的部分公共功能码。
代码 | 名称 | 英文 | 寄存器 PLC 地址 | 位/字操作 | 操作数量 |
---|---|---|---|---|---|
01 | 读线圈状态 | Read Coils | 00001~09999 | 位操作 | 单个或多个 |
02 | 读离散输入状态 | Read Discrete Inputs | 10001~19999 | 位操作 | 单个或多个 |
03 | 读保持寄存器 | Read Holding Registers | 40001~49999 | 字操作 | 单个或多个 |
04 | 读输入寄存器 | Read Input Registers | 30001~39999 | 字操作 | 单个或多个 |
05 | 写单个线圈 | Write Single Coil | 00001~09999 | 位操作 | 单个 |
06 | 写单个保持寄存器 | Write Single Register | 40001~49999 | 字操作 | 单个 |
15 | 写多个线圈 | Write Multiple Coils | 00001~09999 | 位操作 | 多个 |
16 | 写多个保持寄存器 | Write Multiple Registers | 40001~49999 | 字操作 | 多个 |
功能码的操作可分为两种:
- 位操作——最小单位为一位(bit),包括读线圈状态功能码01、读离散输入状态功能码02、写单个线圈功能码05和写多个线圈功能码15;
- 字操作——最小单位为两个字节,包括读保持寄存器功能码03、读输入寄存器功能码04、写单个保持寄存器功能码06和写多个保持寄存器功能码16。
功能码
0x01 读取线圈/离散量输出值
- 该功能码用于读取从设备的线圈或离散量输出的状态,即各DO(Discrete Output,离散输出)的ON/OFF状态。
- 消息帧中指定了需读取的线圈起始地址和线圈数目。
- 起始地址由2个字节构成,取值范围为0x0000到0xFFFF。
- 线圈数量由2个字节构成,取值范围为0x0001到0x07D0(即十进制1~2000)。
- 需要注意,在Modbus协议规定的PDU中,规定所有线圈或寄存器地址从0开始计算。
0x02 读取离散量输入值
- 该功能码用于读取从设备的离散输入,即DI(Discrete Input)的ON/OFF状态。
- 消息帧中指定了需读取的离散输入寄存器起始地址和数目,可读取1~2000个连续的离散量输入状态。
- 如果从设备接受主设备的请求则回复功能码02,并返回离散量输入各变量的当前状态(如果返回的DI数量不是8的整数倍,将用0填充最后数据字节的剩余位)。
- 起始地址由2个字节构成,取值范围为0x0000到0xFFFF。
- 离散量数量由2个字节构成,取值范围为0x0001到0x07D0(即十进制1~2000),最多一次可读取2000个离散输入状态值。
0x03 读取保持寄存器值
- 该功能码用于读取从设备保持寄存器的内容,不支持广播模式。
- 消息帧中指定了需读取的保持寄存器的起始地址和数目,而保持寄存器中各地址的具体内容和意义则由设备开发者自行规定。
- 起始地址由2个字节构成,取值范围为0x0000到0xFFFF。
- 寄存器数量由2个字节构成,取值范围为0x0001到0x007D(即十进制1~125),最多一次可连续读取125个寄存器值。
- 需要注意,Modbus的保持寄存器和输入寄存器是以字(Word)为基本单位的(1Word等于2Bytes)。因此,在读取时需要注意字节序(大小端)问题。
0x04 读取输入寄存器值
- 该功能码用于读取从设备输入寄存器的内容,不支持广播模式。(与03功能码类似)
- 消息帧中指定了需读取的输入寄存器的起始地址和数目,而输入寄存器中各地址的具体内容和意义则由设备开发者自行规定。
- 起始地址由2个字节构成,取值范围为0x0000到0xFFFF。
- 寄存器数量由2个字节构成,取值范围为0x0001到0x007D(即十进制1~125),最多一次可连续读取125个寄存器值。
- 同样需要注意字节序问题。
0x05 写单个线圈/单个离散输出
- 该功能码用于将单个线圈寄存器(或离散输出)设置为ON或OFF,支持广播模式。
- 在广播模式下,所有从站设备的同一地址的值将被统一修改。
- 消息帧中指定了需要变更的线圈地址和设定的状态值。
- 起始地址由2个字节构成,取值范围为0x0000到0xFFFF。
- 目标数据(即查询报文中的ON/OFF状态)由报文数据字段的常数指定,0xFF00表示ON状态,0x0000表示OFF状态,其余所有值均是非法的。
- 需要注意,在Modbus协议规定的PDU中,规定所有线圈或寄存器地址从0开始计算。
0x06 写单个保持寄存器
- 该功能码用于更新从设备的单个保持寄存器的值,支持广播模式。
- 在广播模式下,所有从站设备的同一地址的值将被统一修改。
- 消息帧中需要指定从设备地址以及需要变更的保持寄存器地址和设定值。
- 起始地址由2个字节构成,取值范围为0x0000到0xFFFF。
- 变更目标数据由2个字节构成,取值范围为0x0000到0xFFFF。
- 保持寄存器以字(Word)为基本单位,写入时需要注意目标数据的字节序问题。
0x08 诊断功能
- 该功能码仅用于串行链路,主要用于检测主设备和从设备之间的通信故障,或检测从设备的各种内部故障,该功能不支持广播。
- 查询报文中需要指定从设备地址、功能码(Modbus Command)以及子功能码(Diagnostic Sub-function)。其中,子功能码字段为2个字节,用于区别各诊断类型。
- 在正常的响应报文中,从设备将原样回复功能码和子功能码。
常用的Modbus诊断子功能码定义如下:
功能码 | 子功能码 | 描述 | 说明 |
---|---|---|---|
08 | 00(0x00) | Return Data Query (Loop-back) | 原样返回查询报文 |
08 | 01(0x01) | Restart Communications | 用于初始化并重新启动从站设备其中,报文字段0x00, 0x00 表示保持事件记录0xFF, 0x00 表示清除事件记录 |
08 | 02(0x02) | Return Diagnostic Register | 返回诊断寄存器内容 |
08 | 03(0x03) | Change ASCII Input Delimiter | |
08 | 04(0x04) | Force Listen Only Mode | 强制被寻址的从站设备进入只听模式使其与网络中的其他设备断开,不返回响应 |
08 | 10(0x0A) | Clear Counters and Diagnostic Registers | 清除计数器和诊断寄存器 |
08 | 11(0x0B) | Return Bus Message Count | 返回总线报文计数值 |
08 | 12(0x0C) | Return Bus Communication Error Count | 返回总线通信CRC出错计数 |
08 | 13(0x0D) | Return Bus Exception Error Count | 返回总线异常计数 |
08 | 14(0x0E) | Return Slave Message Count | 返回从站设备接收的报文数量 |
08 | 15(0x0F) | Return Slave No Response Count | 返回从站设备没有返回响应的报文数量 |
08 | 16(0x10) | Return Slave NAK Count | |
08 | 17(0x11) | Return Slave Busy Count | 返回从站设备响应忙的报文数量 |
08 | 18(0x12) | Return Bus Character Overrun Count | 返回总线字符超限的报文数量 |
08 | 19(0x13) | Return IOP Overrun Count (884) | |
08 | 20(0x14) | Clear Overrun Counter and Flag (884) |
0x0B 获取通信事件计数器
- 该功能码主要用于获取从设备通信计数器中的状态字和事件计数的值,不支持广播模式。
- 可以通过在通信报文之前和之后读取通信事件计数值,来确定从设备是否正常处理报文。
- 对于正常完成报文处理和传输的场合,事件计数器增加1;而对于异常响应、轮询命令或读事件计数器(即0x0B功能码)的场合,则计数器不变。
- 通过0x08诊断功能中的0x01子功能和0x0A子功能,可以复位事件寄存器。
0x0C 获取通信事件记录
- 该功能码主要用于从从设备获取状态字、事件计数、报文计数以及事件字节字段。
- 其中状态字和事件计数与功能码0x0B获取的值一致。
- 报文计数器包含了加电重启、清除计数器之后的报文数量,报文计数与通过0x08诊断功能中的0x0B子功能码获取的值一致。
- 事件字节字段包含0~64个字节,定义各种事件。
- 正常情况下响应报文包括一个2Bytes状态字字段、一个2Bytes事件计数字段、一个2Bytes消息计数字段以及0~64个字节的事件字段。
- 由于事件字段是变长的,因此增加了一个1Byte的数据长度字段,以方便读取响应数据。
0x0F 写多个线圈
- 该功能码用于将连续的多个线圈(或离散输出)设置为ON或OFF,支持广播模式。
- 在广播模式下,所有从站设备的同一地址的值将被统一修改。
- 消息帧中指定了需要变更的线圈起始地址和线圈数目。
- 起始地址由2个字节构成,取值范围为0x0000到0xFFFF。
- 寄存器数量字段由2个字节构成,取值范围为0x0001到0x07B0。
- 数据字段中为逻辑1的位对应ON,逻辑0的位对应OFF。
0x10 写多个保持寄存器
- 该功能码用于设置或写入从设备保持寄存器的多个连续的地址块(1~123个寄存器),支持广播模式。
- 在广播模式下,所有从站设备的同一地址的值将被统一修改。
- 消息帧中需要指定从设备地址以及需要变更的保持寄存器地址和数量。
- 起始地址由2个字节构成,取值范围为0x0000到0xFFFF。
- 寄存器数量字段由2个字节构成,取值范围为0x0001到0x007B(即十进制1~123)。
- 在实际开发中,该功能码常用于方便用户写入多字节类型的数据,例如浮点数值。因此,需要注意字节序问题。
0x11 报告从站 ID
- 该功能码仅适用于串行链路,用于读取从站设备的ID、类型描述、当前状态以及其他信息,不支持广播模式。
- 查询报文中没有数据字段。
- 响应消息的构成由从站设备决定。
总结
常用Modbus公共功能码下表所示。
其中,支持广播模式的功能码有:
- 0x05 写单个线圈
- 0x06 写单个保持寄存器
- 0x0F 写多个线圈
- 0x10 写多个保持寄存器
除了广播模式的报文以外,其他所有查询报文都希望能够获取一个正常的响应报文。如果一切正常,则从站设备将返回一个正常响应报文,该响应报文的功能码与请求报文的功能码一致。
另外,对于字操作的功能码,存在多字节存储的大小端问题,因此主站设备和从站设备必须保持一致的规则处理,约定Modbus传输中的数据字段的字节序。
热门推荐
电竞电脑主机组装性价比高?全面指南与推荐配置
中国十大松子产地,哪个地方产的好?
看吉林小城梅河口,如何创造世界松子传奇!
吉林松子外销入旺季
部分高校研究生宿舍短缺,委员建议统筹回购社会闲置用房
陕西省属高校预算公布,这所大学涨幅最高!
深圳杭州业委会工资管理揭秘:规定与现实的差距
中华麋鹿园:大丰区最美自然景观推荐
银行的存折可以进行跨行取款限额调整吗?
银行的ATM机可以进行哪些操作?
火花塞坏了,你的车还能撑多久?
NGK火花塞选型攻略:让你不再迷茫
嗓子发炎期间,这些食物千万别碰!
冬季防嗓炎,这9招你必须知道!
蜂蜜梨茶:嗓子发炎时的天然良方
冬季护嗓指南:告别喉咙发炎
嗓子发炎,吃梨真的靠谱吗?
葡萄糖酸内酯教你做零失败快速馒头
枸杞咖啡:90后的养生新宠
掼蛋规则详解:同花顺、炸弹、六张的奥秘
手机购新补贴来袭,中国移动带你玩转科技潮
什么是行政复议决定
什么是行政复议决定
汉字“泽”的繁体写法及其文化内涵探讨
汉字“泽”的繁体写法及其文化内涵探讨
泽字有何寓意
中华麋鹿园:大丰区必打卡景点
荷兰花海:大丰区最美自然景观
手机购新补贴引爆换机潮,你准备好了吗?
除了刷牙和漱口水,还有哪些牙齿清洁方法?