Modbus 기능 코드

무료무료 기술 자료

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

Modbus 功能码

Modbus 기능 코드是 Modbus 消息帧(프레임)的重要组成部分,是 Modbus 프로토콜中통신事务处理的基础。

Modbus 功能码插图

개요​

Modbus 기능 코드占用一个바이트,取值范围是 1~127(即 0x01~0x7F)。同时,使用기능 코드 + 0x80 表示异常状态,即 129~255 代表异常码。

在 Modbus 표준프로토콜中,一共规定了三类 Modbus 기능 코드。

  1. 公共기능 코드
    • 被明确定义的기능 코드;
    • 保证唯一性;
    • 由 Modbus 协会确认,并提供公开的문서;
    • 可进行一致性测试;
    • 包括프로토콜定义的기능 코드和保留将来使用的기능 코드。
  2. 用户自定义기능 코드
    • 有两个用户自定义기능 코드区域,分别是 6572 和 100110;
    • 用户自定义,不保证唯一性。
  3. 保留기능 코드
    • 保留기능 코드是因为历史遗留原因,某些公司的传统产品上现行使用的기능 코드不作为公共使用。

本튜토리얼主要介绍公共기능 코드,下表展示了 Modbus 프로토콜中的部分公共기능 코드。

代码名称英文레지스터 PLC 주소位/字操作操作数量
01读코일 상태Read Coils00001~09999位操作单个或多个
02读이산 입력状态Read Discrete Inputs10001~19999位操作单个或多个
03读유지 레지스터Read Holding 회원가입s40001~49999字操作单个或多个
04读입력 레지스터Read Input 회원가입s30001~39999字操作单个或多个
05写单个코일Write Single Coil00001~09999位操作单个
06写单个유지 레지스터Write Single 회원가입40001~49999字操作单个
15写多个코일Write Multiple Coils00001~09999位操作多个
16写多个유지 레지스터Write Multiple 회원가입s40001~49999字操作多个

기능 코드的操作可分为两种:

  • 位操作 —— 最小单位为一位(bit),包括读코일 상태기능 코드 01、读이산 입력状态기능 코드 02、写单个코일기능 코드 05 和写多个코일기능 코드 15;
  • 字操作 —— 最小单位为两个바이트,包括读유지 레지스터기능 코드 03、读입력 레지스터기능 코드 04、写单个유지 레지스터기능 코드 06 和写多个유지 레지스터기능 코드 16。

기능 코드​

0x01 읽기코일/离散量출력值​

  • 该기능 코드用于읽기从设备的코일或离散量출력的状态,即各 DO(Discrete Output,离散출력)的 ON/OFF 状态。
  • 消息帧中指定了需읽기的코일시작주소和코일数目。
  • 시작주소由 2 个바이트构成,取值范围为 0x0000 到 0xFFFF。
  • 코일 수량由 2 个바이트构成,取值范围为 0x0001 到 0x07D0(即10진수 1~2000)。
  • 需要注意,在 Modbus 프로토콜规定的 PDU 中,规定所有코일或레지스터주소从 0 开始계산。

0x02 읽기离散量입력值​

  • 该기능 코드用于읽기从设备的이산 입력,即 DI(Discrete Input)的 ON/OFF 状态。
  • 消息帧中指定了需읽기的离散입력 레지스터시작주소和数目,可읽기 1~2000 个连续的离散量입력 상태。
  • 如果从设备接受主设备的请求则回复기능 코드 02,并返回离散量입력各변수的当前状态(如果返回的 DI 数量不是 8 的整数倍,将用 0 填充最后데이터바이트的剩余位)。
  • 시작주소由 2 个바이트构成,取值范围为 0x0000 到 0xFFFF。
  • 离散量数量由 2 个바이트构成,取值范围为 0x0001 到 0x07D0(即10진수 1~2000),最多一次可읽기 2000 个이산 입력状态值。

0x03 유지 레지스터 읽기 (FC03)值​

  • 该기능 코드用于읽기从设备유지 레지스터的콘텐츠,不支持广播모드。
  • 消息帧中指定了需읽기的유지 레지스터的시작주소和数目,而유지 레지스터中各주소的具体콘텐츠和意义则由设备개발者自行规定。
  • 시작주소由 2 个바이트构成,取值范围为 0x0000 到 0xFFFF。
  • 레지스터 수량由 2 个바이트构成,取值范围为 0x0001 到 0x007D(即10진수 1~125),最多一次可连续읽기 125 个레지스터 값。
  • 需要注意,Modbus 的유지 레지스터和입력 레지스터是以字(Word)为基本单位的(1Word 等于 2Bytes)。因此,在읽기时需要注意바이트序(大小端)문제。

0x04 입력 레지스터 읽기 (FC04)值​

  • 该기능 코드用于읽기从设备입력 레지스터的콘텐츠,不支持广播모드。(与 03 기능 코드类似)
  • 消息帧中指定了需읽기的입력 레지스터的시작주소和数目,而입력 레지스터中各주소的具体콘텐츠和意义则由设备개발者自行规定。
  • 시작주소由 2 个바이트构成,取值范围为 0x0000 到 0xFFFF。
  • 레지스터 수량由 2 个바이트构成,取值范围为 0x0001 到 0x007D(即10진수 1~125),最多一次可连续읽기 125 个레지스터 값。
  • 同样需要注意바이트序문제。

0x05 写单个코일/单个离散출력​

  • 该기능 코드用于将单个코일레지스터(或离散출력)设置为 ON 或 OFF,支持广播모드。
  • 在广播모드下,所有슬레이브设备的同一주소的值将被统一修改。
  • 消息帧中指定了需要变更的코일주소和设定的状态值。
  • 시작주소由 2 个바이트构成,取值范围为 0x0000 到 0xFFFF。
  • 目标데이터(即查询프레임中的 ON/OFF 状态)由프레임데이터필드的상수指定,0xFF00 表示 ON 状态,0x0000 表示 OFF 状态,其余所有值均是非法的。
  • 需要注意,在 Modbus 프로토콜规定的 PDU 中,规定所有코일或레지스터주소从 0 开始계산。

0x06 写单个유지 레지스터​

  • 该기능 코드用于更新从设备的单个유지 레지스터的值,支持广播모드。
  • 在广播모드下,所有슬레이브设备的同一주소的值将被统一修改。
  • 消息帧中需要指定从设备주소以及需要变更的유지 레지스터주소和设定值。
  • 시작주소由 2 个바이트构成,取值范围为 0x0000 到 0xFFFF。
  • 变更目标데이터由 2 个바이트构成,取值范围为 0x0000 到 0xFFFF。
  • 유지 레지스터以字(Word)为基本单位,쓰기时需要注意目标데이터的바이트序문제。

0x08 诊断功能​

  • 该기능 코드仅用于串行链路,主要用于检测主设备和从设备之间的통신故障,或检测从设备的各种内部故障,该功能不支持广播。
  • 查询프레임中需要指定从设备주소、기능 코드(Modbus Command)以及子기능 코드(Diagnostic Sub-function)。其中,子기능 코드필드为 2 个바이트,用于区别各诊断유형。
  • 在正常的响应프레임中,从设备将原样回复기능 코드和子기능 코드。

常用的 Modbus 诊断子기능 코드定义如下:

기능 코드子기능 코드설명설명
0800(0x00)Return 데이터 Query (Loop-back)原样返回查询프레임
0801(0x01)Re시작 Communications用于初始化并重新启动슬레이브设备
其中,프레임필드
0x00, 0x00 表示保持事件记录
0xFF, 0x00 表示清除事件记录
0802(0x02)Return Diagnostic 회원가입返回诊断레지스터콘텐츠
0803(0x03)Change ASCII Input Delimiter
0804(0x04)Force Listen Only Mode强制被寻址的슬레이브设备进入只听모드
使其与네트워크中的其他设备断开,不返回响应
0810(0x0A)지우기 Counters and Diagnostic 회원가입s清除计数器和诊断레지스터
0811(0x0B)Return Bus Message Count返回总线프레임计数值
0812(0x0C)Return Bus Communication 오답 Count返回总线통신 CRC 出错计数
0813(0x0D)Return Bus Exception 오답 Count返回总线异常计数
0814(0x0E)Return Slave Message Count返回슬레이브设备수신的프레임数量
0815(0x0F)Return Slave No Response Count返回슬레이브设备没有返回响应的프레임数量
0816(0x10)Return Slave NAK Count
0817(0x11)Return Slave Busy Count返回슬레이브设备响应忙的프레임数量
0818(0x12)Return Bus Character Overrun Count返回总线문자超限的프레임数量
0819(0x13)Return IOP Overrun Count (884)
0820(0x14)지우기 Overrun Counter and Flag (884)

0x0B 获取통신事件计数器​

  • 该기능 코드主要用于获取从设备통신计数器中的状态字和事件计数的值,不支持广播모드。
  • 可以通过在통신프레임之前和之后읽기통신事件计数值,来确定从设备是否正常处理프레임。
  • 对于正常完成프레임处理和传输的场合,事件计数器추가 1;而对于异常响应、轮询命令或读事件计数器(即 0x0B 기능 코드)的场合,则计数器不变。
  • 通过 0x08 诊断功能中的 0x01 子功能和 0x0A 子功能,可以复位事件레지스터。

0x0C 获取통신事件记录​

  • 该기능 코드主要用于从从设备获取状态字、事件计数、프레임计数以及事件바이트필드。
  • 其中状态字和事件计数与기능 코드 0x0B 获取的值一致。
  • 프레임计数器包含了加电重启、清除计数器之后的프레임数量,프레임计数与通过 0x08 诊断功能中的 0x0B 子기능 코드获取的值一致。
  • 事件바이트필드包含 0~64 个바이트,定义各种事件。
  • 正常情况下响应프레임包括一个 2 바이트 状态字필드、一个 2 바이트 事件计数필드、一个 2 바이트 消息计数필드以及 0~64 个바이트的事件필드。
  • 由于事件필드是变长的,因此추가了一个 1 바이트 的데이터길이필드,以方便읽기响应데이터。

0x0F 写多个코일​

  • 该기능 코드用于将连续的多个코일(或离散출력)设置为 ON 或 OFF,支持广播모드。
  • 在广播모드下,所有슬레이브设备的同一주소的值将被统一修改。
  • 消息帧中指定了需要变更的코일시작주소和코일数目。
  • 시작주소由 2 个바이트构成,取值范围为 0x0000 到 0xFFFF。
  • 레지스터 수량필드由 2 个바이트构成,取值范围为 0x0001 到 0x07B0。
  • 데이터필드中为逻辑 1 的位对应 ON,逻辑 0 的位对应 OFF。

0x10 写多个유지 레지스터​

  • 该기능 코드用于设置或쓰기从设备유지 레지스터的多个连续的주소块(1~123个레지스터),支持广播모드。
  • 在广播모드下,所有슬레이브设备的同一주소的值将被统一修改。
  • 消息帧中需要指定从设备주소以及需要变更的유지 레지스터주소和数量。
  • 시작주소由 2 个바이트构成,取值范围为 0x0000 到 0xFFFF。
  • 레지스터 수량필드由 2 个바이트构成,取值范围为 0x0001 到 0x007B(即10진수 1~123)。
  • 在实际개발中,该기능 코드常用于方便用户쓰기多바이트유형的데이터,例如浮点数值。因此,需要注意바이트序문제。

0x11 보고서슬레이브 ID​

  • 该기능 코드仅适用于串行链路,用于읽기슬레이브设备的 ID、유형설명、当前状态以及其他信息,不支持广播모드。
  • 查询프레임中没有데이터필드。
  • 响应消息的构成由슬레이브设备决定。

总结​

常用 Modbus 公共기능 코드下表所示。

Modbus 功能码插图1

其中,支持广播모드的기능 코드有:

  • 0x05 写单个코일
  • 0x06 写单个유지 레지스터
  • 0x0F 写多个코일
  • 0x10 写多个유지 레지스터

除了广播모드的프레임以外,其他所有查询프레임都希望能够获取一个正常的响应프레임。如果一切正常,则슬레이브设备将返回一个正常响应프레임,该响应프레임的기능 코드与请求프레임的기능 코드一致。

另外,对于字操作的기능 코드,存在多바이트存储的大小端문제,因此마스터设备和슬레이브设备必须保持一致的规则处理,约定 Modbus 传输中的데이터필드的바이트序。

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

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

엔지니어 회원

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

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

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

답글 작성

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