Modbus 기능 코드完全분석:从基础到进阶的 21 个표준기능 코드实战指南

무료무료 기술 자료

이 글은 바로 읽을 수 있으며 기초 학습과 검색 유입에 적합합니다.

Modbus 기능 코드完全분석:从基础到进阶的 21 个표준기능 코드实战指南

关键词:Modbus 기능 코드、Modbus 기능 코드、Modbus 01 02 03 04 05 06 15 16、Modbus 读레지스터、Modbus 写코일

기능 코드(기능 코드)是 Modbus 프로토콜的灵魂。它定义了마스터要对슬레이브执行的操作——是읽기데이터还是쓰기데이터,操作的对象是코일、이산 입력、유지 레지스터还是입력 레지스터。理解每一个기능 코드的用途、프레임형식和适用시나리오,是精通 Modbus 통신的基石。

本文以 Modbus 프로토콜사양 V1.1b3 为蓝本,系统化地분석전체 21 个표준기능 코드(包括公共기능 코드、用户定义기능 코드和保留기능 코드),并配以完整的프레임예제和编程实现,帮助您从「会用的엔지니어링师」进阶为「真正理解的专家」。

一、Modbus 데이터模型与기능 코드的关系

Modbus 功能码完全解析:从基础到进阶的 21 个标准功能码实战指南插图
▲ 图1:Modbus 기능 코드体系架构 — 位操作类与레지스터操作类完整分类。

在深入기능 코드之前,必须先理解 Modbus 的데이터模型。Modbus 定义了四种데이터区域:

데이터区域访问유형大小주소范围典型用途
코일(Coils)读写1 bit00001-09999数字量출력(DO)
이산 입력(Discrete Inputs)只读1 bit10001-19999数字量입력(DI)
유지 레지스터(Holding 회원가입s)读写16 bit40001-49999模拟量출력/매개변수
입력 레지스터(Input 회원가입s)只读16 bit30001-39999模拟量입력(AI)

重要提示:在实际프로토콜프레임中,使用的是从 0 开始的「프로토콜주소」。例如,유지 레지스터 40001 对应的프로토콜주소是 0x0000。这个「偏移 1」的设计是初学者最容易混淆的地方。

二、기능 코드分类体系

Modbus 기능 코드分为三大类:

  • 公共기능 코드(1-64, 73-99, 111-127):由 Modbus 组织표준化定义,确保不同厂商设备之间的互操作性
  • 用户定义기능 코드(65-72, 100-110):留给设备厂商自定义实现,不具备通用性
  • 保留기능 코드:已被某些公司用于传统产品(如 8-11, 12-15 等)

三、位操作기능 코드(Bit Access)深度분석

Modbus 功能码完全解析:从基础到进阶的 21 个标准功能码实战指南插图1
▲ 图2:四大데이터模型(코일/이산 입력/유지 레지스터/입력 레지스터)与기능 코드的完整映射关系。

3.1 기능 코드 0x01 — 读코일(Read Coils)

功能:읽기슬레이브中连续코일(DO)的 ON/OFF 状态。这是最基本的位읽기操作。

请求프레임(RTU):

슬레이브 주소 | 0x01 | 시작주소高 | 시작주소低 | 数量高 | 数量低 | CRC
예제:읽기슬레이브 1 的코일 0x0013~0x0037(20~56 号코일,共 37 个)
01 01 00 13 00 25 [CRC]
→ 슬레이브 주소=1, 기능 코드=0x01, 시작주소=0x0013(19), 数量=0x0025(37)

响应프레임:

슬레이브 주소 | 0x01 | 바이트数 | 데이터... | CRC
01 01 05 CD 6B B2 0E 1B [CRC]
→ 5 个바이트데이터, CD=1100 1101 (코일 27-20 的状态)

关键约束:

  • 单次最多읽기 2000 个코일(0x07D0)
  • 响应中的位打包规则:第一个바이트的 LSB 对应시작주소코일
  • 如果请求的数量不是 8 的倍数,最后一个바이트的高位用 0 填充

3.2 기능 코드 0x02 — 读이산 입력(Read Discrete Inputs)

功能:읽기슬레이브中连续이산 입력(DI)的状态。프레임형식与 0x01 完全相同,但操作的是只读的이산 입력区。

与 0x01 的区别:0x01 읽기的是可读写的코일(通常对应物理 DO),而 0x02 읽기的是只读的이산 입력(通常对应物理 DI 如限位开关、센서状态等)。

예제:읽기슬레이브 1 的이산 입력 0x00C4~0x00DB(197~220,共 24 个)
请求: 01 02 00 C4 00 18 [CRC]
响应: 01 02 03 AC DB 35 [CRC]
→ 3 个바이트, AC=1010 1100, DB=1101 1011, 35=0011 0101

3.3 기능 코드 0x05 — 写单个코일(Write Single Coil)

功能:将单个코일设置为 ON 或 OFF。这是最简单的写操作。

请求프레임:

슬레이브 주소 | 0x05 | 코일주소高 | 코일주소低 | 출력值高 | 출력值低 | CRC
출력值: 0xFF00 表示 ON, 0x0000 表示 OFF

예제:将슬레이브 1 的코일 0x00AC(173 号)置为 ON
01 05 00 AC FF 00 [CRC]

响应프레임:正常响应与请求完全一致(回显)。

编程예제(Python):

import minimalmodbus
instrument = minimalmodbus.Instrument('/dev/ttyUSB0', 1)
instrument.serial.baudrate = 9600
# 写单个코일: 주소 0x00AC = ON
instrument.write_bit(0x00AC, 1)

3.4 기능 코드 0x0F — 写多个코일(Write Multiple Coils)

功能:一次性쓰기多个连续코일。当需要同时控制多个 DO 时,0x0F 比多次调用 0x05 高效得多。

请求프레임형식:
슬레이브 주소 | 0x0F | 시작주소高 | 시작주소低 | 数量高 | 数量低 | 바이트数 | 데이터... | CRC

예제:将슬레이브 1 的코일 0x0013~0x001C(20~29,共 10 个코일)分别置为:
20: ON, 21: OFF, 22: ON, 23: ON, 24: OFF, 25: ON, 26: ON, 27: OFF, 28: ON, 29: OFF
2진수: 01 0110 1101 → 高位补0 → 0xCD01... 等等这里需要仔细계산
实际프레임: 01 0F 00 13 00 0A 02 CD 01 [CRC]

四、레지스터操作기능 코드(16-bit Access)深度분석

4.1 기능 코드 0x03 — 读유지 레지스터(Read Holding 회원가입s)

功能:읽기连续유지 레지스터的值。这是 Modbus 中使用频率最高的기능 코드,没有之一。几乎所有데이터采集시나리오都使用 0x03。

请求프레임형식:
슬레이브 주소 | 0x03 | 시작주소高 | 시작주소低 | 레지스터 수량高 | 레지스터 수량低 | CRC

예제:읽기슬레이브 1 的유지 레지스터 0x006B~0x006D(108~110,共 3 个레지스터)
请求: 01 03 00 6B 00 03 [CRC]
响应: 01 03 06 02 2B 00 00 00 64 [CRC]
→ 6 个바이트 = 3 个레지스터 × 2
→ 레지스터 108: 0x022B = 555
→ 레지스터 109: 0x0000 = 0
→ 레지스터 110: 0x0064 = 100

关键约束:

  • 单次最多읽기 125 个레지스터(0x007D)
  • 如果읽기 32 位데이터(float32/int32),确保레지스터 수량为偶数
  • 바이트序문제:不同设备可能使用大端或小端存储多바이트데이터

4.2 기능 코드 0x04 — 读입력 레지스터(Read Input 회원가입s)

功能:읽기连续입력 레지스터的值。프레임형식与 0x03 完全相同,但操作的是只读的입력 레지스터区(如 ADC 采样值、센서原始值等)。

예제:읽기슬레이브 1 的입력 레지스터 0x0008(주소 9,AI 通道 1)
请求: 01 04 00 08 00 01 [CRC]
响应: 01 04 02 00 0A [CRC]
→ 입력 레지스터 9 的值 = 0x000A = 10

4.3 기능 코드 0x06 — 写单个레지스터(Write Single 회원가입)

功能:向单个유지 레지스터쓰기 16 位数值。

请求프레임형식:
슬레이브 주소 | 0x06 | 레지스터주소高 | 레지스터주소低 | 쓰기值高 | 쓰기值低 | CRC

예제:将슬레이브 1 的유지 레지스터 0x0001 쓰기值 0x0003
请求: 01 06 00 01 00 03 [CRC]
响应: 01 06 00 01 00 03 [CRC](回显)

编程예제(C#):

// 使用 NModbus4 库
using Modbus.Device;
using System.IO.Ports;

var port = new SerialPort("COM3", 9600, Parity.None, 8, StopBits.One);
port.Open();
var master = ModbusSerialMaster.CreateRtu(port);
master.WriteSingle회원가입(1, 0x0001, 3); // 슬레이브1, 주소1, 值3

4.4 기능 코드 0x10 — 写多个레지스터(Write Multiple 회원가입s)

功能:一次性쓰기多个连续유지 레지스터。这是批量설정매개변수的效率利器。

请求프레임형식:
슬레이브 주소 | 0x10 | 시작주소高 | 시작주소低 | 레지스터 수량高 | 레지스터 수량低 | 바이트数 | 데이터... | CRC

예제:向슬레이브 1 的레지스터 0x0001 和 0x0002 分别쓰기 0x000A 和 0x0102
请求: 01 10 00 01 00 02 04 00 0A 01 02 [CRC]
→ 바이트数=4(2个레지스터×2)
响应: 01 10 00 01 00 02 [CRC]
→ 响应仅返回시작주소和레지스터 수량

关键约束:

  • 单次最多쓰기 123 个레지스터(0x007B)
  • 바이트数必须等于「레지스터 수량 × 2」
  • 쓰기失败可能导致슬레이브매개변수混乱,建议先备份

五、高级기능 코드详解

5.1 기능 코드 0x07 — 读异常状态(Read Exception Status)

功能:快速읽기슬레이브的 8 个异常状态位。这是一个简单但强大的诊断기능 코드,请求프레임只有 2 个바이트(주소+기능 코드),响应也只有 3 个바이트。

请求: 01 07 [CRC]
响应: 01 07 6D [CRC]
→ 状态바이트 0x6D = 0110 1101,各厂商定义各 bit 含义

5.2 기능 코드 0x08 — 诊断(Diagnostics)

功能:用于통신链路诊断,共有 16 个子기능 코드。最常见的用途是「回路测试」(子기능 코드 0x0000),用来检测슬레이브是否在线并能正常处理프레임。

子기능 코드名称用途
0x0000回路测试回显请求데이터,验证통신链路
0x000A清计数器清零통신事件计数器
0x000B读总线消息计数읽기슬레이브检测到的总线消息总数
0x000C读통신오류 카운트읽기 CRC 검증错误次数
0x000D读异常오류 카운트읽기슬레이브返回的异常响应次数
0x000E读슬레이브消息计数읽기슬레이브已处理的消息数
0x000F读슬레이브无响应计数읽기因广播而无需响应的消息数
回路测试예제:
请求: 01 08 00 00 12 34 [CRC]  → 子기능 코드=0x0000, 데이터=0x1234
响应: 01 08 00 00 12 34 [CRC]  → 必须完全回显请求데이터

5.3 기능 코드 0x0B — 读통신事件计数器

返回슬레이브的통신事件计数器和状态字,用于监控통신质量。

5.4 기능 코드 0x16 — 掩码写레지스터(Mask Write 회원가입)

功能:使用 AND 掩码和 OR 掩码对单个레지스터进行位操作。这是 Modbus 中最巧妙的기능 코드之一——它允许在不읽기当前值的情况下,原子性地修改레지스터的特定位。

请求프레임형식:
슬레이브 주소 | 0x16 | 주소高 | 주소低 | AND掩码高 | AND掩码低 | OR掩码高 | OR掩码低 | CRC

操作逻辑: Result = (Current_Value AND And_Mask) OR (Or_Mask AND (NOT And_Mask))

예제:将레지스터 0x0004 的 bit 0~3 清零,同时设置 bit 4~7 = 0b1010
AND掩码 = 0xFFF0(清除低4位), OR掩码 = 0x00A0(设置 bit5 和 bit7)
请求: 01 16 00 04 FF F0 00 A0 [CRC]

六、기능 코드对比速查表

기능 코드名称操作对象操作유형最多数量使用频率
0x01Read Coils코일读2000★★★★☆
0x02Read Discrete Inputs이산 입력读2000★★★☆☆
0x03Read Holding 회원가입s유지 레지스터读125★★★★★
0x04Read Input 회원가입s입력 레지스터读125★★★★☆
0x05Write Single Coil코일写1★★★☆☆
0x06Write Single 회원가입유지 레지스터写1★★★★★
0x0FWrite Multiple Coils코일写1968★★★☆☆
0x10Write Multiple 회원가입s유지 레지스터写123★★★★★
0x16Mask Write 회원가입유지 레지스터读写1★★☆☆☆
0x17Read/Write Multiple Regs유지 레지스터读写125/121★★☆☆☆

七、기능 코드选择决策树

在实际개발中,选择合适的功码码是关键决策。以下是选择决策流程:

  • 需要읽기数字量출력 상태? → 0x01(코일)/ 0x02(이산 입력)
  • 需要읽기模拟量或매개변수? → 0x03(유지 레지스터)/ 0x04(입력 레지스터)
  • 需要设置单个数字量출력? → 0x05
  • 需要设置单매개변수? → 0x06
  • 需要批量设置매개변수? → 0x10
  • 需要批量设置数字量출력? → 0x0F
  • 需要修改매개변수的某些位而不影响其他位? → 0x16
  • 需要同时读写(如읽기旧매개변수并쓰기新매개변수原子操作)? → 0x17

八、常见陷阱与最佳实践

8.1 바이트序陷阱

Modbus 프로토콜规定 16 位레지스터使用大端바이트序(Big-Endian),但 32 位데이터(如 float32)的바이트序在프로토콜层面没有规定。常见的有四种排列방식:

排列방식레지스터 1레지스터 2常见厂商
ABCD (Big-Endian)高16位低16位施耐德、ABB
CDAB (Little-Endian)低16位高16位西门子 S7-200
BADC (Word-Swap Big)바이트交换-部分国产品牌
DCBA (Word-Swap Little)完全颠倒-少数特殊设备

8.2 广播주소(주소 0)

在 RTU 모드下,使用슬레이브 주소 0 表示广播——所有슬레이브都执行命令,但都不返回响应。只有写操作기능 코드(0x05, 0x06, 0x0F, 0x10)支持广播。

8.3 一次请求勿贪多

虽然사양允许 0x03 一次읽기 125 个레지스터,但不建议一次읽기太多。原因:

  • 增大통신지연(통신 속도 9600 时,125 个레지스터需要약 270ms)
  • 추가 CRC 검증出错的概率
  • 部分슬레이브的内存限制可能导致缓冲区溢出

建议:单次읽기控制在 20~50 个레지스터以内,分为多个小批次읽기。

九、实际案例:构建 Modbus 데이터采集系统

以下是一个典型的 Modbus 데이터采集流程,展示了如何组合使用不同的기능 코드:

// C 언어伪代码 - 典型 Modbus 采集流程
void modbus_acquisition_task(void) {
    // 步骤 1: 읽기设备状态(이산 입력)
    uint8_t di_데이터[2];
    modbus_read_inputs(0x02, &di_데이터, 16);  // 读16个DI
    
    // 步骤 2: 읽기模拟量(입력 레지스터)
    uint16_t ai_데이터[8];
    modbus_read_input_regs(0x00, &ai_데이터, 8); // 读8个AI通道
    
    // 步骤 3: 읽기运行매개변수(유지 레지스터)
    uint16_t params[20];
    modbus_read_holding_regs(0x00, &params, 20);
    
    // 步骤 4: 根据业务逻辑쓰기控制命令
    if (need_시작_motor) {
        modbus_write_coil(0x0005, 1); // 启动모터
    }
    
    // 步骤 5: 如果需要修改매개변수
    if (need_set_temp) {
        modbus_write_register(0x0010, 250); // 设定온도 25.0°C
    }
}

十、总结

기능 코드是 Modbus 프로토콜的「动词」——它定义了마스터对슬레이브做什么操作。掌握了기능 코드的프레임형식和适用시나리오,就等于掌握了 Modbus 통신的核心语法。建议将本文的기능 코드速查表和决策树作为日常개발的参考手册,在实际디버깅中逐步加深理解。

在다음 글中,我们将深入对比 Modbus RTU 和 Modbus TCP 两种传输모드的差异,从物理层到적용层全面분석两者的适用시나리오和性能特点。

相关阅读:Modbus 异常响应码与故障排查完全手册 | Modbus RTU 与 TCP 深度对比 | Modbus CRC 검증원리与编程实现

실제 프로젝트에 이 자료를 활용하시겠습니까?

도구 센터에서 프레임 분석, CRC 검증, 장비 디버깅을 진행하거나 요청을 제출하여 선정 및 연동 제안을 받아보세요.

엔지니어 회원

이 글을 실행 가능한 디버깅 자료로 활용하세요

가입하면 고급 프레임 분석, 자료 패키지 다운로드, 코드 예제, 엔지니어링 사례, 우선 기술 지원을 이용할 수 있어 실제 프로젝트 납품에 적합합니다.

고급 도구 무제한 이용
자료 패키지와 코드 패키지
완전한 엔지니어링 사례 라이브러리
우선 기술 지원 채널

답글 작성

이메일 주소는 공개되지 않습니다. 必填项已用 * 标注