10.5.11
(0x0F)写多个线圈
1. 功能说明
15功能码用于将连续的多个线圈或离散输出设置为ON/OFF状态,支持广播模式,在广播模式下,所有从站设备的同一地址的值将被统一修改。15功能码中,起始地址字段由2字节构成,取值范围为0x00000xFFFF:而寄存器数量字段由2字节构成,取值范用为0x00010x07B0。
2. 查询报文
查询报文中包含请求数据字段,用于定义ON或OFF状态。数据字段中为逻辑1的位对应ON;逻辑0的位对应OFF。其中,ON/OFF与数据字段的对应关系可参考前面的童节“01(0x01)读取线圈,离散量输出状态(Read Coil status/DOs)”中的内容举例说明,假设从站设备地址为5,需要设置线圈地址20~30的状态如下表所示。
线圈状态:
那么,写入的数据字段被划分为2字节,值分别为0xD1,对应于27~20的线圈,值0x05对应于30~28的线圈,注意细体会其中的高低位的对应关系。需要注意的是,在查询报文中,Modbus协议的起始地址为19(0x13),即比线圈起始地址20少1。如下表所示,其中字节数字段表示需要变更数据的字节总数。
功能码15查询报文示例:
字段 | 例 (Hex) | ASCII 模式字符型 | RTU模式8位 (Hex) |
帧头 | “:” | ||
从设备地址 | 0x05 | “0”,“5” | 0x05 |
功能码 | 0x0F | “0”,“F” | 0x0F |
起始地址 (高位) | 0x00 | “0”,“0” | 0x00 |
起始地址 (低位) | 0x13 | “1”,“3” | 0x13 |
寄存器数 (高位) | 0x00 | “0”,“0” | 0x00 |
寄存器数 (低位) | 0x0B | “0”,“B” | 0x08 |
字节数 | 0x02 | “0”,“2” | 0x02 |
变更数据 (高位) | 0xD1 | “D”,“1” | 0xD1 |
变更数据 (低位) | 0x05 | “0”,“5” | 0x05 |
差错校验 | LRC(2字符) | CRC(2字节) | |
帧尾 | CR/LF | ||
合计字节数 | 23 | 11 |
3. 响应报文
对于从设备,在正常情况下,响应报文包括功能码、起始地址以及写入的线圈数量,如下表所示。
功能码15响应报文示例:
字段 | 例 (Hex) | ASCII 模式字符型 | RTU模式8位 (Hex) |
帧头 | “:” | ||
从设备地址 | 0x05 | “0”,“5” | 0x05 |
功能码 | 0x0F | “0”,“F” | 0x0F |
起始地址 (高位) | 0x00 | “0”,“0” | 0x00 |
起始地址 (低位) | 0x13 | “1”,“3” | 0x13 |
寄存器数 (高位) | 0x00 | “0”,“0” | 0x00 |
寄存器数 (低位) | 0x0B | “0”,“B” | 0x08 |
差错校验 | LRC(2字符) | CRC(2字节) | |
帧尾 | CR/LF | ||
合计字节数 | 17 | 8 |
10.5.12
(0x10)写多个保持寄存器
1. 功能说明
16功能码用于设置或写入从设备保持寄存器的多个连续的地址块(1~123个寄存器),支持广播模式,在广播模式下,所有从站设备的同一地址的值将被统一修改。本功能码中,起始地址字段由2字节构成,取值范围为0x0000~0xFFFF;而寄存器数量字段由2字节构成,取值范围为0x0001~0x007B。
2. 查询报文
查询报文包含请求数据字段。数据字段保存需要写入的数值,各数据按每个寄存器2字节存放。举例说明,从站设备地址为5,需要将保持寄存器地址40020~40022设置为如下表所示的数值。
寄存器的设置:
寄存器地址 | 设定值 | 寄存器地址 | 设定值 |
40020 | 0X0155 | 40022 | 0x0157 |
40021 | 0x0156 | — | — |
对应于40020~40022的寄存器,注意仔细体会其中的高低位的对应关系。需要注意的是,在查询报文中,Modbus协议的起始地址为19(0x13),即比寄存器起始地址20少1。如下表所示,其中字节数字段表示需要变更数据的字节总数。
功能码16查询报文示例:
字段 | 例 (Hex) | ASCII 模式字符型 | RTU模式8位 (Hex) |
帧头 | “:” | ||
从设备地址 | 0x05 | “0”,“5” | 0x05 |
功能码 | 0x10 | “0”,“F” | 0x0F |
起始地址 (高位) | 0x00 | “0”,“0” | 0x00 |
起始地址 (低位) | 0x13 | “1”,“3” | 0x13 |
寄存器数 (高位) | 0x00 | “0”,“0” | 0x00 |
寄存器数 (低位) | 0x03 | “0”,“B” | 0x08 |
字节数 | 0x06 | “0”,“6” | 0x06 |
变更数据1 (高位) | 0x01 | “0”,“1” | 0x01 |
变更数据1 (低位) | 0x55 | “5”,“5” | 0x56 |
变更数据2 (高位) | 0x01 | “0”,“1” | 0x01 |
变更数据2 (低位) | 0x56 | “5”,“6” | 0x56 |
变更数据3 (高位) | 0x01 | “0”,“1” | 0x01 |
变更数据3 (低位) | 0x57 | “5”,“7” | 0x57 |
差错校验 | LRC(2字符) | CRC(2字节) | |
帧尾 | CR/LF | ||
合计字节数 | 31 | 15 |
3. 响应报文
对于从设备,在正常情况下,响应报文包括功能码、起始地址及写入的寄存器数量,如下表所示。
功能码16响应报文示例:
字段 | 例 (Hex) | ASCII 模式字符型 | RTU模式8位 (Hex) |
帧头 | “:” | ||
从设备地址 | 0x05 | “0”,“5” | 0x05 |
功能码 | 0x10 | “1”,“0” | 0x10 |
起始地址 (高位) | 0x00 | “0”,“0” | 0x00 |
起始地址 (低位) | 0x13 | “1”,“3” | 0x13 |
寄存器数 (高位) | 0x00 | “0”,“0” | 0x00 |
寄存器数 (低位) | 0x03 | “0”,“3” | 0x03 |
差错校验 | LRC(2字符) | CRC(2字节) | |
帧尾 | CR/LF | ||
合计字节数 | 17 | 8 |
在实际开发过程中,功能码“16(0x10)写多个寄存器(Preset Multiple Registers)”通常用于方便用户写入多字节类型的数据。
例如,假设从站设备地址为5,需要向保持寄存器写入一个32位(4字节)的浮点数,那么此浮点数将占用2个寄存器地址。假设浮点数将存放在40001和40002寄存器中,设定值为1.235(即0x3F9E 147A)实际的查询和响应报文如下(其中标记部分为设定的浮点数值,假设字节序为AB-CD,参考第5.3.7章字节序和大小端的内容)。
查询报文:05 10 00 00 00 02 04 3F 9E 14 7A 05 86
响应报文:05 10 00 00 00 02 40 4C
对于64位(8字节)的双精度浮点数,同理将占用4个寄存器地址共8字节的空间。特别需要注意的是字节序及大小端的问题,前面讨论过多字节存在大小端问题,因此主站设备和从站设备必须保持一致的规则处理,约定Modbus传输中的数据字段的字节序,否则会因为大小端不一致而产生数据处理错误。
如您在使用瑞萨MCU/MPU产品中有任何问题,可识别下方二维码或复制网址到浏览器中打开,进入瑞萨技术论坛寻找答案或获取在线技术支持。
https://community-ja.renesas.com/zh/forums-groups/mcu-mpu/
未完待续
推荐阅读
Moubus功能码详解 - RZ MPU工业控制教程连载(30)
读取保持寄存器值 - RZ MPU工业控制教程连载(31)
写单个线圈与单个保持寄存器相关 - RZ MPU工业控制教程连载(32)