Modbus 功能码详解 📋
功能码概述
功能码是 Modbus 协议的核心,定义了主站和从站之间可以执行的各种操作。每个功能码都有特定的用途和格式。
🎯 功能码分类
读取功能码
01 - 读线圈状态 (Read Coils)
| 字段名称 | 长度 | 说明 |
|---|---|---|
| 功能码 | 1字节 | 指定要执行的操作类型 (0x01) |
| 起始地址 | 2字节 | 标识目标线圈的起始地址 (0x0000-0xFFFF) |
| 线圈数量 | 2字节 | 指定要读取的线圈数量 (1-2000) |
| 字段名称 | 长度 | 说明 |
|---|---|---|
| 功能码 | 1字节 | 固定为 0x01 |
| 字节计数 | 1字节 | 后续线圈状态数据的字节数 |
| 线圈状态 | N字节 | 线圈状态,每位代表一个线圈(1=ON, 0=OFF) |
| 字段名称 | 长度 | 说明 |
|---|---|---|
| 功能码 | 1字节 | 0x81 (0x01 + 0x80) |
| 异常码 | 1字节 | 错误类型代码 |
02 - 读离散输入状态 (Read Discrete Inputs)
| 字段名称 | 长度 | 说明 |
|---|---|---|
| 功能码 | 1字节 | 指定要执行的操作类型 (0x02) |
| 起始地址 | 2字节 | 标识目标输入的起始地址 (0x0000-0xFFFF) |
| 输入数量 | 2字节 | 指定要读取的输入数量 (1-2000) |
| 字段名称 | 长度 | 说明 |
|---|---|---|
| 功能码 | 1字节 | 固定为 0x02 |
| 字节计数 | 1字节 | 后续输入状态数据的字节数 |
| 输入状态 | N字节 | 输入状态,每位代表一个输入(1=ON, 0=OFF) |
| 字段名称 | 长度 | 说明 |
|---|---|---|
| 功能码 | 1字节 | 0x82 (0x02 + 0x80) |
| 异常码 | 1字节 | 错误类型代码 |
03 - 读保持寄存器 (Read Holding Registers)
| 字段名称 | 长度 | 说明 |
|---|---|---|
| 功能码 | 1字节 | 指定要执行的操作类型 (0x03) |
| 起始地址 | 2字节 | 标识目标寄存器的起始地址 (0x0000-0xFFFF) |
| 寄存器数量 | 2字节 | 指定要读取的寄存器数量 (1-125) |
| 字段名称 | 长度 | 说明 |
|---|---|---|
| 功能码 | 1字节 | 固定为 0x03 |
| 字节计数 | 1字节 | 后续寄存器数据的字节数(寄存器数×2) |
| 寄存器值 | N字节 | 寄存器值,每个寄存器2字节,高字节在前 |
| 字段名称 | 长度 | 说明 |
|---|---|---|
| 功能码 | 1字节 | 0x83 (0x03 + 0x80) |
| 异常码 | 1字节 | 错误类型代码 |
04 - 读输入寄存器 (Read Input Registers)
| 字段名称 | 长度 | 说明 |
|---|---|---|
| 功能码 | 1字节 | 指定要执行的操作类型 (0x04) |
| 起始地址 | 2字节 | 标识目标寄存器的起始地址 (0x0000-0xFFFF) |
| 寄存器数量 | 2字节 | 指定要读取的寄存器数量 (1-125) |
| 字段名称 | 长度 | 说明 |
|---|---|---|
| 功能码 | 1字节 | 固定为 0x04 |
| 字节计数 | 1字节 | 后续寄存器数据的字节数(寄存器数×2) |
| 寄存器值 | N字节 | 寄存器值,每个寄存器2字节,高字节在前 |
| 字段名称 | 长度 | 说明 |
|---|---|---|
| 功能码 | 1字节 | 0x84 (0x04 + 0x80) |
| 异常码 | 1字节 | 错误类型代码 |
写入功能码
05 - 写单个线圈 (Write Single Coil)
| 字段名称 | 长度 | 说明 |
|---|---|---|
| 功能码 | 1字节 | 指定要执行的操作类型 (0x05) |
| 线圈地址 | 2字节 | 标识目标线圈的地址 (0x0000-0xFFFF) |
| 线圈值 | 2字节 | 指定线圈的状态 (0x0000=OFF 或 0xFF00=ON) |
| 字段名称 | 长度 | 说明 |
|---|---|---|
| 功能码 | 1字节 | 固定为 0x05 |
| 线圈地址 | 2字节 | 被写入的线圈地址(与请求相同) |
| 线圈值 | 2字节 | 写入的线圈值(与请求相同) |
| 字段名称 | 长度 | 说明 |
|---|---|---|
| 功能码 | 1字节 | 0x85 (0x05 + 0x80) |
| 异常码 | 1字节 | 错误类型代码 |
06 - 写单个寄存器 (Write Single Register)
| 字段名称 | 长度 | 说明 |
|---|---|---|
| 功能码 | 1字节 | 指定要执行的操作类型 (0x06) |
| 寄存器地址 | 2字节 | 标识目标寄存器的地址 (0x0000-0xFFFF) |
| 寄存器值 | 2字节 | 指定寄存器的值 (0x0000-0xFFFF) |
| 字段名称 | 长度 | 说明 |
|---|---|---|
| 功能码 | 1字节 | 固定为 0x06 |
| 寄存器地址 | 2字节 | 被写入的寄存器地址(与请求相同) |
| 寄存器值 | 2字节 | 写入的寄存器值(与请求相同) |
| 字段名称 | 长度 | 说明 |
|---|---|---|
| 功能码 | 1字节 | 0x86 (0x06 + 0x80) |
| 异常码 | 1字节 | 错误类型代码 |
15 - 写多个线圈 (Write Multiple Coils)
| 字段名称 | 长度 | 说明 |
|---|---|---|
| 功能码 | 1字节 | 指定要执行的操作类型 (0x0F) |
| 起始地址 | 2字节 | 标识目标线圈的起始地址 (0x0000-0xFFFF) |
| 线圈数量 | 2字节 | 指定要写入的线圈数量 (1-1968) |
| 字节计数 | 1字节 | 指定后续数据字节数 |
| 线圈值 | N字节 | 指定线圈的状态 (按位打包) |
| 字段名称 | 长度 | 说明 |
|---|---|---|
| 功能码 | 1字节 | 固定为 0x0F |
| 起始地址 | 2字节 | 写入的起始线圈地址(与请求相同) |
| 线圈数量 | 2字节 | 成功写入的线圈数量(与请求相同) |
| 字段名称 | 长度 | 说明 |
|---|---|---|
| 功能码 | 1字节 | 0x8F (0x0F + 0x80) |
| 异常码 | 1字节 | 错误类型代码 |
16 - 写多个寄存器 (Write Multiple Registers)
| 字段名称 | 长度 | 说明 |
|---|---|---|
| 功能码 | 1字节 | 指定要执行的操作类型 (0x10) |
| 起始地址 | 2字节 | 标识目标寄存器的起始地址 (0x0000-0xFFFF) |
| 寄存器数量 | 2字节 | 指定要写入的寄存器数量 (1-123) |
| 字节计数 | 1字节 | 指定后续数据字节数 |
| 寄存器值 | N字节 | 指定寄存器的值 |
| 字段名称 | 长度 | 说明 |
|---|---|---|
| 功能码 | 1字节 | 固定为 0x10 |
| 起始地址 | 2字节 | 写入的起始寄存器地址(与请求相同) |
| 寄存器数量 | 2字节 | 成功写入的寄存器数量(与请求相同) |
| 字段名称 | 长度 | 说明 |
|---|---|---|
| 功能码 | 1字节 | 0x90 (0x10 + 0x80) |
| 异常码 | 1字节 | 错误类型代码 |
诊断功能码
08 - 诊断 (Diagnostics)
| 字段名称 | 长度 | 说明 |
|---|---|---|
| 功能码 | 1字节 | 指定要执行的操作类型 (0x08) |
| 子功能码 | 2字节 | 标识诊断操作的类型 |
| 数据 | N字节 | 诊断数据,根据子功能码而定 |
| 字段名称 | 长度 | 说明 |
|---|---|---|
| 功能码 | 1字节 | 固定为 0x08 |
| 子功能码 | 2字节 | 与请求相同的子功能码 |
| 数据 | N字节 | 诊断响应数据,根据子功能码而定 |
| 字段名称 | 长度 | 说明 |
|---|---|---|
| 功能码 | 1字节 | 0x88 (0x08 + 0x80) |
| 异常码 | 1字节 | 错误类型代码 |
17 - 报告从站 ID (Report Slave ID)
| 字段名称 | 长度 | 说明 |
|---|---|---|
| 功能码 | 1字节 | 指定要执行的操作类型 (0x11) |
| 字段名称 | 长度 | 说明 |
|---|---|---|
| 功能码 | 1字节 | 固定为 0x11 |
| 字节计数 | 1字节 | 后续数据的字节数 |
| 从站ID | N字节 | 从站标识信息 |
| 运行状态 | 1字节 | 从站运行状态 |
| 字段名称 | 长度 | 说明 |
|---|---|---|
| 功能码 | 1字节 | 0x91 (0x11 + 0x80) |
| 异常码 | 1字节 | 错误类型代码 |
📊 功能码总结
常用功能码速查表
| 功能码 | 名称 | 操作类型 | 数据类型 | 响应特点 |
|---|---|---|---|---|
| 0x01 | 读线圈状态 | 读取 | 1位布尔值 | 返回字节计数+位打包数据 |
| 0x02 | 读离散输入 | 读取 | 1位布尔值 | 返回字节计数+位打包数据 |
| 0x03 | 读保持寄存器 | 读取 | 16位数值 | 返回字节计数+寄存器值 |
| 0x04 | 读输入寄存器 | 读取 | 16位数值 | 返回字节计数+寄存器值 |
| 0x05 | 写单个线圈 | 写入 | 1位布尔值 | 回显请求内容 |
| 0x06 | 写单个寄存器 | 写入 | 16位数值 | 回显请求内容 |
| 0x0F | 写多个线圈 | 写入 | 1位布尔值 | 返回地址+数量 |
| 0x10 | 写多个寄存器 | 写入 | 16位数值 | 返回地址+数量 |
响应数据解析要点
解析技巧
读取操作响应:
- 包含字节计数字段,指示后续数据长度
- 线圈/输入状态按位打包,LSB对应最小地址
- 寄存器值采用大端序(高字节在前)
写入操作响应:
- 单个写入:完全回显请求内容
- 多个写入:返回起始地址和数量确认
异常响应:
- 功能码 = 原功能码 + 0x80
- 包含具体的异常码说明错误类型
完整响应结构
本文档提供了所有功能码的请求和响应格式概览。
详细的响应数据结构、解析方法和实际示例,请参考:
📨 响应数据结构详解
该文档包含:
- 每种响应的完整字段说明
- 字节序和位操作处理方法
- 数据类型转换技巧
- 时序要求和验证方法
- 大量实际解析示例
这份功能码详细说明涵盖了 Modbus 协议中的所有标准功能码,结合响应数据结构文档,可以帮助你完全掌握 Modbus 通信的各个方面。