浅谈Modbus协议

Modbus协议介绍

Modbus协议是一种应用层通信协议,最初由Modicon(现为施耐德电气的一部分)在1979年开发,设计用于可编程逻辑控制器(PLC)之间的通信。它是一种工业标准协议,支持多种通信方式,如串行通信(RS-232/RS-485)和以太网通信(Modbus TCP/IP)。以下是对Modbus协议的详细介绍:

一、Modbus协议基本概念
  1. 通信模式
    • 主从模式(Master-Slave):单个主机(Master)可以与多个从设备(Slave)通信。
    • 请求-响应模式:主设备发送请求,从设备返回响应。
  2. 数据表示
    • 数据以二进制字节流的形式传输。
    • 支持以下基本数据类型:
      • 单位数值:16位寄存器(通常为无符号整型)。
      • 布尔值:单个位。
      • 扩展数据:通过多个寄存器组合实现浮点数、长整型等。
  3. 地址范围
    • 每个从设备有一个唯一地址(通常为1-247)。
    • 主机通过从设备地址定位通信对象。
二、Modbus协议的功能码(Function Codes)

Modbus协议通过功能码指定操作类型,常见功能码包括:

  1. 读操作
    • 01:读取线圈(Coils)状态。
    • 02:读取离散输入(Discrete Inputs)状态。
    • 03:读取保持寄存器(Holding Registers)。
    • 04:读取输入寄存器(Input Registers)。
  2. 写操作
    • 05:写单个位(线圈)。
    • 06:写单个寄存器。
    • 15:写多个位(线圈)。
    • 16:写多个寄存器。
  3. 诊断操作
    • 08:诊断功能,如回环测试(Loopback Test)。
三、Modbus协议的帧结构

Modbus协议的帧结构根据通信方式不同,主要分为Modbus RTUModbus TCP/IP两种。

1. Modbus RTU帧结构

Modbus RTU是基于串行通信的方式,数据格式紧凑,高效。

  • 帧结构:字段长度 (字节)描述从站地址1标识目标设备的地址。功能码1指示执行的操作类型。数据字段N操作相关的具体数据,长度由功能码决定。校验码(CRC)2用于错误检测的循环冗余校验码。
  • 特点
    • 数据帧之间通过时间间隔区分。
    • CRC校验增强了通信的可靠性。
2. Modbus TCP/IP帧结构

Modbus TCP/IP基于以太网通信,数据传输速度更快,适用于现代网络环境。

  • 帧结构:字段长度 (字节)描述事务标识符2标识请求和响应的匹配关系。协议标识符2固定为0x0000,表示Modbus协议。长度字段2表示后续数据的总长度(字节数)。单元标识符1对应Modbus RTU中的从站地址。功能码1操作类型。数据字段N操作相关数据。
  • 特点
    • 取消了CRC校验,依赖TCP/IP的错误检测机制。
    • 可实现远程通信,无需传统串行网络限制。
四、Modbus寄存器与数据模型

Modbus协议将设备的内部数据分为以下四种数据类型,每种类型有独立的地址空间:

  1. 线圈(Coils)
    • 类型:读写。
    • 数据内容:单个位。
    • 地址范围:0000109999
  2. 离散输入(Discrete Inputs)
    • 类型:只读。
    • 数据内容:单个位。
    • 地址范围:1000119999
  3. 输入寄存器(Input Registers)
    • 类型:只读。
    • 数据内容:16位整数。
    • 地址范围:3000139999
  4. 保持寄存器(Holding Registers)
    • 类型:读写。
    • 数据内容:16位整数。
    • 地址范围:4000149999
五、Modbus的优缺点
1. 优点
  • 简单易用:结构清晰,易于实现和调试。
  • 兼容性强:广泛支持于工业设备。
  • 灵活性高:支持多种通信方式(RTU/ASCII/TCP)。
  • 可靠性高:RTU模式通过CRC确保数据完整性。
2. 缺点
  • 无安全性:缺乏身份验证和加密,易受攻击。
  • 带宽限制:Modbus RTU数据帧短,适合低速通信。
  • 地址空间有限:支持的设备地址较少。
六、Modbus的应用场景
  1. 工业自动化
    • PLC与传感器之间的数据采集和控制。
    • HMI与PLC之间的通信。
  2. 能源管理
    • 智能电表的远程抄表。
    • 电力系统的状态监测。
  3. 楼宇自动化
    • 空调、照明系统的集中控制。
    • 电梯运行状态监控。
  4. 远程监控
    • 石油管道压力监测。
    • 农业灌溉系统自动化控制。
七、Modbus协议的扩展与改进
  1. Modbus Plus
    • 提高了通信速率,支持多主设备网络。
  2. Modbus TCP/IP
    • 扩展到以太网环境,支持Internet远程通信。
  3. Modbus Secure
    • 提供基于TLS/SSL的安全通信。

Modbus数据包完整解释示例

下面以**Modbus RTU协议读取保持寄存器(Holding Registers)**的请求和响应为例,完整解析数据包的各个部分。

场景假设
  1. 主设备请求从设备地址 1
  2. 请求读取从地址 40001 对应的保持寄存器起始地址(实际地址 0000),读取 2 个寄存器(即 4 个字节)。
  3. 从设备返回对应的数据。
1. Modbus RTU 请求帧结构解析

请求数据包

字段数据长度 (字节)说明
从站地址0x011指定目标设备地址为 1。
功能码0x031表示读取保持寄存器的功能码。
起始地址高字节0x001寄存器起始地址的高字节(起始地址 0000 的高字节)。
起始地址低字节0x001寄存器起始地址的低字节(起始地址 0000 的低字节)。
寄存器数量高字节0x001请求读取寄存器数量的高字节(读取 2 个寄存器)。
寄存器数量低字节0x021请求读取寄存器数量的低字节(读取 2 个寄存器)。
CRC校验低字节0xC41CRC16 校验码的低字节(自动计算)。
CRC校验高字节0x0B1CRC16 校验码的高字节(自动计算)。

完整请求帧(十六进制表示)

复制编辑01 03 00 00 00 02 C4 0B
字段逐步解析:
  1. 从站地址(0x01
    • 表示请求发送到地址为 1 的从设备。
  2. 功能码(0x03
    • 表示读取保持寄存器(Holding Registers)的请求。
  3. 起始地址(0x0000
    • 请求从寄存器地址 40001 开始(Modbus地址40001的实际地址为0000)。
  4. 寄存器数量(0x0002
    • 请求读取 2 个寄存器的数据。
  5. CRC校验(0xC40B
    • 用于错误检测的循环冗余校验码,由请求帧前面的所有字节计算得出。
2. Modbus RTU 响应帧结构解析

响应数据包(假设从设备返回两个寄存器的值分别为 0x12340x5678):

字段数据长度 (字节)说明
从站地址0x011表示响应来自地址为 1 的从设备。
功能码0x031表示读取保持寄存器的功能码。
数据字节计数0x041表示后续数据部分的字节数,共 4 个字节(2 个寄存器,每个 2 字节)。
数据1高字节0x121第一个寄存器(40001)的高字节。
数据1低字节0x341第一个寄存器(40001)的低字节。
数据2高字节0x561第二个寄存器(40002)的高字节。
数据2低字节0x781第二个寄存器(40002)的低字节。
CRC校验低字节0x5D1CRC16 校验码的低字节(自动计算)。
CRC校验高字节0xCA1CRC16 校验码的高字节(自动计算)。

完整响应帧(十六进制表示)

mathematica复制编辑01 03 04 12 34 56 78 5D CA
字段逐步解析:
  1. 从站地址(0x01
    • 表示响应来自地址为 1 的从设备。
  2. 功能码(0x03
    • 表示设备成功执行了读取保持寄存器的操作。
  3. 数据字节计数(0x04
    • 表示返回的寄存器数据部分共有 4 个字节。
  4. 数据部分
    • 第一个寄存器(40001):高字节 0x12,低字节 0x34,合并后为 0x1234
    • 第二个寄存器(40002):高字节 0x56,低字节 0x78,合并后为 0x5678
  5. CRC校验(0x5DCA
    • 用于检测响应数据的完整性和正确性。
3. CRC校验计算

CRC校验采用 Modbus CRC16算法 计算以下部分:

  • 请求帧校验范围:01 03 00 00 00 02
  • 响应帧校验范围:01 03 04 12 34 56 78

计算步骤:

  1. 初始值为 0xFFFF
  2. 逐字节计算,更新CRC值。
  3. 最终结果是 2 字节,分别存储为低字节和高字节。
4. 总结
  • 请求帧结构清晰,从站地址、功能码、起始地址、寄存器数量、CRC校验组成。
  • 响应帧包含返回数据和相关信息,如数据字节计数、寄存器值及CRC校验。
  • 数据解析直接基于功能码和数据结构,适合实现灵活的工业自动化系统。

如果需要实际代码实现,可以进一步探索基于Python、C或其他语言的Modbus通信库,如 pymodbuslibmodbus


Modbus地址与寄存器地址

1. Modbus地址与寄存器地址的概念
  • Modbus地址
    • 用户可读的逻辑地址,用于表示不同类型的数据,例如保持寄存器、输入寄存器、线圈、离散输入等。
    • Modbus地址从1开始(例如40001),符合人类习惯的编号方式。
  • 寄存器地址
    • 实际的数据存储地址,是从0开始的偏移量,表示寄存器在设备中的位置。
    • 计算机内部存储从0起始,因此寄存器地址比Modbus地址少1。
2. Modbus地址与寄存器地址的关系

Modbus协议将设备的数据存储划分为以下四种区域,每种区域有对应的逻辑地址范围和寄存器地址范围:

数据类型Modbus地址范围寄存器地址范围Modbus地址示例实际地址
线圈(Coils)000010999909998000010
离散输入100011999909998100010
输入寄存器300013999909998300010
保持寄存器400014999909998400010

在Modbus协议中:

  • Modbus地址 = 实际寄存器地址 + 起始偏移量
  • 对于保持寄存器,起始偏移量为 40001
3. 为什么“地址40001”的实际地址是“0000”?

按照上述关系,Modbus地址40001 对应的实际寄存器地址可以通过以下公式计算:实际地址=Modbus地址−起始偏移量实际地址 = Modbus地址 – 起始偏移量实际地址=Modbus地址−起始偏移量

对于保持寄存器:实际地址=40001−40001=0实际地址 = 40001 – 40001 = 0实际地址=40001−40001=0

因此,Modbus地址 40001 的实际寄存器地址为 0000

4. 历史原因与设计初衷
  • 人类友好性
    • 逻辑地址从1开始(如40001)更符合人类习惯,而计算机内部通常从0开始。
  • 数据类型区分
    • Modbus协议使用逻辑地址的第一个数字区分数据类型。例如:
      • 4xxxx 表示保持寄存器。
      • 3xxxx 表示输入寄存器。
    • 这种设计在工业设备的配置和调试中具有很高的可读性。
5. 实际应用中的注意事项
  • 寄存器地址与Modbus地址的转换
    • 编写Modbus客户端时,很多库(如pymodbus)要求输入的是实际寄存器地址,而非Modbus地址。
    • 如果需要读取Modbus地址 40001,应将其转换为寄存器地址 0
  • 误解与问题
    • 用户有时会混淆两种地址,导致通信失败。例如:
      • 请求地址40001时输入寄存器地址40000,会引发错误。
6. 总结
  • Modbus地址40001的实际地址为0000 是由于 Modbus地址从1起始,而寄存器地址从0起始。
  • 这种设计提高了数据类型区分的可读性,同时需要在实际实现中正确转换地址。
  • 熟悉地址关系对于避免通信错误至关重要。

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注