news 2026/5/1 4:43:48

Modbus RTU 基本功能码和概念

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Modbus RTU 基本功能码和概念

Modbus 是一种串行通信协议,最初由 Modicon(现为施耐德电气的一部分)为其可编程逻辑控制器 (PLC) 开发。它已成为工业自动化领域事实上的标准通信协议,用于在主站设备(如监控计算机、HMI)和从站设备(如 PLC、传感器、执行器)之间交换数据。

  • RTU (Remote Terminal Unit): 这是 Modbus 协议的一种传输模式。另一种常见模式是 ASCII。RTU 模式的主要特点是:
    • 二进制编码: 数据以紧凑的二进制形式传输。
    • 高效: 相比 ASCII 模式,RTU 模式传输相同信息量所需字节数更少,效率更高。
    • 帧结构: 一个完整的 Modbus RTU 帧由以下部分组成:
      1. 从站地址(1 Byte): 标识目标从站设备。
      2. 功能码(1 Byte): 指定主站请求的操作类型(读、写)和数据类型(线圈、寄存器等)。
      3. 数据域(n Bytes): 包含请求或响应的具体数据(地址、数量、值等)。
      4. CRC 校验(2 Bytes): 循环冗余校验,用于检测传输过程中可能出现的错误。
    • 时序: RTU 模式依靠字符间的时间间隔(大于 3.5 个字符时间)来界定帧的开始和结束。

核心功能:Modbus 协议的核心功能是让主站能够读取或写入从站设备中特定类型的数据存储区域。这些区域被抽象为四种主要类型:

  1. 线圈 (Coils): 1 位(位)输出量,可读可写。通常对应 PLC 的数字量输出点 (DO),如继电器状态、灯的控制信号。功能码 01 (读), 05 (写单个), 15 (写多个)。
  2. 离散量输入 (Discrete Inputs): 1 位(位)输入量,只读。通常对应 PLC 的数字量输入点 (DI),如按钮、限位开关的状态。功能码 02 (读)。
  3. 保持寄存器 (Holding Registers): 16 位(字)数据,可读可写。通常用于存储模拟量数据(如温度、压力)、配置参数或计算结果。功能码 03 (读), 06 (写单个), 16 (写多个)。
  4. 输入寄存器 (Input Registers): 16 位(字)数据,只读。通常用于存储来自模拟量输入模块 (AI) 的数据。功能码 04 (读)。

功能码解释

功能码是 Modbus 帧中紧随从站地址之后的一个字节。它定义了主站请求的操作类型(读/写)以及要操作的数据类型(线圈/离散输入/寄存器)。下表列出了最常用的功能码:

功能码 (十六进制)功能码 (十进制)名称操作数据类型
0x0101读线圈线圈 (Coils)
0x0202读离散量输入离散输入 (DIs)
0x0303读保持寄存器保持寄存器 (HRs)
0x0404读输入寄存器输入寄存器 (IRs)
0x0505写单个线圈线圈 (Coils)
0x0606写单个保持寄存器保持寄存器 (HRs)
0x0F15写多个线圈线圈 (Coils)
0x1016写多个保持寄存器保持寄存器 (HRs)
0x83131异常响应 (功能码 + 128)--
  • 异常响应: 如果从站无法执行主站的请求(例如,地址不存在、数据无效),它会返回一个异常响应帧。该帧的功能码是原始功能码值 + 0x80(或在原始功能码字节的最高位加 1)。紧随功能码之后是一个异常码(1 Byte),用于指示具体的错误原因。常见的异常码有:
    • 0x01: 非法功能 (不支持此功能码)
    • 0x02: 非法数据地址 (请求的地址无效或不存在)
    • 0x03: 非法数据值 (写入的值超出范围或无效)
    • 0x04: 从站设备故障 (设备内部错误)

功能码 01 (0x01) 详解 - 读线圈

  • 功能: 读取一个或多个连续线圈 (1位输出量) 的当前状态 (ON/OFF, 1/0)。
  • 请求帧结构:
    • [从站地址](1 Byte)
    • [功能码 = 0x01](1 Byte)
    • [起始地址高字节](1 Byte) - 要读取的第一个线圈的地址的高8位。
    • [起始地址低字节](1 Byte) - 要读取的第一个线圈的地址的低8位。
    • [线圈数量高字节](1 Byte) - 要读取的线圈总数的高8位。
    • [线圈数量低字节](1 Byte) - 要读取的线圈总数的低8位。
    • [CRC16 低字节](1 Byte)
    • [CRC16 高字节](1 Byte)
  • 响应帧结构:
    • [从站地址](1 Byte)
    • [功能码 = 0x01](1 Byte)
    • [字节数](1 Byte) - 后面数据域包含的字节数。计算公式:(线圈数量 + 7) / 8
    • [数据域](n Bytes) - 线圈状态按位打包的结果。每个字节包含8个线圈的状态(LSB 表示第一个线圈,MSB 表示该字节内的最后一个线圈)。如果读取的线圈数量不是8的倍数,最后一个字节的高位用0填充。
    • [CRC16 低字节](1 Byte)
    • [CRC16 高字节](1 Byte)

功能码 01 示例

  • 场景: 主站 (地址 0x01) 请求读取从站 (地址 0x02) 的线圈,起始地址为 0x0000 (线圈0),读取 10 个线圈 (线圈0 - 线圈9)。假设线圈状态:线圈0=ON(1), 线圈1=OFF(0), 线圈2=ON(1), 线圈3=ON(1), 线圈4=OFF(0), 线圈5=OFF(0), 线圈6=ON(1), 线圈7=OFF(0), 线圈8=ON(1), 线圈9=OFF(0)。
  1. 主站请求帧 (Hex):

    02 01 00 00 00 0A CRC
    • 02: 从站地址 (0x02)
    • 01: 功能码 (读线圈)
    • 00 00: 起始地址 = 0x0000 (线圈0)
    • 00 0A: 线圈数量 = 0x000A (10个)
    • CRC: 校验码 (假设计算为C10C)
  2. 从站响应帧 (Hex):

    02 01 02 CD 01 CRC
    • 02: 从站地址 (0x02)

    • 01: 功能码 (读线圈)

    • 02: 字节数 = 2 Bytes (因为 (10 + 7) / 8 = 1.25 -> 向上取整为 2)

    • CD: 第一个数据字节 (0xCD 二进制1100 1101)

      • LSB (Bit0) =1(线圈0 ON)
      • Bit1 =0(线圈1 OFF)
      • Bit2 =1(线圈2 ON)
      • Bit3 =1(线圈3 ON)
      • Bit4 =0(线圈4 OFF)
      • Bit5 =0(线圈5 OFF)
      • Bit6 =1(线圈6 ON)
      • MSB (Bit7) =1(线圈7 ON? 但假设是OFF?这里有问题,后面解释)
    • 01: 第二个数据字节 (0x01 二进制0000 0001)

      • LSB (Bit0) =1(线圈8 ON)
      • Bit1 =0(线圈9 OFF)
      • Bits 2-7: 未使用,填充为0 (读取10个线圈,第二个字节只用低2位)
    • 注意: 第一个字节0xCD(1100 1101) 中,MSB (Bit7) 对应线圈7。在我们的假设状态中,线圈7是 OFF(0),所以 Bit7 应该是0。但是0xCD的 Bit7 是1(因为0xCD=1100 1101)。这里存在一个错误假设。修正假设状态:线圈7=ON(1)。那么:

      • 线圈0=ON(1), 1=OFF(0), 2=ON(1), 3=ON(1), 4=OFF(0), 5=OFF(0), 6=ON(1), 7=ON(1) -> 第一个字节1100 1101=0xCD(LSB 是线圈0)。
      • 线圈8=ON(1), 9=OFF(0) -> 第二个字节0000 0001=0x01(LSB 是线圈8)。
    • CRC: 校验码 (假设计算为E40B)


功能码 03 (0x03) 详解 - 读保持寄存器

  • 功能: 读取一个或多个连续保持寄存器 (16位数据) 的当前值。
  • 请求帧结构:
    • [从站地址](1 Byte)
    • [功能码 = 0x03](1 Byte)
    • [起始地址高字节](1 Byte) - 要读取的第一个寄存器的地址的高8位。
    • [起始地址低字节](1 Byte) - 要读取的第一个寄存器的地址的低8位。
    • [寄存器数量高字节](1 Byte) - 要读取的寄存器总数的高8位。
    • [寄存器数量低字节](1 Byte) - 要读取的寄存器总数的低8位。
    • [CRC16 低字节](1 Byte)
    • [CRC16 高字节](1 Byte)
  • 响应帧结构:
    • [从站地址](1 Byte)
    • [功能码 = 0x03](1 Byte)
    • [字节数](1 Byte) - 后面数据域包含的字节数。计算公式:寄存器数量 * 2(因为每个寄存器16位=2字节)。
    • [数据域](n Bytes) - 寄存器的值,按顺序排列。每个寄存器占用2个字节,通常是大端序 (Big-Endian),即高字节在前 (MSB),低字节在后 (LSB)。例如,寄存器值 0x1234 会表示为12 34
    • [CRC16 低字节](1 Byte)
    • [CRC16 高字节](1 Byte)

功能码 03 示例

  • 场景: 主站 (地址 0x01) 请求读取从站 (地址 0x03) 的保持寄存器,起始地址为 0x0006 (寄存器6),读取 3 个寄存器 (寄存器6, 7, 8)。假设寄存器值:
    • 寄存器6: 0x1234 (4660)
    • 寄存器7: 0x5678 (22136)
    • 寄存器8: 0x9ABC (39612)
  1. 主站请求帧 (Hex):

    03 03 00 06 00 03 CRC
    • 03: 从站地址 (0x03)
    • 03: 功能码 (读保持寄存器)
    • 00 06: 起始地址 = 0x0006 (寄存器6)
    • 00 03: 寄存器数量 = 0x0003 (3个)
    • CRC: 校验码 (假设计算为45F1)
  2. 从站响应帧 (Hex):

    03 03 06 12 34 56 78 9A BC CRC
    • 03: 从站地址 (0x03)
    • 03: 功能码 (读保持寄存器)
    • 06: 字节数 = 6 Bytes (3 寄存器 * 2 字节/寄存器)
    • 12 34: 寄存器6 的值 (0x1234)
    • 56 78: 寄存器7 的值 (0x5678)
    • 9A BC: 寄存器8 的值 (0x9ABC)
    • CRC: 校验码 (假设计算为05D9)

重要注意事项

  1. 地址偏移: Modbus 协议定义的数据区地址是从 0 开始的。但很多设备文档或软件 (如 SCADA, HMI) 可能会使用基于 1 的索引(例如,线圈1对应地址0x0000)。务必查看设备手册确认其寻址方式。
  2. 字节顺序 (Endianness): 对于16位寄存器,Modbus 协议规定传输时是大端序。但在将两个字节组合成一个16位整数时,或在表示更大数据类型(如32位浮点数,占用两个寄存器)时,应用层必须定义寄存器之间的组合顺序(是[RegA Hi, RegA Lo]还是[RegA Lo, RegA Hi])以及多寄存器数据类型的字节顺序。这是应用中常见的混淆点。
  3. 数据类型映射: 保持寄存器中存储的原始字节数据需要映射到具体的物理意义(如温度、压力)。这通常需要知道缩放比例、偏移量和数据类型(整数、浮点数)。
  4. CRC 计算: CRC 校验是保证通信可靠性的重要环节。计算算法是标准的 Modbus RTU CRC16 (多项式 0x8005,初始值 0xFFFF)。通信两端必须使用相同的算法。
  5. 调试工具: 使用串口监视工具或专门的 Modbus 调试工具(如 Modscan, QModMaster)可以直观地查看发送和接收的原始报文,是排查通信问题的有效手段。注意查看十六进制文本。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/20 19:20:41

2025国产运维监控系统横评:全栈智能与信创适配引领选型新风向

2025 年,数字化转型进入深水区,混合云架构、云原生部署与信创替代成为企业 IT 建设的核心关键词。传统监控工具 “数据孤岛、告警风暴、国产化适配不足” 的痛点愈发凸显,国产运维监控系统凭借自主可控、本土适配、全栈融合的优势快速崛起。本…

作者头像 李华
网站建设 2026/4/29 11:28:48

揭秘3大黑科技:用Leon Sans打造文字粒子爆炸的骚操作

揭秘3大黑科技:用Leon Sans打造文字粒子爆炸的骚操作 【免费下载链接】leonsans Leon Sans is a geometric sans-serif typeface made with code in 2019 by Jongmin Kim. 项目地址: https://gitcode.com/gh_mirrors/le/leonsans 你曾想过让网页上的文字像烟…

作者头像 李华
网站建设 2026/5/1 2:43:05

实战笔记】200smart电子厂净化空调PID控制程序开发实录

200smart 电子洁净厂房净化空调串级 P ID 自控程序 串级 PID 控制 自写双向 PID 子程序 自写露点与焓值计算子程序 控制精度:温度-1 度,湿度-5%最近在搞电子洁净厂房的空调自控项目,客户要求温湿度控制精度硬指标:温度1℃、湿度5…

作者头像 李华
网站建设 2026/4/22 9:49:12

React Native轮播组件实战精髓:从入门到精通掌握react-native-snap-carousel

在移动应用开发中,轮播组件已成为展示内容、提升用户体验的重要工具。react-native-snap-carousel作为React Native生态中的明星轮播组件,以其卓越的性能表现和丰富的功能特性赢得了开发者的广泛青睐。本文将带领你深入探索这一组件的核心价值与实际应用…

作者头像 李华
网站建设 2026/4/24 22:05:52

Higress云原生网关健康检查:5大核心机制深度解析与实战配置

Higress云原生网关健康检查:5大核心机制深度解析与实战配置 【免费下载链接】higress Next-generation Cloud Native Gateway | 下一代云原生网关 项目地址: https://gitcode.com/GitHub_Trending/hi/higress 在微服务架构的复杂环境中,网关的健康…

作者头像 李华
网站建设 2026/4/7 18:38:46

如何快速解决AMD GPU识别问题:完整技术方案指南

如何快速解决AMD GPU识别问题:完整技术方案指南 【免费下载链接】ROCm AMD ROCm™ Software - GitHub Home 项目地址: https://gitcode.com/GitHub_Trending/ro/ROCm 在Ubuntu系统环境中,使用AMD GPU进行AI计算时,许多开发者会遇到&qu…

作者头像 李华