Java Modbus通信实战(二):Modbus通信协议深度剖析

举报
Yeats_Liao 发表于 2025/11/25 13:16:20 2025/11/25
【摘要】 在上一篇文章中,我们了解了 Modbus 协议的基础知识。这次我们深入探讨 Modbus 的核心内容:数据模型、消息结构和错误处理机制。通过具体的实例和详细的分析,帮助大家真正掌握 Modbus 协议的实际应用。 1. 数据模型详解 1.1 离散量输入离散量输入用于表示开关状态、传感器状态等二进制信号,每个离散量输入占 1 位。在工业生产车间中,通常有多个用于检测设备运行状态的开关传感器。以...

在上一篇文章中,我们了解了 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 2345 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 主站处理方式

主站接收到异常响应后,会根据异常功能码和错误代码判断错误类型并采取相应措施。

错误处理策略:

  1. 错误记录:记录错误信息,向操作人员报告具体错误原因

    • 错误代码 0x02:“请求的寄存器地址超出范围”
    • 错误代码 0x03:“写入数据值超出允许范围”
  2. 重试机制:针对临时性错误设置重试策略

    • 错误代码 0x06(从站忙):等待一段时间后重新发送请求,最多重试 3 次
    • 错误代码 0x05(确认):延长等待时间,继续监听响应

3.4 错误检测机制

3.4.1 CRC 校验(RTU 模式)

在 RTU 模式下,每帧消息都包含一个 16 位的循环冗余校验码(CRC)。

校验过程:

  1. 发送方计算消息的 CRC 值并附加到消息末尾
  2. 接收方重新计算接收消息的 CRC 值
  3. 比较接收到的 CRC 值与计算出的 CRC 值
  4. 若两者不相等,则表示消息在传输过程中发生错误

实例:

  • 主站发送消息:01 03 00 00 00 02 AB CD
  • 从站接收后计算 CRC 值
  • 若计算结果与接收到的 AB CD 不一致,从站认为消息有误,不进行后续处理

3.4.2 LRC 校验(ASCII 模式)

在 ASCII 模式下,使用纵向冗余校验(LRC)来检测消息错误。

校验算法:

  1. 对消息中除起始符、结束符和校验码之外的所有字符进行求和
  2. 取求和结果的补码作为校验码
  3. 接收方按相同算法计算并比较校验码

实例:

  • 主站发送消息::010300000002AB\r\n
  • 从站接收后计算 LRC 值
  • 若与接收到的 AB 不一致,判定消息有误

4. 总结

通过本文的详细分析,我们深入了解了 Modbus 协议的核心机制:

数据模型:四种数据类型各有用途,为不同的工业应用场景提供了灵活的数据表示方式。

消息结构:RTU 和 ASCII 两种模式各有特点,RTU 模式传输效率高,ASCII 模式可读性好。

错误处理:完善的错误检测和处理机制确保了通信的可靠性,为工业应用提供了稳定的数据传输保障。

掌握这些核心概念后,我们就可以在实际项目中正确使用 Modbus 协议,实现可靠的工业设备通信。
下一篇文章将介绍如何在 Java 中实现 Modbus 通信的具体编程技术。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。