跳转至

Modbus 协议文档 📚

欢迎使用 Modbus 协议文档

这里提供了一份清晰、易读的 Modbus 协议技术文档,涵盖了协议的核心概念、技术规范和实践应用。

📖 协议概述

Modbus 是一种应用层消息传递协议,由 Modicon 公司在 1979 年发布。它已经成为工业自动化领域最广泛使用的通信协议之一。

🌟 主要特性

  • 完全开放的协议规范
  • 任何厂商都可以免费使用
  • 社区支持广泛
  • 协议结构简单明了
  • 易于实现和调试
  • 学习成本低
  • 内置错误检测机制
  • 支持多种传输介质
  • 工业级稳定性
  • 在工业自动化领域应用广泛
  • 支持多种设备类型
  • 生态系统完善

🔧 协议变体

Modbus 协议支持多种传输方式,适应不同的应用场景:

远程终端单元

  • 传输方式: 串行传输,二进制编码
  • 校验方式: CRC-16 循环冗余校验
  • 特点: 数据密度高,传输效率好
  • 应用场景: RS-232/RS-485 串行网络

技术规格:

  • 帧格式: [地址][功能码][数据][CRC-16]
  • 字符编码: 8位二进制
  • CRC多项式: x^16 + x^15 + x^2 + 1 (0xA001)
  • 典型配置: 9600 bps, 8-N-1

ASCII 字符编码

  • 传输方式: 串行传输,ASCII 字符编码
  • 校验方式: LRC (纵向冗余校验)
  • 特点: 可读性好,调试方便
  • 应用场景: 需要人工监控的场合

技术规格:

  • 帧格式: [:][地址][功能码][数据][LRC][CR][LF]
  • 字符编码: ASCII十六进制字符
  • 起始符: ':' (0x3A)
  • 结束符: CR LF (0x0D 0x0A)

以太网传输

  • 传输方式: 以太网传输
  • 校验方式: 依赖 TCP 协议的可靠性
  • 特点: 支持多主站,传输距离远
  • 应用场景: 现代工业以太网环境

技术规格:

  • 默认端口: 502
  • MBAP头: 7字节 (事务标识+协议标识+长度+单元标识)
  • 最大PDU: 253字节
  • 连接方式: TCP长连接或短连接

📊 数据模型

Modbus 使用了一个简单而优雅的数据模型,将设备数据抽象为四种类型的数据区域:

数据类型 地址范围 访问权限 数据宽度 描述
线圈 (Coils) 00001-09999 读/写 1 bit 离散输出,可读写的布尔值
离散输入 (Discrete Inputs) 10001-19999 只读 1 bit 离散输入,只读的布尔值
输入寄存器 (Input Registers) 30001-39999 只读 16 bit 模拟输入,只读的数值
保持寄存器 (Holding Registers) 40001-49999 读/写 16 bit 模拟输出,可读写的数值

地址编号说明

地址编号是从 1 开始的,但在实际协议中传输的地址是从 0 开始的。

🎯 功能码概览

Modbus 协议定义了多种功能码来执行不同的操作:

  • 01 (0x01): 读线圈状态
  • 02 (0x02): 读离散输入状态
  • 03 (0x03): 读保持寄存器
  • 04 (0x04): 读输入寄存器
  • 05 (0x05): 写单个线圈
  • 06 (0x06): 写单个寄存器
  • 15 (0x0F): 写多个线圈
  • 16 (0x10): 写多个寄存器
  • 08 (0x08): 诊断功能
  • 17 (0x11): 报告从站 ID

详细功能码说明

完整的功能码详细说明请参考:功能码详解

📦 帧格式示例

帧结构:

[从站地址]  [功能码] [数据] [CRC校验]
   1字节    1字节   N字节   2字节

示例 - 读取保持寄存器:

请求: 01 03 00 00 00 02 C4 0B
响应: 01 03 04 00 0A 00 0B B8 FA

请求解析:

  • 01: 从站地址
  • 03: 功能码(读保持寄存器)
  • 00 00: 起始地址(0)
  • 00 02: 寄存器数量(2)
  • C4 0B: CRC校验

帧结构:

[起始符] [从站地址] [功能码] [数据] [LRC校验] [结束符]
  ':'     2字符    2字符    N字符   2字符    CR LF

示例 - 读取线圈状态:

请求: :01010000000AFE<CR><LF>
响应: :0101020055A9<CR><LF>

帧结构:

[事务标识][协议标识] [长度] [单元标识] [功能码] [数据]
  2字节    2字节    2字节    1字节    1字节   N字节

示例 - 写单个寄存器:

请求: 00 01 00 00 00 06 01 06 00 01 00 03
响应: 00 01 00 00 00 06 01 06 00 01 00 03

⚡ 异常响应

当从站无法正常处理请求时,会返回异常响应:

异常码 名称 描述
01 非法功能码 接收到的功能码不被支持
02 非法数据地址 接收到的数据地址不被允许
03 非法数据值 接收到的数据值不被允许
04 从站设备故障 从站在处理请求时发生不可恢复的错误
05 确认 从站已接受请求并正在处理,但需要长时间处理
06 从站设备忙 从站正在处理长时间程序命令

异常响应格式:

RTU: [从站地址] [异常功能码] [异常码] [CRC校验]
TCP: [MBAP头] [异常功能码] [异常码]

其中异常功能码 = 原功能码 + 0x80

🔍 技术规范

串行传输参数

  • 波特率: 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200 bps
  • 数据位: 8 位
  • 停止位: 1 或 2 位
  • 奇偶校验: 无、奇校验、偶校验

时序要求

  • 字符间超时: 1.5 个字符时间
  • 帧间间隔: 3.5 个字符时间
  • 响应超时: 通常设置为 1-5 秒

🔐 校验算法

算法步骤:

  1. 初始化CRC寄存器为0xFFFF
  2. 对每个数据字节执行以下操作:
    • 将数据字节与CRC寄存器低字节异或
    • 右移CRC寄存器8次,每次检查最低位
    • 如果最低位为1,则与0xA001异或

C语言实现:

uint16_t crc16(uint8_t *data, uint16_t length) {
    uint16_t crc = 0xFFFF;
    for (uint16_t i = 0; i < length; i++) {
        crc ^= data[i];
        for (uint8_t j = 0; j < 8; j++) {
            if (crc & 0x0001) {
                crc = (crc >> 1) ^ 0xA001;
            } else {
                crc >>= 1;
            }
        }
    }
    return crc;
}

算法步骤:

  1. 将所有数据字节相加
  2. 取结果的二进制补码
  3. 转换为ASCII十六进制字符

C语言实现:

1
2
3
4
5
6
7
uint8_t lrc_check(uint8_t *data, uint16_t length) {
    uint8_t lrc = 0;
    for (uint16_t i = 0; i < length; i++) {
        lrc += data[i];
    }
    return (uint8_t)(-(int8_t)lrc);
}

🛡️ 安全注意事项

安全风险

Modbus协议本身不提供安全机制,存在以下风险:

  • 明文传输: 所有数据以明文形式传输
  • 无身份认证: 不验证通信双方身份
  • 无数据完整性保护: 除基本校验外无额外保护
  • 易受网络攻击: 可能遭受中间人攻击、重放攻击等

安全建议

网络层安全:

  • 使用VPN隧道加密Modbus TCP通信
  • 配置防火墙限制Modbus端口(502)访问
  • 使用专用工业网络,与办公网络隔离

应用层安全:

  • 实施TLS加密(Modbus over TLS)
  • 添加应用层身份认证机制
  • 部署网络监控和入侵检测系统

💡 实际应用案例

场景: PLC控制系统

  • 设备: PLC + 多台变频器
  • 协议: Modbus RTU over RS-485
  • 配置: 9600 bps, 8-N-1, 从站地址1-10
  • 功能: 读取变频器状态,控制电机启停和转速

场景: SCADA监控系统

  • 设备: 中央监控站 + 多个现场控制器
  • 协议: Modbus TCP/IP over Ethernet
  • 网络: 工业以太网交换机组网
  • 功能: 监控空调、照明、安防系统

场景: 智能电表数据采集

  • 设备: 数据采集器 + 多台智能电表
  • 协议: Modbus RTU over RS-485
  • 拓扑: 总线型连接,最多32个设备
  • 功能: 定时读取电量、功率等参数

🔧 开发工具推荐

调试工具

  • 串口调试助手: 用于RTU/ASCII协议调试
  • Wireshark: 用于TCP/IP协议分析
  • ModbusPoll/ModbusSlave: 专业Modbus测试工具
  • pymodbus: Python开发库,支持所有Modbus变体

开发库推荐

Python:

pip install pymodbus

C/C++:

  • libmodbus (Linux)
  • FreeModbus (嵌入式)

Java:

  • j2mod
  • modbus4j

C#/.NET:

  • NModbus
  • EasyModbus

📚 相关文档


温馨提示

这份文档提供了 Modbus 协议的全面介绍,建议结合实际项目进行学习和实践。