
版本: 1.0 | 编写日期: 2026-04-22
功能码(Function Code)是 Modbus 协议中的"命令代码",告诉设备要执行什么操作。
类比理解:
功能码就像餐厅菜单上的编号:
- 01号 = 查看某道菜是否还有
- 03号 = 查看菜的价格
- 06号 = 点一道菜
- 10号 = 批量点菜┌─────────────────────────────────────────────────────────────┐
│ Modbus 功能码 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 读取类 │ │ 写入类 │ │ 诊断类 │ │
│ │ 01 02 03 │ │ 05 06 15 │ │ 07 08 11 │ │
│ │ 04 │ │ 16 22 │ │ 43 ... │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
│ 最常用 ★★★ 常用 ★★ 进阶 ★ │
│ │
└─────────────────────────────────────────────────────────────┘
项目 | 说明 |
|---|---|
功能码 | 0x01 (十进制 1) |
作用 | 读取开关量输出的状态(ON/OFF) |
数据类型 | 位(单个 0 或 1) |
可读数量 | 1 ~ 2000 个 |
通俗解释:
查询设备的"开关"状态。比如:继电器是吸合还是断开?阀门是开还是关?
典型应用:
示例:
请求:读取 1 号从站,地址 0 开始的 8 个线圈
响应:返回 8 个位状态,如 [1,0,1,1,0,0,1,0]
解读:线圈 0=ON, 线圈 1=OFF, 线圈 2=ON, ...项目 | 说明 |
|---|---|
功能码 | 0x02 (十进制 2) |
作用 | 读取开关量输入的状态(ON/OFF) |
数据类型 | 位(单个 0 或 1) |
可读数量 | 1 ~ 2000 个 |
通俗解释:
查询设备的"输入信号"状态。与 FC01 的区别是:这是只读的外部信号。
FC01 vs FC02 对比:
对比项 | FC01 线圈 | FC02 离散输入 |
|---|---|---|
方向 | 输出(可控制) | 输入(只读) |
典型设备 | 继电器、指示灯 | 按钮、限位开关 |
可写 | ✅ 可以写 | ❌ 只能读 |
典型应用:
项目 | 说明 |
|---|---|
功能码 | 0x03 (十进制 3) |
作用 | 读取可读写的数值数据 |
数据类型 | 16位整数(0 ~ 65535) |
可读数量 | 1 ~ 125 个 |
通俗解释:
读取设备的"参数值"或"设置值"。这是最常用的功能码!
典型应用:
示例:
请求:读取 1 号从站,地址 0 开始的 3 个寄存器
响应:返回 3 个数值,如 [500, 100, 200]
解读:
寄存器 0 = 500 → 频率设定 50.0Hz
寄存器 1 = 100 → 加速时间 10.0s
寄存器 2 = 200 → 减速时间 20.0s项目 | 说明 |
|---|---|
功能码 | 0x04 (十进制 4) |
作用 | 读取只读的测量数值 |
数据类型 | 16位整数(0 ~ 65535) |
可读数量 | 1 ~ 125 个 |
通俗解释:
读取设备的"测量值"或"实际值"。与 FC03 的区别是:这是只读的传感器数据。
FC03 vs FC04 对比:
对比项 | FC03 保持寄存器 | FC04 输入寄存器 |
|---|---|---|
方向 | 可读写 | 只读 |
典型数据 | 设定值、参数 | 测量值、实际值 |
典型应用 | 频率设定、PID参数 | 温度测量、压力测量 |
典型应用:
项目 | 说明 |
|---|---|
功能码 | 0x05 (十进制 5) |
作用 | 控制单个开关量输出 |
数据类型 | 位(ON 或 OFF) |
写入数量 | 1 个 |
通俗解释:
控制一个"开关"。比如:启动电机、打开阀门、点亮指示灯。
写入值:
值 | 含义 |
|---|---|
0xFF00 | ON(开/启动) |
0x0000 | OFF(关/停止) |
典型应用:
示例:
请求:写入 1 号从站,地址 0 的线圈,值 = ON
响应:成功(原样返回请求)
效果:电机启动项目 | 说明 |
|---|---|
功能码 | 0x06 (十进制 6) |
作用 | 设置单个参数值 |
数据类型 | 16位整数(0 ~ 65535) |
写入数量 | 1 个 |
通俗解释:
设置一个"数值参数"。比如:设置频率、设置温度、设置时间。
典型应用:
示例:
请求:写入 1 号从站,地址 0 的寄存器,值 = 500
响应:成功(原样返回请求)
效果:频率设定为 50.0Hz(精度 0.1)项目 | 说明 |
|---|---|
功能码 | 0x0F (十进制 15) |
作用 | 批量控制多个开关量输出 |
数据类型 | 位(多个 ON/OFF) |
写入数量 | 1 ~ 1968 个 |
通俗解释:
一次控制多个"开关"。比逐个用 FC05 更高效。
典型应用:
示例:
请求:写入 1 号从站,地址 0 开始的 8 个线圈
数据:[1,0,1,1,0,0,1,0]
响应:成功,写入 8 个线圈
效果:8 路继电器按指定状态动作项目 | 说明 |
|---|---|
功能码 | 0x10 (十进制 16) |
作用 | 批量设置多个参数值 |
数据类型 | 16位整数(多个) |
写入数量 | 1 ~ 123 个 |
通俗解释:
一次设置多个"数值参数"。比逐个用 FC06 更高效。
典型应用:
示例:
请求:写入 1 号从站,地址 0 开始的 3 个寄存器
数据:[500, 100, 150]
响应:成功,写入 3 个寄存器
效果:
频率 = 50.0Hz
加速时间 = 10.0s
减速时间 = 15.0s项目 | 说明 |
|---|---|
功能码 | 0x16 (十进制 22) |
作用 | 修改寄存器的特定位,不影响其他位 |
数据类型 | 16位整数 |
写入数量 | 1 个 |
通俗解释:
精确修改"控制字"的某一位。比如:只改第 3 位,其他位不变。
典型应用:
算法原理:
结果 = (当前值 AND AND屏蔽) OR (OR屏蔽 AND NOT AND屏蔽)
简单理解:
- AND屏蔽 = 0 的位会被清零
- OR屏蔽 = 1 的位会被置一
- AND屏蔽 = 1 的位保持原值项目 | 说明 |
|---|---|
功能码 | 0x17 (十进制 23) |
作用 | 一个请求同时完成读取和写入 |
数据类型 | 16位整数 |
读取数量 | 1 ~ 125 个 |
写入数量 | 1 ~ 121 个 |
通俗解释:
"原子操作":设置参数的同时读取状态。一次通信完成两件事。
典型应用:
优势:
项目 | 说明 |
|---|---|
功能码 | 0x07 (十进制 7) |
作用 | 快速读取设备的异常状态字节 |
数据类型 | 8位字节 |
典型应用:设备快速诊断
项目 | 说明 |
|---|---|
功能码 | 0x08 (十进制 8) |
作用 | 执行各种诊断测试 |
子功能 | 返回查询数据、重启通信、返回计数器等 |
典型应用:通信链路测试、故障诊断
项目 | 说明 |
|---|---|
功能码 | 0x11 (十进制 17) |
作用 | 读取设备的标识信息 |
返回数据 | 设备类型、运行状态、厂商信息 |
典型应用:设备识别、设备发现
项目 | 说明 |
|---|---|
功能码 | 0x2B (十进制 43) |
作用 | 读取详细的设备标识信息 |
可读信息 | 厂商名称、产品代码、版本号、产品名称等 |
典型应用:设备管理、资产追踪
┌─────────────────────────────────────────────────────┐
│ 我要操作什么数据? │
├─────────────────────────────────────────────────────┤
│ │
│ 位数据(开关量) │
│ ├── 读取 → FC01(线圈)或 FC02(离散输入) │
│ └── 写入 → FC05(单个)或 FC15(多个) │
│ │
│ 字数据(数值) │
│ ├── 读取 → FC03(保持寄存器)或 FC04(输入寄存器)│
│ └── 写入 → FC06(单个)或 FC16(多个) │
│ │
└─────────────────────────────────────────────────────┘
操作 | 推荐功能码 | 理由 |
|---|---|---|
读取单个参数 | FC03 | 最简单直接 |
读取多个参数 | FC03 | 一次读取多个 |
设置单个参数 | FC06 | 最简单直接 |
设置多个参数 | FC16 | 一次设置多个 |
控制单个开关 | FC05 | 最简单直接 |
控制多个开关 | FC15 | 一次控制多个 |
设置并读取 | FC23 | 原子操作 |
排名 | 功能码 | 使用频率 | 典型场景 |
|---|---|---|---|
🥇 | FC03 | ★★★★★ | 读取参数/状态 |
🥈 | FC06 | ★★★★☆ | 设置参数 |
🥉 | FC16 | ★★★☆☆ | 批量设置参数 |
4 | FC04 | ★★★☆☆ | 读取测量值 |
5 | FC05 | ★★☆☆☆ | 控制开关 |
答:都是读取位状态,区别在于数据来源:
答:都是读取寄存器,区别在于数据性质:
答:
答:
答:设备会返回异常响应:
异常码 | 含义 | 解决方法 |
|---|---|---|
0x01 | 非法功能码 | 设备不支持该功能码 |
0x02 | 非法地址 | 地址超出范围 |
0x03 | 非法数据 | 数据值无效 |
0x04 | 设备故障 | 设备内部错误 |
┌──────────────────────────────────────────────────────────────┐
│ Modbus 功能码速查卡 │
├──────────────────────────────────────────────────────────────┤
│ 读取类 │
│ ┌────┬──────────────────────┬───────────────────────────┐ │
│ │ 01 │ 读取线圈(输出位) │ 可写 │ 1-2000 个 │ │
│ │ 02 │ 读取离散输入(输入位)│ 只读 │ 1-2000 个 │ │
│ │ 03 │ 读取保持寄存器 │ 可写 │ 1-125 个 ⭐最常用 │ │
│ │ 04 │ 读取输入寄存器 │ 只读 │ 1-125 个 │ │
│ └────┴──────────────────────┴───────────────────────────┘ │
│ │
│ 写入类 │
│ ┌────┬──────────────────────┬───────────────────────────┐ │
│ │ 05 │ 写单个线圈 │ 1 个 │ ON=0xFF00 │ │
│ │ 06 │ 写单个寄存器 │ 1 个 │ ⭐最常用 │ │
│ │ 15 │ 写多个线圈 │ 1-1968 个 │ │
│ │ 16 │ 写多个寄存器 │ 1-123 个 │ │
│ │ 22 │ 屏蔽写寄存器 │ 位操作 │ │
│ │ 23 │ 读写多个寄存器 │ 原子操作 │ │
│ └────┴──────────────────────┴───────────────────────────┘ │
│ │
│ 记忆口诀: │
│ 01读线圈02读输入,03读参数04读值 │
│ 05写开关06写值,15批量16多参数 │
└──────────────────────────────────────────────────────────────┘