基于RS485 RTU通讯的电子设备
六遥
遥信(DI或YX):典型应用位长时间触点的闭合断开,如断路器的位置信号
遥测(AI或YC):采集$U$、$I$、$T$等
遥调(AO):应用于变压器调压、无功调节等
遥控(YK或DO):应用于断路器的分合闸,不同于遥信,为短时脉动信号
遥脉:使用脉冲信号向系统发送信息,多用于综自系统电能计量
Modbus-RTU
规约格式附在软件说明书后
Modbus功能码
Modbus 功能码占用一个字节,取值范围是 1~127(即 0x01~0x7F)。同时,使用功能码 + 0x80 表示异常状态,即 129~255 代表异常码。
在 Modbus 标准协议中,一共规定了三类 Modbus 功能码。
- 公共功能码
- 被明确定义的功能码;
- 保证唯一性;
- 由 Modbus 协会确认,并提供公开的文档;
- 可进行一致性测试;
- 包括协议定义的功能码和保留将来使用的功能码。
- 用户自定义功能码
- 有两个用户自定义功能码区域,分别是 65~72 和 100~110;
- 用户自定义,不保证唯一性。
- 保留功能码
- 保留功能码是因为历史遗留原因,某些公司的传统产品上现行使用的功能码不作为公共使用。
部分公用功能码
代码(dec) | 名称 | 英文 | 寄存器 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 | 字操作 | 多个 |
tip:
需要注意,在 Modbus 协议规定的 PDU 中,规定所有线圈或寄存器地址从 0 开始计算。
在0x05中,目标数据(即查询报文中的 ON/OFF 状态)由报文数据字段的常数指定,0xFF00 表示 ON 状态,0x0000 表示 OFF 状态,其余所有值均是非法的。
0x0F:支持广播模式;在广播模式下,所有从站设备的同一地址的值将被统一修改;消息帧中指定了需要变更的线圈起始地址和线圈数目;数据字段中为逻辑 1 的位对应 ON,逻辑 0 的位对应 OFF
0x10:在实际开发中,该功能码常用于方便用户写入多字节类型的数据,例如浮点数值。因此,需要注意字节序问题。
0x08 诊断功能
- 仅用于串行链路,主要用于检测主设备和从设备之间的通信故障,或检测从设备的各种内部故障,不支持广播。
- 查询报文中需要指定从设备地址、功能码(Modbus Command)以及子功能码(Diagnostic Sub-function)。其中,子功能码字段为 2 个字节,用于区别各诊断类型。
- 在正常的响应报文中,从设备将原样回复功能码和子功能码。
- modbus中线圈(coil)和寄存器(register)的概念主要起源于PLC,在 PLC 应用领域,一个线圈就代表一个 PLC 输出点,也称为输出继电器。通过控制线圈导通与否来改变继电器输出状态,实现弱电控制强电。但实际上,在如今的 Modbus 设备中,它们都只是对应一块内存区域而已。其中,线圈代表位操作(bit),表示一个布尔变量;寄存器代表字操作(word),表示一个整型变量(当然也可以通过多个字的组合,表示浮点数以及其他复合数据结构)。
常用的 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) |
0x11 报告从站 ID
- 该功能码仅适用于串行链路,用于读取从站设备的 ID、类型描述、当前状态以及其他信息,不支持广播模式。
- 查询报文中没有数据字段。
- 响应消息的构成由从站设备决定。
寄存器种类 | 含义 | PLC | 示例 |
---|---|---|---|
线圈状态 (Coil Status) | 输出端口(可读可写) | DO(数字量输出) | 电磁阀输出、LED 显示、遥控 |
离散输入状态 (Input Status) | 输入端口(只读) | DI(数字量输入) | 拨码开关、微动开关、遥信 |
保持寄存器 (Holding Register) | 输出参数(可读可写) | AO(模拟量输出) | PID 运行参数、阈值上下限、定值参数、时间等 |
输入寄存器 (Input Register) | 输入参数(只读) | AI(模拟量输入) | 传感器数据输入、遥测 |
Modbus 异常响应
异常响应
通常来说,在 Modbus 主设备(客户端)和从设备(服务器)的通信过程中,存在以下 4 种处理反馈:
- 正常接收,正常处理,返回正常响应报文。
- 因为通信错误等原因,造成从站设备没有接收到查询报文,主站设备将按超时处理。
- 从站设备接收到查询报文,但报文存在错误(例如 LRC、CRC 错误等),从站设备将丢弃报文不响应,主站设备将按超时处理。
- 从站设备接收到正确的报文,但是超过处理范围(例如不存在的功能码或者寄存器等),从站设备将按返回包含异常码(Exception Code)的响应报文。
异常功能码
异常响应报文由从站地址、功能码以及异常码构成。其中,功能码与正常响应报文不同,在异常响应报文中,功能码最高位(即 MSB)被设置为 1。
因为 Modbus 协议中功能码占用一个字节,因此可以用如下表达式描述正常功能码和异常功能码的关系:
|
|
异常帧
与正常报文类似,从设备给主设备回复的异常报文也包含 4 个域:
域 | 定义 | 大小(RTU 格式) | 描述 |
---|---|---|---|
1 | 从设备号(地址) | 1 个字节 | 从设备的唯一地址,1-247 |
2 | 异常功能码 | 1 个字节 | 请求功能码 + 128(0x80) |
3 | 异常数据 | n 个字节 | 异常码(看下面说明) |
4 | 校验和 | 2 个字节 | CRC 校验和(ASCII 为 LRC) |
异常数据域通常存放异常码,至于返回什么异常码则依赖于此次通信发生了何种错误。
下表列出了 Modbus 协议中常见的异常码。
异常码 | 名称 | 描述 |
---|---|---|
01 (0x01) | 非法功能码 | 从站设备不支持此功能码。 |
02 (0x02) | 非法数据地址 | 指定的数据地址在从站设备中不存在。 |
03 (0x03) | 非法数据值 | 指定的数据超过范围或者不允许使用。 |
04 (0x04) | 从站设备故障 | 从站设备处理响应的过程中,出现未知错误等。 |
05 (0x05) | 确认 | 从站设备已经接受请求,并且正在处理这个请求,但是需要长持续时间进行这些操作,返回这个响应防止在客户机(或主站)中发生超时错误,客户机(或主机)可以继续发送轮询程序完成报文来确认是否完成处理。 |
06 (0x06) | 从站设备忙 | 从站设备正在处理长持续时间的程序命令。 |
07 (0x07) | 否定确认 | 从站设备无法执行主站设备发送的请求。 |
08 (0x08) | 存储奇偶性差错 | 指示扩展文件区不能通过一致性校验。 |
10 (0x0A) | 不可用的网关路径 | 与网关一起使用,指示网关不能为处理请求分配输入端口值输出端口的内部通信路径。通常意味着网关是错误配置的或过载的。 |
11 (0x0B) | 网关目标设备响应失败 | 与网关一起使用,指示没有从目标设备中获得响应,通常意味着设备未在网络中。 |
PLC寄存器地址分配
寄存器种类 | 寄存器PLC地址 | 寄存器Modbus协议地址 | 简称 |
---|---|---|---|
线圈状态 | 00001~09999 | 0000H~FFFFH | 0x |
离散输入状态 | 10001~19999 | 0000H~FFFFH | 1x |
保持寄存器 | 40001~49999 | 0000H~FFFFH | 4x |
输入寄存器 | 30001~39999 | 0000H~FFFFH | 3x |
专业术语
在 Modbus 开发中的常见专业术语如下:
- Master /Client :主(站)设备/客户端
- Slave /Server:从(站)设备/服务器端
- ADU :应用数据单元(Application Data Unit)
- PDU :协议数据单元(Protocol Data Unit)
- MSB :最高有效位(Most Significant Bit)
- LSB :最低有效位(Least Significant Bit)
- MBAP :Modbus 应用协议(Modbus Application Protocol)
- PLC :可编程逻辑控制器(Programmable Logic Controller)
- RTU :远程终端单元(Remote Terminal Unit)
- SCADA :监督控制和数据采集(Supervisory Control And Data Acquisition)
Modbus开发环境
- mudbus poll
- modbus slave
- VSPD