Java Modbus通信实战(二):Modbus通信协议深度剖析
在上一篇文章中,我们了解了 Modbus 协议的基础知识。
这次我们深入探讨 Modbus 的核心内容:数据模型、消息结构和错误处理机制。
通过具体的实例和详细的分析,帮助大家真正掌握 Modbus 协议的实际应用。
1. 数据模型详解
1.1 离散量输入
离散量输入用于表示开关状态、传感器状态等二进制信号,每个离散量输入占 1 位。
在工业生产车间中,通常有多个用于检测设备运行状态的开关传感器。
以 8 个传感器为例,其状态通过离散量输入寄存器表示:
| 地址 | 状态 |
|---|---|
| 1 | 开(1) |
| 2 | 关(0) |
| 3 | 开(1) |
| 4 | 关(0) |
| 5 | 开(1) |
| 6 | 关(0) |
| 7 | 开(1) |
| 8 | 关(0) |
对应的二进制表示为 10101010。
主站要获取这些设备的运行状态时,会向从站发送读取离散量输入的请求。
1.2 线圈
线圈属于可读写数据,用于控制开关设备的状态,每个线圈占 1 位。
在自动化控制系统中,假设有 4 个继电器分别控制不同设备:
- 初始状态:所有继电器关闭,二进制表示为
0000 - 开启地址 2 的继电器:主站发送写单个线圈命令,二进制表示变为
0010
1.3 输入寄存器
输入寄存器用于读取传感器的测量值、设备的状态参数等,每个输入寄存器占 16 位(2 字节)。
以温度传感器为例:
- 测量环境温度:25.5℃
- 数据转换:根据传感器量程和精度转换为整数 255
- 存储位置:地址 30001 的输入寄存器
- 十六进制表示:
00FF
1.4 保持寄存器
保持寄存器可读写,常用于设置设备参数、控制设备运行状态等,每个保持寄存器占 16 位(2 字节)。
以变频器频率设置为例:
- 频率范围:0 - 50Hz
- 设定频率:30Hz
- 数据转换:根据变频器量程和精度转换为整数 300
- 存储位置:地址 40001 的保持寄存器
- 十六进制表示:
012C
2. 消息结构详解
2.1 RTU 模式消息结构
2.1.1 请求消息
主站向从站发送读取保持寄存器的请求时,消息格式如下:
消息组成:
- 从站地址:
01- 目标从站的地址 - 功能码:
03- 读取保持寄存器操作 - 数据域:
- 起始寄存器地址:
00 00- 从地址 40001 开始读取 - 寄存器数量:
00 02- 读取 2 个寄存器
- 起始寄存器地址:
- 校验码(CRC):
AB CD- 通过 CRC 算法计算得出
完整消息:01 03 00 00 00 02 AB CD
2.1.2 响应消息
从站接收到请求并正常处理后,返回的响应消息如下:
消息组成:
- 从站地址:
01 - 功能码:
03 - 数据域:
- 字节数:
04- 返回 4 个字节的数据 - 寄存器值:
01 23 45 67- 两个寄存器的值分别为01 23和45 67
- 字节数:
- 校验码(CRC):
EF GH
完整消息:01 03 04 01 23 45 67 EF GH
2.2 ASCII 模式消息结构
2.2.1 请求消息
主站发送读取保持寄存器的请求消息格式如下:
消息组成:
- 起始符:
:- 消息开始标识 - 从站地址:
01 - 功能码:
03 - 数据域:
- 起始寄存器地址:
0000 - 寄存器数量:
0002
- 起始寄存器地址:
- 校验码(LRC):
AB - 结束符:
CRLF- 回车换行
完整消息::010300000002AB\r\n
2.2.2 响应消息
从站返回的响应消息如下:
消息组成:
- 起始符:
: - 从站地址:
01 - 功能码:
03 - 数据域:
- 字节数:
04 - 寄存器值:
01234567
- 字节数:
- 校验码(LRC):
CD - 结束符:
CRLF
完整消息::01030401234567CD\r\n
3. 错误处理机制详解
3.1 异常功能码
当从站接收到主站的请求并检测到错误时,会返回与请求功能码对应的异常功能码。
异常功能码计算方式:
- 正常功能码:0x03(读取保持寄存器)
- 异常功能码:0x83(0x03 + 0x80)
3.2 异常响应数据
从站返回的异常响应消息除异常功能码外,还包含一个字节的错误代码,用于明确错误类型。
常见错误代码及实例:
0x01 - 非法功能
主站请求从站执行不支持的功能码。
实例:主站发送功能码 0x1F 要求从站执行特殊操作,但该从站只支持 0x01 - 0x16 功能码,从站返回异常功能码 0x9F 和错误代码 0x01。
0x02 - 非法数据地址
主站请求读取从站中不存在的寄存器地址。
实例:主站请求读取地址 40050 - 40055 的保持寄存器,但从站的保持寄存器地址范围仅为 40001 - 40020,从站返回异常功能码 0x83 和错误代码 0x02。
0x03 - 非法数据值
主站向从站写入的数据值超出寄存器允许范围。
实例:主站要将值 60 写入地址 40001 的保持寄存器,而该寄存器取值范围是 0 - 50,从站返回异常功能码 0x86 和错误代码 0x03。
0x04 - 从站设备故障
从站设备内部出现故障,无法完成请求的操作。
实例:从站存储器损坏,主站发送读取保持寄存器请求时,从站返回异常功能码 0x83 和错误代码 0x04。
0x05 - 确认
从站已接受请求,但需要更多时间来处理,通常用于长时间运行的操作。
实例:主站要求从站进行复杂计算任务,从站返回异常功能码 0x83 和错误代码 0x05,告知主站已接收请求,正在处理中。
0x06 - 从站忙
从站正忙于处理其他任务,暂时无法处理当前请求。
实例:从站正在进行大量数据存储操作,此时主站发送读取离散量输入请求,从站返回异常功能码 0x82 和错误代码 0x06。
0x08 - 存储器奇偶校验错误
从站在访问存储器时检测到奇偶校验错误。
实例:主站请求读取输入寄存器时,从站在读取存储器数据时发现奇偶校验错误,返回异常功能码 0x84 和错误代码 0x08。
0x0A - 网关路径无效
用于 Modbus 网关设备,表示网关无法找到通往目标从站的有效路径。
实例:主站通过网关连接多个从站,当主站向不存在于网关配置中的从站发送请求时,网关返回异常功能码和错误代码 0x0A。
0x0B - 网关目标设备失败
网关成功连接到目标从站,但从站拒绝了请求。
实例:从站设置了访问权限,网关虽能连接到从站,但主站的请求因权限不足被从站拒绝,网关返回异常功能码和错误代码 0x0B。
3.3 主站处理方式
主站接收到异常响应后,会根据异常功能码和错误代码判断错误类型并采取相应措施。
错误处理策略:
-
错误记录:记录错误信息,向操作人员报告具体错误原因
- 错误代码 0x02:“请求的寄存器地址超出范围”
- 错误代码 0x03:“写入数据值超出允许范围”
-
重试机制:针对临时性错误设置重试策略
- 错误代码 0x06(从站忙):等待一段时间后重新发送请求,最多重试 3 次
- 错误代码 0x05(确认):延长等待时间,继续监听响应
3.4 错误检测机制
3.4.1 CRC 校验(RTU 模式)
在 RTU 模式下,每帧消息都包含一个 16 位的循环冗余校验码(CRC)。
校验过程:
- 发送方计算消息的 CRC 值并附加到消息末尾
- 接收方重新计算接收消息的 CRC 值
- 比较接收到的 CRC 值与计算出的 CRC 值
- 若两者不相等,则表示消息在传输过程中发生错误
实例:
- 主站发送消息:
01 03 00 00 00 02 AB CD - 从站接收后计算 CRC 值
- 若计算结果与接收到的
AB CD不一致,从站认为消息有误,不进行后续处理
3.4.2 LRC 校验(ASCII 模式)
在 ASCII 模式下,使用纵向冗余校验(LRC)来检测消息错误。
校验算法:
- 对消息中除起始符、结束符和校验码之外的所有字符进行求和
- 取求和结果的补码作为校验码
- 接收方按相同算法计算并比较校验码
实例:
- 主站发送消息:
:010300000002AB\r\n - 从站接收后计算 LRC 值
- 若与接收到的
AB不一致,判定消息有误
4. 总结
通过本文的详细分析,我们深入了解了 Modbus 协议的核心机制:
数据模型:四种数据类型各有用途,为不同的工业应用场景提供了灵活的数据表示方式。
消息结构:RTU 和 ASCII 两种模式各有特点,RTU 模式传输效率高,ASCII 模式可读性好。
错误处理:完善的错误检测和处理机制确保了通信的可靠性,为工业应用提供了稳定的数据传输保障。
掌握这些核心概念后,我们就可以在实际项目中正确使用 Modbus 协议,实现可靠的工业设备通信。
下一篇文章将介绍如何在 Java 中实现 Modbus 通信的具体编程技术。
- 点赞
- 收藏
- 关注作者
评论(0)