深入분석Modbus RTU命令与应答机制

무료무료 기술 자료

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

深入解析Modbus RTU命令与应答机制
深入解析Modbus RTU命令与应答机制插图

Modbus RTU프로토콜설명

Modbus是基于主从结构的통신 프로토콜。它使用RS-485, RS-422, RS-232인터페이스,以及이더넷 TCP/IP네트워크(Modbus TCP프로토콜)进行데이터传输。

Modbus RTU消息包括:

  • SlaveID设备的주소
  • 기능 코드
  • 依赖于기능 코드的特殊데이터
  • CRC-16(Modbus)

结构如下:

SlaveID    기능 코드 特殊데이터    CRC16

如果你去掉SlaveID주소和CRC-16(Modbus),你将得到PDU(프로토콜데이터单元)。

SlaveID是设备的주소,可以从0到247之间选择值。值得注意的是,从248到255的주소是保留的。

模块中的데이터存储在四个表中,其中两个是只读的,另外两个是读写的。每个表可以容纳9999个值。

以下是表的总结:

  • 离散출력코일 (DO):读写;레지스터 주소1-9999;HEX주소范围0000到270E
  • 이산 입력触点 (DI):只读;레지스터 주소10001-19999;HEX주소范围0000到270E
  • 模拟입력 레지스터 (AI):只读;레지스터 주소30001-39999;HEX주소范围0000到270E
  • 模拟출력유지 레지스터 (AO):读写;레지스터 주소40001-49999;HEX주소范围0000到270E

每个表都有一个레지스터 주소(例如AO的40001),它对应于一个주소(例如0000)。这种差异被称为"偏移"。表的偏移量分别为1, 10001, 30001和40001。

以一个例子설명:从40108到40110레지스터为设备주소17获取AI值的Modbus RTU请求如下:

11 03 006B 0003 7687

这个分解如下:

  • 11:SlaveID设备주소(10진수中的17或HEX中的11)
  • 03:기능 코드
  • 006B:第一个레지스터的주소(계산为40108-40001 = 107,这是HEX中的6B)
  • 0003:所需的레지스터 수량(从40108到40110获取三个레지스터)
  • 7687:CRC 검증和

Modbus RTU从设备会回复:

11 03 06 AE41 5652 4340 49AD

这转化为:

  • 设备주소:11(或10진수中的17)
  • 기능 코드:03
  • 바이트计数(表示后面跟随6바이트):06
  • 회원가입值AO0、AO1和AO2作为两바이트시퀀스
  • CRC值由49AD给出

模拟출력레지스터的值可以通过多种방식解释,例如:

  • 作为16位无符号整数(范围0至65535)
  • 作为16位有符号整数(范围-32768至32767)
  • 作为两个문자的ASCII문자串
  • 作为离散开/关值(0或1)
  • 作为32位无符号整数(范围0到4,294,967,295)
  • 作为32位有符号整数(范围-2,147,483,648至2,147,483,647)
  • 作为32位单精度IEEE浮点数(范围1.2×10^−38至3.4×10^+38)
  • 作为四문자ASCII문자串
深入解析Modbus RTU命令与应答机制插图1

Modbus RTU命令是什么?

以下是用于읽기和쓰기Modbus RTU레지스터的代码表。

功能代码功能操作데이터유형访问유형
01 (0x01)읽기DO离散출력코일 상태읽기
02 (0x02)읽기DI이산 입력状态읽기
03 (0x03)읽기AO유지 레지스터16位
04 (0x04)읽기AI입력 레지스터16位
05 (0x05)쓰기一个DO强制单코일离散
06 (0x06)쓰기一个AO预设单레지스터16位
15 (0x0F)多DO쓰기强制多코일离散
16 (0x10)多AO쓰기预设多레지스터16位

如何보내기Modbus RTU命令来읽기离散출력?命令0x01

此命令用于읽기DO数字출력的值。

PDU请求指定第一个DO레지스터的시작주소和后续所需的DO值数量。在PDU中,DO值从零开始寻址。

响应中的DO值为一个바이트,对应位的值。

位值定义为1 = ON,0 = OFF。

第一个데이터바이트的低位包含在请求中指定주소的DO值。其余的DO值按照추가的值到바이트的最高值。即从右到左。

如果请求的DO值少于八个,则响应中的其余位将填充为零(从低바이트到高바이트的方向)。바이트计数进一步表示响应中데이터的完整바이트数。

一个从20到56的DO查询예제,针对设备的SlaveID주소17。第一个레지스터的주소将是001316진수=19,因为帐户是从0주소开始的(001416진수=20, -1零偏移=我们得到001316진수=19)。

바이트请求바이트回复
(Hex)필드名(Hex)필드名
11设备주소11设备주소
01功能代码01功能代码
00第一个레지스터주소高바이트05更多的바이트数
13第一个레지스터주소低바이트CDDO 27-20的레지스터 값 (1100 1101)
00레지스터 수량高바이트6BDO 35-28的레지스터 값 (0110 1011)
25레지스터 수량低바이트B2DO 43-36的레지스터 값 (1011 0010)
0ECRC-16(Modbus)0EDO 51-44的레지스터 값 (0000 1110)
84CRC-16(Modbus)1BDO 56-52的레지스터 값 (0001 1011)
45CRC-16(Modbus)
E6CRC-16(Modbus)
DO 27-20的출력 상태显示为바이트CD16진수值,或在2진수系统中为1100 1101。

在레지스터DO 56-52中,右边请求了5位,其余的位填充为零以得到完整的바이트(0001 1011)。

通道---DO 56DO 55DO 54DO 53DO 52
位00011011
16진수1B

如何보내기Modbus RTU命令来읽기数字입력?命令0x02

此命令用于읽기数字입력DI的值。

从레지스터# 10197到10218的DI请求예제,针对设备的SlaveID주소17。第一个레지스터的주소将是00C416진수=196,因为帐户是从0주소开始的。

바이트请求바이트回复
(Hex)필드名(Hex)필드名
11设备주소11设备주소
02功能代码02功能代码
00第一个레지스터주소高바이트03更多的바이트数
C4第一个레지스터주소低바이트ACDI 10204-10197的레지스터 값 (1010 1100)
00레지스터 수량高바이트DBDI 10212-10205的레지스터 값 (1101 1011)
16레지스터 수량低바이트35DI 10218-10213的레지스터 값 (0011 0101)
BACRC-16(Modbus)20CRC-16(Modbus)
A9CRC-16(Modbus)18CRC-16(Modbus)

如何보내기Modbus RTU命令来읽기模拟출력?命令0x03

此命令用于읽기模拟출력AO的值。

从레지스터# 40108到40110的AO请求예제,针对设备的SlaveID주소17。第一个레지스터的주소将是006B16진수=107,因为帐户是从0주소开始的。

바이트请求바이트回复
(Hex)필드名(

Hex) | 필드名
11 | 设备주소 | 11 | 设备주소
03 | 功能代码 | 03 | 功能代码
00 | 第一个레지스터주소高바이트 | 06 | 更多的바이트数
6B | 第一个레지스터주소低바이트 | AE | #40108的레지스터 값高位
00 | 레지스터 수량高바이트 | 41 | #40108的레지스터 값低位
03 | 레지스터 수량低바이트 | 56 | #40109的레지스터 값高位
76 | CRC 검증和 | 52 | #40109的레지스터 값低位
87 | CRC 검증和 | 43 | #40110的레지스터 값高位
40 | #40110的레지스터 값低位
49 | CRC-16(Modbus)
AD | CRC-16(Modbus)

如何보내기Modbus RTU命令来읽기模拟입력?命令0x04

此命令用于읽기模拟입력AI的值。

从레지스터# 30009的AI请求예제,针对设备的SlaveID주소17。第一个레지스터的주소是000816진수=8,因为帐户是从0주소开始的。

바이트请求바이트回复
(Hex)필드名(Hex)필드名
11设备주소11设备주소
04功能代码04功能代码
00第一个레지스터주소高바이트02更多的바이트数
08第一个레지스터주소低바이트00#30009的레지스터 값高位
00레지스터 수량高바이트0A#30009的레지스터 값低位
01레지스터 수량低바이트F8CRC-16(Modbus)
B2CRC-16(Modbus)F4CRC-16(Modbus)
98CRC-16(Modbus)

如何보내기Modbus RTU命令来쓰기离散출력?命令0x05

此命令用于记录DO数字출력的一个值。

值FF 0016진수将출력设置为ON。

值00 0016진수将출력设置为OFF。

所有其他值都无效,且不会影响출력值。

对这样的请求的正常响应是回声(响应中的重复请求),在DO状态已更改后返回。

예제,使用设备的SlaveID주소17的레지스터# 173的DO记录。레지스터주소为00AC16진수=172,因为从0주소开始记录。

바이트请求바이트回复
(Hex)필드名(Hex)필드名
11设备주소11设备주소
05功能代码05功能代码
00第一个레지스터주소高바이트00第一个레지스터주소高바이트
AC第一个레지스터주소低바이트AC第一个레지스터주소低바이트
FF高바이트值FF高바이트值
00低바이트值00低바이트值
4ECRC-16(Modbus)4ECRC-16(Modbus)
8BCRC-16(Modbus)8BCRC-16(Modbus)
DO173출력 상태已从OFF更改为ON。

如何보내기Modbus RTU命令来记录模拟출력?命令0x06

此命令用于记录模拟출력AO的一个值。

예제,使用设备的SlaveID주소17的레지스터# 40002的AO记录。第一个레지스터的주소为000116진수=1,因为从0주소开始记录。

바이트请求바이트回复
(Hex)필드名(Hex)필드名
11设备주소11设备주소
06功能代码06功能代码
00第一个레지스터주소高바이트00第一个레지스터주소高바이트
01第一个레지스터주소低바이트01第一个레지스터주소低바이트
00高바이트值00高바이트值
03低바이트值03低바이트值
9ACRC-16(Modbus)9ACRC-16(Modbus)
9BCRC-16(Modbus)9BCRC-16(Modbus)

如何보내기Modbus RTU命令来쓰기多个离散引脚?命令0x0F

此命令用于记录DO数字출력的多个值。

예제,쓰기多个DO,从设备的SlaveID주소17的레지스터# 20到# 29。레지스터주소为001316진수=19,因为从0주소开始记录。

바이트请求바이트回复
(Hex)필드名(Hex)필드名
11设备주소11设备주소
0F功能代码0F功能代码
00第一个레지스터주소高바이트00第一个레지스터주소高바이트
13第一个레지스터주소低바이트13第一个레지스터주소低바이트
00레지스터 수량高바이트00记录的레지스터 수량高바이트
0A레지스터 수량低바이트0A记录的레지스터 수량低바이트
02更多的바이트数26CRC-16(Modbus)
CDDO 27-20的바이트值 (1100 1101)99CRC-16(Modbus)
01DO 29-28的바이트值 (0000 0001)
BFCRC-16(Modbus)
0BCRC-16(Modbus)

答案返回已记录的레지스터 수량。

如何보내기Modbus RTU命令来记录多个模拟출력?命令0x10

此命令用于记录模拟출력AO的多个值。

예제,记录多个AO,从设备的SlaveID주소17的레지스터# 40002和# 40003。第一个레지스터的주소为000116진수=1,因为从0주소开始记录。

바이트请求바이트回复
(Hex)필드名(Hex)필드名
11设备주소11设备주소
10功能代码10功能代码
00第一个레지스터주소高바이트00第一个레지스터주소高바이트
01第一个레지스터주소低바이트01第一个레지스터주소低바이트
00레지스터 수량高바이트00记录的레지스터 수량高바이트
02레지스터 수량低바이트02记录的레지스터 수량低바이트
04更多的바이트数12CRC-16(Modbus)
0040002高位值98CRC-16(Modbus)
0A40002低位值
0140003高位值
0240003低位值
C6CRC-16(Modbus)
F0CRC-16(Modbus)
深入解析Modbus RTU命令与应答机制插图2

Modbus请求的错误

如果设备수신到一个请求,但无法处理该请求,该设备将以错误代码进行响应。

响应将包含修改后的功能代码,高位바이트为1。

예제:

原始值结果值
요청 내功能代码响应中的功能错误代码
01 (01 hex) 0000 0001129 (81 hex) 1000 0001
02 (02 hex) 0000 0010130 (82 hex) 1000 0010
03 (03 hex) 0000 0011131 (83 hex) 1000 0011
04 (04 hex) 0000 0100132 (84 hex) 1000 0100
05 (05 hex) 0000 0101133 (85 hex) 1000 0101
06 (06 hex) 0000 0110134 (86 hex) 1000 0110
15 (0F hex) 0000 1111143 (8F hex) 1000 1111
16 (10 hex) 0001 0000144 (90 hex) 1001 0000

带有错误的请求和响应예제:

바이트请求바이트响应
(Hex)필드名(Hex)필드名
0A设备주소0A设备주소
01功能代码81已更改的功能代码
04第一个레지스터주소高바이트02错误代码
A1第一个레지스터주소低바이트B0CRC-16(Modbus)
00레지스터 수량高바이트53CRC-16(Modbus)
01레지스터 수량低바이트
ACCRC-16(Modbus)
63CRC-16(Modbus)

错误代码설명

01 | 不能处理已接受的功能代码。
02 | 请求中指定的데이터주소不可用。
03 | 查询데이터필드中包含的值是无效值。
04 | 슬레이브尝试执行请求的操作时发生不可恢复的错误。
05 | 슬레이브已接受请求并正在处理,但需要较长时间。此响应防止主机生成超时错误。
06 | 슬레이브正忙于处理命令。主机在슬레이브空闲时必须重复消息。
07 | 슬레이브无法执行请求中指定的程序功能。使用功能번호13或14的不成功的程序请求返回此代码。主机必须从슬레이브请求诊断信息或错误信息。
08 | 슬레이브在읽기扩展内存时检测到奇짝수 패리티错误。主机可以重复请求,但通常在这种情况下需要维修。

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

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

엔지니어 회원

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

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

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

답글 작성

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