Modbus 03 / 04 功能码入门:如何看懂请求报文和回复报文

阅读时间:约 15 分钟

Modbus 03 / 04 功能码请求与回复报文入门

很多刚接触 Modbus 的朋友,第一次看到设备日志里的报文时都会有点懵:

01 03 00 00 00 02 C4 0B
01 03 04 00 E6 01 2C 1B 89

这些数字看起来像一串密码,但它们不是随机内容。Modbus RTU 报文通常由 从机地址、功能码、数据区、CRC 校验 组成。只要先看清这几个部分,再结合设备手册中的寄存器表,就能判断一条报文在问什么、设备又回复了什么。

03 和 04 是设备采集中最常见的两个读取功能码。本文会先拆解 03 / 04 的查询请求和回复报文,再介绍 ThingsCloud 的 属性智能转换:它可以根据设备类型中的 Modbus 寄存器配置,把设备回复的 Modbus 报文自动转换成设备属性值;对于读写类寄存器或 IO,也可以把属性下发转换成对应的 Modbus 写入报文。

一、先记住一条规则:主站问,从站答

Modbus RTU 是典型的主站 / 从站通信。主站负责发起请求,从站收到请求后再回复。接入 ThingsCloud 时,可以先按下面这层关系理解:

  • ThingsCloud 任务生成并下发 Modbus 查询报文,DTU / 网关负责把报文透传到 RS485 总线。
  • RS485 总线上的传感器、仪表、PLC、温控器等设备作为从站回复数据。
  • 设备回复后,DTU / 网关把 Modbus RTU 报文透传回云端,ThingsCloud 再根据配置解析成属性。

Modbus 03 功能码完整请求与回复报文示例

所以,当你在日志里看到两行报文时,通常可以先判断:

主站请求:01 03 00 00 00 02 C4 0B
从站回复:01 03 04 00 E6 01 2C 1B 89

第一行是在问:“地址为 01 的设备,请用 03 功能码,从地址 0000 开始,读取 2 个寄存器。”

第二行是在答:“地址为 01 的设备回复了 4 个字节的数据,分别是 00 E6 和 01 2C。”

二、03 和 04 到底有什么区别?

03 和 04 都是“读取寄存器”,它们的请求报文结构几乎一样,区别在于读取的寄存器类型不同。

功能码名称常见用途寄存器特性
03读取保持寄存器读取或写入配置值、参数值,也常被一些厂家用于读取传感器数值通常可读可写
04读取输入寄存器读取温度、湿度、压力、流量、电压等采集值通常只读

在 ThingsCloud 的 Modbus 配置中,这个差异对应到数据寄存器的读写类型:

  • 只读 / 输入寄存器:读取功能码是 04,用于采集传感器数值。
  • 读写 / 保持寄存器:读取功能码是 03,写入单个保持寄存器时通常使用 06,常用于读取或修改配置数值。

但现场设备不一定完全按教科书来。有些厂家的温湿度传感器也用 03 功能码读取采集值。因此,最终以设备厂家提供的 Modbus 寄存器手册为准,不要只凭“传感器就一定用 04”来判断。

三、03 功能码请求报文怎么拆?

先看一条完整的 03 请求报文:

01 03 00 00 00 02 C4 0B

03 与 04 功能码请求和回复报文拆解示意

把它拆开:

字节含义解释
01从机地址要访问地址为 1 的设备
03功能码读取保持寄存器
00 00起始寄存器地址0x0000 开始读取
00 02寄存器数量读取 2 个寄存器
C4 0BCRC 校验用于校验报文是否传输错误

这条请求用一句话翻译就是:

主站请求地址为 01 的从站,从保持寄存器地址 0x0000 开始,读取 2 个寄存器。

这里有 3 个细节很容易出错。

第一,报文中的起始地址是 16 位地址字段,这里用十六进制展示。设备手册里可能写 0000H0x000040001寄存器地址 0 等不同形式。尤其要注意,40001 常是保持寄存器的参考编号,不一定等于报文里直接填写的地址值。

第二,读取数量是“寄存器数量”,不是字节数量。1 个 Modbus 寄存器是 2 个字节,所以读取 2 个寄存器,回复数据区里会有 4 个数据字节。

第三,CRC 在 Modbus RTU 报文里通常低字节在前。上面这条请求的 CRC 是 0x0BC4,报文里写成 C4 0B

四、03 功能码回复报文怎么拆?

对应的回复报文:

01 03 04 00 E6 01 2C 1B 89

拆开来看:

字节含义解释
01从机地址地址为 1 的设备在回复
03功能码回复的是 03 读取保持寄存器
04字节数后面有 4 个数据字节
00 E6第 1 个寄存器值十六进制 0x00E6,十进制是 230
01 2C第 2 个寄存器值十六进制 0x012C,十进制是 300
1B 89CRC 校验校验回复报文

如果这两个寄存器分别代表温度和湿度,并且设备手册说明需要除以 10,那么:

  • 00 E6 = 230,实际温度是 23.0℃
  • 01 2C = 300,实际湿度是 30.0%RH

也就是说,Modbus 报文本身只告诉你“寄存器里的原始值”。这个值代表温度、湿度还是电压,是否要除以 10100,需要看设备手册和平台配置。

五、04 功能码请求报文怎么拆?

04 请求报文和 03 几乎一样,只是功能码变成了 04

01 04 00 00 00 02 71 CB

拆开:

字节含义解释
01从机地址要访问地址为 1 的设备
04功能码读取输入寄存器
00 00起始寄存器地址0x0000 开始读取
00 02寄存器数量读取 2 个寄存器
71 CBCRC 校验用于校验报文是否传输错误

翻译成自然语言:

主站请求地址为 01 的从站,从输入寄存器地址 0x0000 开始,读取 2 个寄存器。

六、04 功能码回复报文怎么拆?

对应的 04 回复报文:

01 04 04 09 C4 13 88 B4 B3

拆开:

字节含义解释
01从机地址地址为 1 的设备在回复
04功能码回复的是 04 读取输入寄存器
04字节数后面有 4 个数据字节
09 C4第 1 个寄存器值十六进制 0x09C4,十进制是 2500
13 88第 2 个寄存器值十六进制 0x1388,十进制是 5000
B4 B3CRC 校验校验回复报文

如果设备手册说明第 1 个寄存器是温度,单位需要除以 100;第 2 个寄存器是湿度,单位需要除以 100,那么:

  • 09 C4 = 2500,实际温度是 25.00℃
  • 13 88 = 5000,实际湿度是 50.00%RH

同样的回复结构,在不同设备上可能代表不同物理含义。读报文不能脱离寄存器手册。

七、为什么回复里有“字节数”,请求里没有?

03 / 04 的请求里已经写明了要读取多少个寄存器,所以请求不需要再写“字节数”。例如 00 02 表示读取 2 个寄存器。

回复里则需要告诉主站“我后面带了多少字节的数据”。因为 1 个寄存器是 2 个字节,所以:

读取寄存器数量回复字节数
1 个寄存器02
2 个寄存器04
3 个寄存器06
10 个寄存器14,也就是十进制 20

所以看到回复报文中的第三个字节,不要把它当成寄存器值。它只是后面数据区的长度。

八、如何从数据字节变成设备属性值?

读懂 03 / 04 报文后,还差最后一步:把寄存器原始值变成有业务意义的属性。

以这条 04 回复为例:

01 04 04 09 C4 13 88 B4 B3

数据区是:

09 C4 13 88

如果按照 2 个 16 位无符号整数解析,就是:

寄存器原始值十进制业务属性换算后
第 1 个寄存器09 C42500温度25.00℃
第 2 个寄存器13 885000湿度50.00%RH

但有些设备会用 32 位浮点数表示一个值。例如电表的电压可能占用 2 个寄存器,也就是 4 个字节。此时就不能按两个 16 位整数拆,而要按 32 位浮点数解析,还要关注字节序,例如 ABCDBADCCDABDCBA

这也是很多新手遇到“读到了数据,但数值不对”的原因:报文能通,不代表数据类型、寄存器长度和字节序一定配对正确。

九、ThingsCloud 如何把 Modbus 报文变成属性?

如果完全手写解析逻辑,你需要自己处理从机地址、功能码、起始地址、寄存器数量、数据类型、字节序、倍率换算和 CRC。对单个设备还可以接受,一旦项目里有多种型号、多条总线或多个项目,就很容易出错。

ThingsCloud 的 属性智能转换 正是为这个场景设计的。它的核心思路是:先在设备类型中定义属性,再在 Modbus 配置中把属性和寄存器地址绑定。

典型配置链路是:

  1. 在设备类型中创建属性,例如 temperaturehumidityvoltage
  2. 在 Modbus 配置中,为这些属性填写寄存器地址、读写类型、数据类型和字节序;普通透传场景还要确认从机地址,云网关子设备场景通常使用子设备地址。
  3. 开启 属性智能转换,并设置正确的自定义数据流。
  4. 通过任务下发 03 / 04 查询指令。
  5. 设备回复 Modbus 报文后,ThingsCloud 自动解析并更新属性当前值。

ThingsCloud 属性智能转换把 Modbus 报文映射成设备属性

例如,你已经把温度属性绑定到输入寄存器 0x0000,数据类型配置为 16 位无符号整数,并按设备手册设置倍率。当设备回复:

01 04 04 09 C4 13 88 B4 B3

ThingsCloud 就可以根据寄存器表,把 09 C4 解析为温度属性,把 13 88 解析为湿度属性。随后这些属性可以用于设备详情、历史数据、可视化看板、ThingsX App、告警策略和自动化逻辑。

十、属性智能转换解决了哪些问题?

对新手来说,属性智能转换最大的价值不是“少写代码”,而是把 Modbus 的底层复杂度收敛到一张寄存器配置表里。

它主要解决 4 类问题:

问题传统做法ThingsCloud 做法
报文看不懂自己写解析脚本或用调试工具反复试按寄存器表配置,平台自动解析
数据类型容易错手动判断 16 位、32 位、浮点数和字节序在 Modbus 配置中选择数据类型和字节序
上层应用难复用每个应用都要理解寄存器看板、App、告警统一使用属性
下发控制复杂手写 Modbus 写寄存器报文读写属性下发可自动转换为对应 Modbus 报文

在 ThingsCloud 中,数据寄存器可以绑定到 Number 属性。平台支持常见的 16 位整数、16 位无符号整数、32 位整数、32 位无符号整数和 32 位浮点数,并支持常见字节序配置。对于 IO 寄存器,则可以绑定 Boolean 属性。

十一、调试时按这 5 步排查

如果你正在现场调试 03 / 04 功能码,建议按下面顺序排查。

  1. 先看从机地址
    请求里的第 1 个字节必须和设备实际地址一致。同一条 RS485 总线上不能有两个设备使用同一个从机地址。
  2. 再看功能码
    设备手册写 03 就用 03,写 04 就用 04。不要只按经验猜。
  3. 核对起始寄存器地址
    特别注意 0x00000001H40001 这些写法之间的差异。不同手册和工具对地址起点的表达可能不同。
  4. 核对读取数量
    读取数量是寄存器数量。读 2 个寄存器,回复数据区应该是 4 个字节。
  5. 最后看数据类型和字节序
    如果日志有回复,但数值明显不对,优先检查 16 / 32 位类型、是否有倍率、字节序是否匹配。

如果使用 ThingsCloud,可以在设备调试日志中观察请求和回复,再结合 Modbus 配置表确认属性是否被正确更新。

总结

03 和 04 功能码并不复杂。请求报文的核心是“问哪台设备、用什么功能码、从哪个地址开始、读几个寄存器”;回复报文的核心是“哪台设备在答、答的是哪个功能码、后面有多少字节数据、每个寄存器的值是多少”。

真正容易出错的,是从报文到业务属性的最后一段:数据类型、字节序、倍率、寄存器地址和属性之间的关系。ThingsCloud 的属性智能转换把这段关系配置化,让设备回复的 Modbus 报文能够自动变成温度、湿度、电压、电流等设备属性,也让上层看板、App、告警和自动化不必直接面对底层报文。

对初学者来说,先学会拆 03 / 04 报文,再用 ThingsCloud 的 Modbus 配置把寄存器映射成属性,是理解 Modbus 设备接入最稳的一条路径。

相关文档可参考:

关于 ThingsCloud

ThingsCloud 是新一代物联网设备统一接入平台,帮助企业在极短的时间内搭建个性化的物联网平台和应用,并适应不断变化的发展需求。目前广泛应用于制造、电力、能源、环境、农业、楼宇、家居、教育、交通、物流、自动化等领域。

ThingsCloud 可接入各类网关,传感器、执行器、控制器、通信模组、智能硬件等,实现数据采集、远程控制,数据分析、告警通知、智能联动。还可以零代码生成项目应用 SaaS 和用户应用 App,并开放 API 和实时消息,便于业务系统集成和扩展开发。

通过使用 ThingsCloud,企业可以大大缩短搭建物联网系统的时间,节省软件开发费用,降低定制开发的风险,快速落地数字化和智能化项目。我们的客户遍布各行业,包括中国石化、中国铁塔、中国燃气、吉林大学、北控水务、ACE、中国民航大学、西安交通大学、精量电子、大秦铁路、宁波水利局等。

🚀 开箱即用的物联网平台

立即搭建您的 物联网平台

接入物联网设备搭建可视化看板生成专属 App
仅需不到 30 分钟,开启您的物联网之旅

开箱即用
无需部署
快速上手
10,000+ 企业信赖
6,000,000+ 设备接入
99.9% 服务可用性
信任与选择

5000+ 大型企业正在使用ThingsCloud

从初创公司到世界 500 强,企业选择 ThingsCloud 构建可靠的物联网解决方案

更多博客

应用场景

全球 80% 的数据将来自物联网,不论是传统行业还是新兴行业,都将利用更多有价值的数据来驱动业务,实现降本增效。