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

Modbus RTU协议描述

Modbus是基于主从结构的通信协议。它使用RS-485, RS-422, RS-232接口,以及Ethernet 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设备地址(十进制中的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(或十进制中的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命令与应答机制插图3

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。第一个寄存器的地址将是0013十六进制=19,因为帐户是从0地址开始的(0014十六进制=20, -1零偏移=我们得到0013十六进制=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的输出状态显示为字节CD十六进制值,或在二进制系统中为1100 1101。

在寄存器DO 56-52中,右边请求了5位,其余的位填充为零以得到完整的字节(0001 1011)。

通道DO 56DO 55DO 54DO 53DO 52
00011011
十六进制1B

如何发送Modbus RTU命令来读取数字输入?命令0x02

此命令用于读取数字输入DI的值。

从寄存器# 10197到10218的DI请求示例,针对设备的SlaveID地址17。第一个寄存器的地址将是00C4十六进制=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。第一个寄存器的地址将是006B十六进制=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。第一个寄存器的地址是0008十六进制=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 00十六进制将输出设置为ON。

值00 00十六进制将输出设置为OFF。

所有其他值都无效,且不会影响输出值。

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

示例,使用设备的SlaveID地址17的寄存器# 173的DO记录。寄存器地址为00AC十六进制=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记录。第一个寄存器的地址为0001十六进制=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。寄存器地址为0013十六进制=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。第一个寄存器的地址为0001十六进制=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命令与应答机制插图5

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 | 从站在读取扩展内存时检测到奇偶校验错误。主机可以重复请求,但通常在这种情况下需要维修。

相关新闻

  • Modbus Poll 异常功能解释与详细说明

    Modbus Poll 异常功能解释与详细说明

    Modbus Poll是一种广泛用于Modbus通信协议的测试工具,它允许用户模拟主设备(通常是客户端)与从设备(通常是服务器)之间的通信,以验证通信的正常性。在Modbus Poll的使用中,用户可能会遇到各种异常功能,这些异常功能对于故障诊断和问题解决至关重要。本文将深入探讨Modbus Poll中的异常功能,为用户提供详细的解释和说明。 Modbus Poll 异常功能的概述 Modbus Poll异常功能是指在使用该工具时可能出现的不正常行为或错误情况。这些异常功能是用户了解问题并采取适…

    Modbus技术文档 2023年11月3日
  • Modbus异常相应代码说明

    Modbus异常相应代码说明

    Modbus通信协议是工业自动化中常用的协议,它允许主设备(通常是客户端)与从设备(通常是服务器)之间进行数据交换。在Modbus通信中,服务器(从设备)必须生成适当的响应来处理请求,并在必要时发送异常响应。本文将深入探讨Modbus响应的生成和异常处理。 Modbus响应类型 Modbus通信中,根据请求的处理结果,可以生成两种类型的响应: Modbus异常响应的目的 Modbus异常响应的主要目的是向客户端提供与请求处理过程中检测到的错误相关的信息。它帮助客户端了解通信问题的具体原因,从而采…

    Modbus技术文档 2023年11月3日
  • 在Modbus通讯中发送时间戳的参考方法

    在Modbus通讯中发送时间戳的参考方法

    在Modbus协议中嵌入时间戳需要一些谨慎考虑,因为Modbus本身没有定义专门的时间戳对象。以下是如何在Modbus(RS485)通信中发送时间戳的一些建议方法和步骤: 如何在Modbus (RS485)通信中发送时间戳 在工业自动化和远程监测应用中,时间戳对于确切的数据关联至关重要。尤其是在Modbus通信中,没有内置的时间戳机制,因此需要特别关注如何嵌入时间戳。以下是实现这一目标的方法和步骤: 步骤1:选择时间戳格式 首先,您需要选择适当的时间戳格式。常见的时间戳格式之一是使用POSIX(…

    Modbus技术文档 2023年10月31日
  • 渐进式解决Modbus通信问题的方法

    渐进式解决Modbus通信问题的方法

    在工业自动化领域,Modbus通信协议是一种常见的选择,但有时会出现通信问题。本文将介绍一些渐进式步骤,以帮助您排查和解决Modbus通信问题。 1:确认从站是否支持Modbus 首先,确保每个从站都真正支持Modbus协议。有时,设备具备Modbus连接器,但却没有可用的硬件或固件支持。因此,在问题排查的第一步,您需要验证每个从站是否具备硬件和固件支持,并且已启用Modbus功能。 2:选择协议 -Modbus RTU还是Modbus ASCII? Modbus协议有两种常见的变种:RTU和A…

    Modbus技术文档 2023年10月30日
  • Modbus如何读取单个及多个寄存器的方法

    Modbus如何读取单个及多个寄存器的方法

    当你涉及工业自动化、传感器和设备之间的通信时,Modbus协议通常会出现在你的工具箱中。Modbus是一种用于读取和控制设备数据的通信协议,它在工业控制系统中得到了广泛的应用。现在,让我们以小白理解的方式来解释Modbus如何读取保持寄存器的数据,包括单个寄存器和多个寄存器的读取。 什么是Modbus? Modbus是一种通信协议,用于连接各种工业设备、传感器和控制器。它允许这些设备之间进行数据交换,以实现监控、控制和数据采集。Modbus协议有不同的变种,包括Modbus RTU、Modbus…

    Modbus技术文档 2023年10月29日
  • 用 Modbus 总线控制 ABB ACS800 系列变频器的方法

    用 Modbus 总线控制 ABB ACS800 系列变频器的方法

    一、硬件的安装和连接: 二、变频器参数设置: 三、变频器的 Modbus 寻址: 地址 数据集 内容 40001 数据字 1.1 控制字 40002 数据字 1.2 给定 1 40003 数据字 1.3 给定 2 40004 数据字 2.1 状态字 40005 数据字 2.2 实际值 1 40006 数据字 2.3 实际值 2 40101-49999 40101-49999 用于参数寄存器,千位和百位对应于参数组号,十位和个位对应于组内参数号&n…

    Modbus技术文档 2023年10月26日

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

邮箱

cloud@modbus.cn

QQ
QQ
微信
微信
分享本页
返回顶部
深入解析Modbus RTU命令与应答机制