hey-girl东拼西凑原创文章,若有歧义可留言,若需转载需标明出处
前言: 本篇主要针对modbus4种操作的数据对象进行详解。针对不同的功能码结合实际报文案例进行分析。若是新手,请先读之前的文章,在转到这篇。
以下案例来自书籍《modbus软件开发实战指南》中部分摘取,作为个人学习理解。
功能码01(读线圈状态)
- 概念:读取从设备的线圈状态
- 查询报文
查从设备地址为3,并读取从设备的Modbus地址00019-00055(线圈地址)。共计37个状态值。起始线圈地址0x13(即十进制的00019)。线圈地址是从0开始计数。
RTU:03 01 00 13 00 25 CRC - 响应报文
我们查的是37个线圈的状态。在响应的数据中。每个线圈占用1bit。状态被表示1=ON ,0=OFF。第一个数据字节的最低有效位,标识查询报文中的起始线圈的状态值。其他线圈以此类推,一直到这个数据的最高有效位。并在后续的字节中按照同样的方式由低到高排列。
也就是说在本例中。37个状态,8位一字节表示,需要5个字节保存状态。不能填满就补0。
比如20-27这一部分的状态ON-ON-OFF-ON-OFF-ON-OFF,等价11001010。二进制表示为01010011,16进制为0x53.
那下图4-3就很好理解了。数据1 一个字节(16进制)表示就是 8个线圈状态了
功能码02(读离散量输入值)
- 概念:读取从设备的离散量输入的on/off状态
- 查询报文
查从设备地址为3,读取从设备的离散,输入寄存器中的地址10101-10120。modbus地址十进制表示100-199。共计20个离散输入状态值。如果是RTU得模式报文应该就是 03(设备地址) 02(功能码) 00(起始地址高位) 64(低位) 00(寄存器数高位) 14(寄存器数低位) CRC。0x64就是十进制100
- 响应报文
RTU的情况:
03地址 02功能码 03数据域的字节数(就是数据占多少字节)
0x53 8bit(01010011),每一位代表一个状态1=on 0=off。这里取20个离散状态。也就是3个字节可以装下。和前面一样补0
功能码03(读取保持寄存器值)
- 概念:读取从设备保持寄存器的内容,不支持广播模式。消息帧必须指定要读取的寄存器开始地址和寄存器数量。
- 查询报文
查询从设备地址为7,读的保持寄存器起始地址40201-40203一共3个寄存器的内容。也就是对应modbus协议地址200-202的内容。
- 响应报文
保持寄存器以字(word)为单位,前面文章也说到过1word=2byte。上面的查询报文我发的是连续读3个寄存器内容。将返回6个字节。注意保持寄存器中各地址的具体内容和意义,是设备开发者定的。我理解就是这里响应的数据代表什么含义。需要和产品对接。
功能码04(读取输入寄存器值)
- 概念:读取输入寄存器值,不支持广播模式。消息帧中需要定义寄存器的起始地址和数量
- 查询报文
读从设备地址为7,输入寄存器地址30301-30302。共3个寄存器地址。即读取modbus协议地址300-302的内容。报文如下:
- 响应报文
也是以字为单位,连续读3个。就是6个字节
功能码05(写单个线圈或单个离散线圈)
-
概念:用于将单个线圈寄存器或离散输入设置为ON或者OFF,之前的操作都是读,这个是写的操作。支持广播模式。广播模式就是批量改。0XFF00表示ON,0X0000表示OFF。其他的值都是非法。并且对寄存器不起作用,并且返回异常响应
-
查询报文
查询报文必须有:从设备地址,需要操作的线圈的地址、要修改的值。就理解成edit操作。线圈地址从0开始计数。
例:从设备地址为3,设置线圈地址00150为ON状态。则线圈地址为0x95(十进制的149)
-
响应报文
针对修改的结果进行响应。成功会返回和查询报文一样的报文。失败会异常。(异常情况单独在说,这里只反映成功)
功能码06(写单个保持寄存器)
- 概念:修改单个保持寄存器的值。支持广播,也就是批量改
- 查询报文
一样的,需要改谁,改哪里,改啥样。
例:从设备地址为3,设置寄存器地址40150为1200(hex 0x04b0),即modbus地址0x95(十进制的149)
- 响应报文
和之前写线圈一样,成功就返回一样的报文,失败就异常。这里就不贴了
功能码08(诊断功能)
- 概念:只用于串行链路(个人理解就是tcp不适用),主要就是检测主从设备之间的通信故障,或者检测从设备的各种内部故障。不支持广播。为了区别诊断类型。查询报文中提供2个字节的子功能码字段。
- 时间有限这块内容,推荐看书了解。
功能码15(写多个线圈)
-
概念: 就是一次设置 多个连续的的线圈或者离散输出。设置为ON或者OFF.支持广播(也就是一次改多个从设备)
-
查询报文
从站地址为5,需要设置的线圈地址为20-30,值在下表
-
响应报文
成功返回写入的线圈数量,这里是0x0B(十进制的11)
功能码16(写多个保持寄存器)
-
概念:设置从设备保持寄存器的多个连续的地址块(1-123个寄存器)。支持广播模式
-
查询报文
包含了请求数据字段。各数据按每个寄存器2个字节来存放(word)
例:从站地址为5,将保持寄存器地址40020-40022设置为下表的值。
-
响应报文
关于异常功能码,可以参考这位作者大大写的文章异常码