Modbus应用程序协议规范V1.1b3

发布时间 2023-04-16 18:47:38作者: 闪亮的敦敦

1.介绍

1.1本文件范围

MODBUS是一种应用层消息传递协议,位于OSI模型的第7级,它在不同类型的总线或网络上连接的设备之间提供客户端/服务器通信。

MODBUS是一种请求/回复协议,并提供由功能码指定的服务。MODBUS功能码是MODBUS请求/回复pdu的元素。本文档的目的是描述在MODBUS事务框架内使用的功能码。

目前,它使用:

  • 以太网上的 TCP/IP。请参见MODBUS消息传递实现指南V1.0a。
  • 在各种媒体上进行的异步串行传输(电线:EIA/TIA-232-E、EIA-422、EIA/TIA-485-A;光纤、无线电等)。
  • MODBUS+,一个高速令牌传递网络。

2.缩写

  • ADU 应用数据单元
  • ADU 应用数据单元控制
  • HMI 人机接口
  • IETF 互联网工程任务组
  • I/O 输入/输出
  • IP 互联网协议
  • MAC 媒体访问控制
  • MB MODBUS协议
  • MBAP MODBUS应用协议
  • PDU 协议数据单元
  • PLC 可编程逻辑控制
  • TCP 传输控制协议

3.背景

MODBUS协议允许在所有类型的网络架构中进行轻松的通信。

每种类型的设备(PLC、HMI、控制面板、驱动程序、运动控制、I/O设备……)都可以使用MODBUS协议启动远程操作。

可以在串行线上和在以太网TCP/IP网络上进行相同的通信。网关允许使用MODBUS协议在几种类型的总线或网络之间进行通信。

4. 一般说明

4.1协议描述

MODBUS 协议定义了一个独立于底层通信层的简单协议数据单元 (PDU)。 MODBUS 协议在特定总线或网络上的映射可以在应用数据单元(ADU)上引入一些附加字段。

MODBUS应用程序数据单元由启动MODBUS事务的客户端构建。该函数向服务器指示要执行什么类型的操作。MODBUS应用程序协议建立了由客户端发起的请求的格式。

MODBUS数据单元的功能码字段以一个字节进行编码。有效代码的范围为1…255十进制(保留的范围为128-255,并用于异常响应)。当消息从客户端发送到服务器设备时,功能码字段会告诉服务器要执行什么类型的操作。功能码“0”无效。

子功能码被添加到一些功能码中,以定义多个操作。

从客户端发送到服务器的消息的数据字段包含服务器用于执行由功能码定义的操作的附加信息。这可以包括离散地址和寄存器地址、要处理的项目数量以及字段中实际数据字节的计数。

在某些类型的请求中,数据字段可能不存在(零长度),在这种情况下,服务器不需要任何附加信息。该功能码单独指定了该操作。

如果在正确接收的MODBUS ADU中所请求的MODBUS功能没有发生错误,则从服务器到客户端的响应的数据字段包含所请求的数据。如果发生与所请求的MODBUS功能相关的错误,则该字段将包含一个异常代码,服务器应用程序可以使用该异常代码来确定下一个要采取的操作。

例如,客户端可以读取一组离散输出或输入的开/关状态,也可以读取/写一组寄存器的数据内容。

当服务器响应客户端时,它将使用功能码字段来指示正常(无错误)响应或发生了某种错误(称为异常响应)。对于正常响应,服务器简单地向请求回显原始功能码。

对于异常响应,服务器返回与请求PDU中的原始功能码相同的代码,其最高有效位设置为逻辑1。

MODBUS PDU 的大小受限于从串行线路网络上的第一个 MODBUS 实现继承的大小约束(最大 RS485 ADU = 256 字节)。

因此:

MODBUS用于串行线通信的PDU=256-服务器地址(1字节)-CRC(2字节)=253字节。

最后:

RS232/RS485 ADU=253字节+Server地址(1字节)+CRC(2字节)=256字节。

TCPMODBUS ADU=253字节+MBAP(7字节)=260字节。

MODBUS协议定义了三个PDU。它们分别是:

  • MODBUS请求PDU, mb_req_pdu
  • MODBUS响应PDU,mb_rsp_pdu
  • MODBUS异常响应PDU,mb_excep_rsp_pdu

对mb_req_pdu的定义为:

mb_req_pdu = {function_code, request_data}

function_code = [1字节]MODBUS功能码

request_data = [n字节]这个字段依赖于功能码,通常包含变量引用、变量计数、数据偏移量、子函数代码。

对mb_rsp_pdu的定义为:

mb_rsp_pdu={function_code,response_data}

function_code=[1字节]MODBUS功能码

response_data=[n字节]这个字段依赖于功能码,通常包含变量引用、变量计数、数据偏移量、子函数代码。

对mb_excep_rsp_pdu的定义为:

mb_excep_rsp_pdu={exception-function_code,request_data}

exception-function_code=[1字节]MODBUS功能码+0x80

exception_code=[1字节]MODBUS异常码定义在表“MODBUS异常代码”(参见第7节)。

4.2数据编码

MODBUS对地址和数据项使用“大端”表示。这意味着,当传输的数值大于一个字节时,将首先发送最高的字节。例如

 

4.3MODBUS数据模型

MODBUS的数据模型基于一系列具有显著特征的表。

这四个主要表包括:

在输入和输出之间的区别,以及在可位寻址和可文字寻址数据项之间的区别,并不意味着任何程序行为。如果这是对相关目标机器最自然的解释,那么认为所有四个表相互叠加是完全可以接受的,而且也是非常常见的。

对于每个主表,该协议允许单独选择65536个数据项,并且这些项的读取或写操作被设计为跨越多个连续的数据项,直到依赖于事务函数代码的数据大小限制。

很明显,所有通过MODBUS(位、寄存器)处理的数据都必须位于设备应用程序内存中。但是内存中的物理地址不应该与数据引用相混淆。唯一的要求是将数据引用与物理地址链接起来。

在MODBUS函数中使用的MODBUS逻辑引用数是从零开始的无符号整数索引。

  • MODBUS模型的实现例子

下面的示例显示了组织设备中数据的两种方法。 可能存在不同的组织方法,但本文档并未对所有组织方法进行描述。 每个设备都可以根据其应用程序拥有自己的数据组织。

示例1:具有4个独立数据块的设备

下面的示例显示了具有数字和模拟、输入和输出的设备中的数据组织。每个块都是独立的,因为来自不同块的数据没有相关性。因此,每个块都可以使用不同的MODBUS函数进行访问。

示例2:只有一个数据块的设备

在本例中,该设备只有1个数据块。相同的数据可以通过几个MODBUS函数获得,或通过16位访问或通过位访问。

4.4MODBUS地址模型

MODBUS应用程序协议精确地定义了PDU寻址规则。在 MODBUS PDU 中,每个数据的寻址范围为 0 到 65535。

它还清楚地定义了由 4 个块组成的 MODBUS 数据模型,这些块包括从 1 到 n 编号的几个元素。

在MODBUS数据模型中,数据块中的每个元素的编号都从1到n。然后,MODBUS数据模型必须绑定到设备应用程序。

MODBUS 数据模型和设备应用程序之间的预映射完全是供应商设备特定的。

上图显示编号为 X 的 MODBUS 数据在 MODBUS PDU X-1 中寻址。

4.5定义 MODBUS 事务

以下状态图描述了在服务器端对MODBUS事务的通用处理。

一旦服务器处理了请求,就会使用适当的MODBUS服务器事务构建MODBUS响应。

根据处理的结果,将构建两种类型的响应:

  • 积极的 MODBUS 响应:
    • 响应功能码=请求功能码
  • MODBUS异常响应:
    • 其目的是向客户提供有关在处理过程中检测到的错误的相关信息;
    • 响应功能码=请求功能码+0x80;
    • 提供了一个异常代码来指示错误的原因。

5.功能码类别

MODBUS功能代码有三类。它们是:

  • 公共功能代码
    • 定义良好的功能码
    • 保证独一无二
    • 已由社区进行验证
    • 公开记录的
    • 有可用的一致性测试
    • 包括已定义的公共分配功能码以及保留供将来使用的未分配功能码
  • 用户定义的功能码
    • 用户定义的功能码有两个范围,即从65到72和从100到110的十进制。
    • 用户可以选择并实现该规范不支持的功能码。
    • 不能保证所选功能码的使用将是唯一的。
    • 如果用户希望将该功能重新定位为公共功能码,他必须启动一个RFC来将更改引入公共类别,并分配一个新的公共功能码。
    • MODBUS组织公司明确保留开发拟议的RFC的权利。
  • 保留功能码
    • 一些公司目前用于遗留产品的功能代码,但不供公众使用。
    • 参考性说明。

5.1公共功能码定义

6.功能码描述

6.1 读取线圈01(0x01)

此功能码用于读取远程设备中从1到2000个线圈的连续状态。请求PDU指定了起始地址,即所指定的第一个线圈的地址,以及线圈的数量。在PDU中,线圈从零开始处理。因此,编号为1-16的线圈被命名为0-15。

响应消息中的线圈被打包为数据字段的每一位一个线圈。 状态表示为 1= ON 和 0= OFF。 第一个数据字节的 LSB 包含查询中寻址的输出。 其他线圈跟随到该字节的高位端,并在后续字节中从低位到高位。

如果返回的输出量不是8的倍数,则最终数据字节中的其余位将用零填充(朝向字节的高阶末端)。“字节计数”字段指定完整字节的数量。

*N = 输出的数量/8,如果余数不为0,则N=N+1

以下是读取离散输出 20–38 的请求示例:

输出27-20的状态显示为字节值CD十六进制。输出27是这个字节的MSB,输出20是LSB。

按照惯例,一个字节中的位显示为 MSB 在左边,LSB 在右边。 因此,第一个字节中的输出从左到右是“27 到 20”。 下一个字节从左到右输出“35 到 28”。 由于位是串行传输的,因此它们从 LSB 流向 MSB: 20 。 . . 27, 28 。 . . 35,以此类推。

在最后一个数据字节中,输出 38-36 的状态显示为字节值 05 十六进制。输出 38 位于左起第六位位置,输出 36 是该字节的 LSB。 剩下的五个高位用零填充。

6.2 读取离散输入 02(0x02)

此功能代码用于读取远程设备中离散输入的1到2000个连续状态。请求PDU指定了起始地址,即指定的第一个输入的地址以及输入的数量。在PDU中,离散输入从零开始被寻址。因此,编号为1-16的离散输入被处理为0-15。

响应消息中的离散输入被打包为数据字段的每一位一个输入。 状态表示为 1=ON; 0 = 关闭。 第一个数据字节的 LSB 包含查询中寻址的输入。 其他输入跟随该字节的高位端,并在后续字节中从低位到高位。

如果返回的输入数量不是 8 的倍数,则最终数据字节中的剩余位将用零填充(朝向字节的高位端)。 字节计数字段指定完整数据字节的数量。

以下是读取离散输入 197 – 218 的请求示例:

离散输入 204–197 的状态显示为字节值 AC 十六进制。输入 204 是该字节的 MSB,输入 197 是 LSB。

离散输入 218–213 的状态显示为字节值 35 十六进制。输入 218 位于左起第三位位置,输入 213 是 LSB。

注意: 剩余的两个位(朝向高阶端)为零填充。

6.3 读取保持寄存器 03(0x03)

该功能码用于读取远程设备中连续的保持寄存器块的内容。 请求 PDU 指定起始寄存器地址和寄存器数量。 在 PDU 寄存器中,从零开始寻址。 因此,编号为 1-16 的寄存器被寻址为 0-15。

响应消息中的寄存器数据被打包为每个寄存器两个字节,每个字节内的二进制内容右对齐。 对于每个寄存器,第一个字节包含高位,第二个字节包含低位。

以下是读取寄存器 108 – 110 的请求示例:

6.4 读取输入寄存器 04(0x04)

该功能码用于读取远程设备中 1 到 125 个连续输入寄存器。 请求 PDU 指定起始寄存器地址和寄存器数量。 在 PDU 寄存器中,从零开始寻址。 因此,编号为 1-16 的输入寄存器寻址为 0-15。

响应消息中的寄存器数据被打包为每个寄存器两个字节,每个字节内的二进制内容右对齐。 对于每个寄存器,第一个字节包含高位,第二个字节包含低位。

下面是一个要读取输入寄存器9的请求的示例:

6.5 写单个线圈 05(0x05)

此功能码用于在远程设备中将单个输出写入 ON 或 OFF。

请求 PDU 指定要强制的线圈的地址。 线圈从零开始寻址。 因此编号为 1 的线圈被寻址为 0。请求的 ON/OFF 状态由线圈值字段中的常量指定。 值 0XFF00 请求线圈开启。 值 0X0000 要求关闭线圈。 所有其他值都是非法的,不会影响线圈。

正常响应是请求的回显,在写入线圈状态后返回。

以下是将线圈 173 写入 ON 的请求示例:

6.6 写单个寄存器 06(0x06)

此功能代码用于在远程设备中写入单个保持寄存器。

请求 PDU 指定要写入的寄存器的地址。 寄存器从零开始寻址。 因此,编号为 1 的寄存器被寻址为 0。

正常响应是请求的回显,在写入寄存器内容后返回。

以下是将寄存器 2 写入 0x0003的请求示例:

6.7 读异常状态 07(0x07)(仅串行线)

该功能码用于读取远程设备中 8 个异常状态输出的内容。

该功能提供了一种访问此信息的简单方法,因为异常输出引用是已知的(函数中不需要输出引用)。

正常响应包含八个异常状态输出的状态。 输出被打包成一个数据字节,每个输出一位。 最低输出参考的状态包含在字节的最低有效位中。

八个异常状态输出的内容是特定于设备的。

下面是一个要读取异常状态的请求的示例:

在本例中,输出数据为 6D 十六进制(0110 1101 二进制)。 从左到右,输出为 OFF-ON-ON-OFF-ON-ON-OFF-ON。 状态从最高地址到最低地址的输出显示。

6.8 诊断 08(0x08)(仅串行线)

MODBUS 功能码 08 提供了一系列测试,用于检查客户端设备和服务器之间的通信系统,或检查服务器内部的各种错误情况。

------未翻译------

6.9 获取Comm事件计数器 11(0x0B)(仅串行线)

该功能码用于从远程设备的通信事件计数器中获取状态字和事件计数。

通过获取一系列消息前后的当前计数,客户端可以确定远程设备是否能正常处理这些消息。

每次成功完成消息后,设备的事件计数器都会增加一次。 对于异常响应、轮询命令或获取事件计数器命令,它不会增加。

事件计数器可以通过诊断功能(代码 08)复位,具有重新启动通信选项(代码 00 01)或清除计数器和诊断寄存器(代码 00 0A)的子功能。

正常响应包含一个两字节的状态字和一个两字节的事件计数。 如果远程设备仍在处理先前发出的程序命令(存在忙状态),则状态字将为全 1(FF FF 十六进制)。 否则,状态字将全为零。

以下是获取远程设备中的通信事件计数器的请求示例:

在此示例中,状态字为 0xFFFF,表示远程设备中的程序功能仍在进行中。事件计数显示设备已计数了 264 个(01 08 hex)事件。

6.10 获取Comm事件日志 12(0x0C)(仅串行线)

此功能代码用于从远程设备获取状态字、事件计数、消息计数和事件字节字段。

状态字和事件计数与获取通信事件计数器功能(11,0B 十六进制)返回的相同。

消息计数器包含远程设备自上次重启、清除计数器操作或上电以来处理的消息数量。 此计数与诊断功能(代码 08)、子功能返回总线消息计数(代码 11,0B 十六进制)返回的计数相同。

事件字节字段包含 0-64 个字节,每个字节对应于远程设备的一个 MODBUS 发送或接收操作的状态。 远程设备按时间顺序将事件输入字段。 字节 0 是最近的事件。 每个新字节都会从字段中刷新最旧的字节。

正常响应包含一个两字节的状态字字段、一个两字节的事件计数字段、一个两字节的消息计数字段和一个包含 0-64 字节事件的字段。 字节计数字段定义了这四个字段中数据的总长度。

以下是在远程设备中获取通信事件日志的请求示例:

-------未翻译-------

6.11 写多个线圈 15(0x0F)

该功能码用于在远程设备中强制线圈序列中的每个线圈打开或关闭。 请求 PDU 指定要强制的线圈参考。 线圈从零开始寻址。 因此编号为 1 的线圈寻址为 0。

请求的开/关状态由请求数据字段的内容指定。字段位位置的逻辑“1”请求相应输出的ON。逻辑上的“0”请求其关闭。

正常响应返回功能码、起始地址、强制线圈数量。

以下是从线圈 20 开始写入一系列 10 个线圈的请求示例:

请求数据内容为两个字节:CD 01 hex(1100 1101 0000 0001 binary)。 二进制位对应于以下方式的输出:

传输的第一个字节(CD 十六进制)寻址输出 27-20,最低有效位寻址该组中的最低输出 (20)。

传输的下一个字节(01 十六进制)寻址输出 29-28,最低有效位寻址该组中的最低输出 (28)。 最后一个数据字节中未使用的位应填零。

6.12 写多个寄存器 16(0x10)

该功能码用于在远程设备中写入一块连续的寄存器(1 到 123 个寄存器)。

请求的写入值在请求数据字段中指定。 数据被打包为每个寄存器的两个字节。

正常响应返回功能码、起始地址和写入的寄存器数量。

这是一个请求写入两个寄存器的示例:

6.13 报告服务器ID 17(0x11)

6.14 读取文件记录 20(0x14)

6.15 写文件记录 21(0x15)

6.16 掩码写入寄存器(Mask Write Register) 22(0x16)

该功能码用于使用AND掩码、OR掩码和寄存器当前内容的组合来修改指定保持寄存器的内容。 该功能可用于设置或清除寄存器中的各个位。

该请求指定要写入的保持寄存器、用作 AND 掩码的数据以及用作 OR 掩码的数据。 寄存器从零开始寻址。 因此寄存器 1-16 被寻址为 0-15。

该函数的算法为:

结果 = (当前内容 AND And_Mask) OR (Or_Mask AND (NOT And_Mask))

举例:

注意:

如果 Or_Mask 值为零,则结果只是当前内容和 And_Mask 的逻辑与运算。 如果 And_Mask 值为零,则结果等于 Or_Mask 值。

可以使用读取保持寄存器功能(功能代码 03)读取寄存器的内容。 但是,它们可以在控制器扫描其用户逻辑程序时进行更改。

正常响应是请求的回声。 写入寄存器后返回响应。

以下是使用上述掩码值对远程设备中的寄存器 5 进行掩码写入的示例。

6.17 读写多个寄存器(Read/Write Multiple registers) 23(0x17)

6.18 读取FIFO队列(Read FIFO Queue) 24(0x18)

6.19 封装接口传输(Encapsulated Interface Transport ) 43(0x2B)

6.20 CANopen General Reference Request and Response PDU 43/13(0x2B/0x0D)

6.21 读取设备标识 43/14(0x2B/0x0E)

此功能代码仅允许读取与远程设备的物理和功能描述相关的标识和附加信息。

读取设备标识接口被建模为由一组可寻址数据元素组成的地址空间。 数据元素称为对象,对象 ID 标识它们。

该界面由 3 类对象组成:

  • 基本设备识别。此类别中的所有对象都是必填的:供应商名称、产品代码和修订号。
  • 常规设备识别。除了基本数据对象之外,设备还提供附加和可选的标识和描述数据对象。此类别的所有对象都在标准中定义了,但它们的实现是可选的。
  • 扩展设备标识。除了常规数据对象外,设备还提供有关物理设备本身的附加和可选标识和描述私有数据。 所有这些数据都依赖于设备。

请求参数说明:

分配编号 14 的 MODBUS 封装接口标识读取标识请求。

参数“读取设备ID码”允许定义四种访问类型:

  • 01: 请求获取基本的设备标识(流访问)
  • 02: 请求获取常规设备标识(流访问)
  • 03: 请求获取扩展设备标识(流访问)
  • 04: 请求获取一个特定的标识对象(个人访问)

如果读取设备ID代码为非法,则会在响应中返回异常码03。

如果响应不适合于单个响应,则必须执行几个事务(请求/响应)。对象Id字节给出了要获取的第一个对象的标识。对于第一个事务,客户端必须将对象Id设置为0,以获得设备标识数据的开始。对于后面的事务,客户端必须将对象Id设置为服务器在上一个响应中返回的值。

备注:对象是不可分割的,因此任何对象的大小都必须与事务响应的大小相一致。

如果对象 ID 与任何已知对象都不匹配,则服务器会像指出对象 0 一样进行响应(从头重新启动)。

如果是单独访问:ReadDevId 代码 04,请求中的 Object Id 给出了要获取的对象的标识,如果 Object Id 与任何已知对象都不匹配,则服务器返回异常响应,异常代码 = 02(非法数据地址)。

如果服务器设备被要求提供比其符合级别更高的描述级别(读取设备代码),则它必须根据其实际符合级别做出响应。

响应参数说明:

Function code 0x2B(十六进制)
MEI Type 14 (0x0E) MEI 类型分配给设备识别接口的编号
ReadDevId code 与请求ReadDevId代码相同:01、02、03或04
Conformity Level符合性水平 设备的标识一致性级别和支持的访问类型
0x01:基本标识(仅限流访问)
0x02:常规标识(仅限流访问)
0x03:扩展标识(仅限流访问)
0x81:基本标识(流访问和单独访问)
0x82:常规标识(流访问和单独访问)
0x83:扩展标识(流访问和单独访问)
More Follows 对于ReadDevId代码01、02或03(流访问),如果标识数据不适合单个响应,则可能需要多个请求/响应事务。
0x00:没有更多的对象可用
0xFF:其他标识对象是可用的,需要MODBUS事务
对于ReadDevId代码04(单独访问),此字段必须设置为00。
Next Object Id 如果“MoreFollows = FF”,则标识下一个要请求的Object。如果“MoreFollows = 00”,则必须设置为00(无用)
Number Of Objects 响应中返回的标识对象数(对于单个访问,对象数 = 1)
Object0.Id PDU 中返回的第一个对象的标识(流访问)或请求的对象(单独访问)
Object0.Length 以字节表示的第一个对象的长度
Object0.Value 第一个对象的值(对象0)。长度的字节)
.... ....
ObjectN.Id 最后一个对象的标识(在响应范围内)
ObjectN.Length 最后一个对象的字节的长度
ObjectN.Value Value of the last Object (ObjectN.Length bytes)

针对“基本设备标识”的读取设备识别请求的示例:在本例中,所有信息都在一个响应PDU中发送。

如果设备需要多个事务来发送响应,则会启动以下事务。

第一次事务:

第二次事务:

7.MODBUS异常响应

当客户端设备向服务器设备发送请求时,它期望得到正常响应。 客户端的查询可能会发生四种可能的事件之一:

  • 如果服务器设备接收到的请求没有通信错误,并且可以正常处理查询,则返回正常响应。
  • 如果服务器由于通信错误而没有收到请求,则不返回任何响应。客户端程序最终将处理该请求的超时条件。
  • 如果服务器接收到请求,但检测到通信错误(奇偶校验、LRC、CRC、……),则不返回任何响应。客户端程序最终将处理该请求的超时条件。
  • 如果服务器接收到的请求没有通信错误,但不能处理它(例如,如果请求是读取一个不存在的输出或寄存器),服务器将返回一个异常响应,通知客户端错误的性质。

异常响应消息有两个字段可以将其与正常响应区分开来:

功能码字段:在正常响应中,服务器在响应的功能码字段中回显原始请求的功能码。 所有功能代码的最高有效位 (MSB) 均为 0(它们的值均低于 80 十六进制)。 在异常响应中,服务器将功能代码的 MSB 设置为 1。这使得异常响应中的功能码值比正常响应的值高 0x80。

通过设置功能码的 MSB,客户端的应用程序可以识别异常响应,并可以检查异常代码的数据字段。

数据字段:在正常响应中,服务器可能会返回数据字段中的数据或统计信息(请求中请求的任何信息)。 在异常响应中,服务器在数据字段中返回异常代码。 这定义了导致异常的服务器条件。

客户端请求和服务器异常响应的示例

在此示例中,客户端向服务器设备发送请求。 功能代码 (01) 用于读取输出状态。 它请求地址 1185(04A1 十六进制)处的输出状态。 请注意,仅读取一个输出,如输出数量字段 (0001) 所指定。

如果服务器设备中不存在输出地址,则服务器将返回异常响应并显示异常代码 (02)。 这指定了服务器的非法数据地址。

异常代码的列表

异常码 名称 含义
01 非法功能 ILLEGAL FUNCTION 查询中收到的功能代码不是服务器允许的操作。 这可能是因为该功能代码仅适用于较新的设备,并未在所选单元中实现。 它还可能表明服务器处于错误状态,无法处理这种类型的请求,例如因为它未配置且被要求返回寄存器值。
02 非法数据地址 ILLEGAL DATA ADDRESS 查询中收到的数据地址不是服务器允许的地址。 更具体地说,参考号和传输长度的组合是无效的。 对于100个寄存器的控制器,PDU将第一个寄存器寻址为0,最后一个寄存器寻址为99。如果提交的请求起始寄存器地址为96,寄存器数量为4,则该请求将成功运行( 地址至少)在寄存器 96、97、98、99 上。如果提交的请求的起始寄存器地址为 96,寄存器数量为 5,则此请求将失败,异常代码为 0x02“非法数据地址” 因为它试图对寄存器 96、97、98、99 和 100 进行操作,并且没有地址为 100 的寄存器。
03 非法数据值ILLEGAL DATA VALUE 数据字段中包含的值不是服务器允许的值。 这表明复杂请求的其余部分的结构存在错误,例如隐含长度不正确。 它具体并不意味着提交存储在寄存器中的数据项具有超出应用程序预期的值,因为 MODBUS 协议不知道任何特定寄存器的任何特定值的重要性。
04 服务器设备故障SERVER DEVICE FAILURE 当服务器试图执行所请求的操作时,发生了一个不可恢复的错误。
05 确认ACKNOWLEDGE 专门与编程命令结合使用。
服务器已接受请求并正在处理它,但这样做需要很长时间。 返回此响应是为了防止客户端发生超时错误。 客户端接下来可以发出轮询程序完成消息以确定处理是否完成。
06 服务器设备繁忙SERVER DEVICE BUSY 专门与编程命令结合使用。
服务器正在处理一个长时间的程序命令。 客户端应该稍后在服务器空闲时重新传输消息。
08 存储器奇偶误差MEMORY PARITY ERROR 专门与功能码 20 和 21 以及引用类型 6 结合使用,以指示扩展文件区域未能通过一致性检查。
服务器尝试读取记录文件,但在内存中检测到奇偶校验错误。 客户端可以重试请求,但可能需要服务器设备上的服务。
0A 网关路径不可用GATEWAY PATH UNAVAILABLE 专门与网关结合使用,表示网关无法分配从输入端口到输出端口的内部通信路径来处理请求。 通常意味着网关配置错误或过载。
0B 网关目标设备未能响应GATEWAY TARGET DEVICE
FAILED TO RESPOND
专门与网关结合使用,表示未从目标设备获得响应。 通常意味着该设备不在网络上。

附件A(信息性):MODBUS保留的功能码、子码和MEI类型

下列功能码和子码不属于本公开规范的一部分,这些功能码和子码是专门保留的。 格式为功能码/子码或仅保留所有子码(0-255)的功能码:8/19; 8/21-65535、9、10、13、14、41、42、90、91、125、126 和 127。

功能码 43 及其用于设备识别的 MEI 类型 14 和用于 CANopen 通用参考请求和响应 PDU 的 MEI 类型 13 是本规范中当前可用的封装接口传输。

以下功能码和 MEI 类型不属于本公开规范的一部分,这些功能码和 MEI 类型被特别保留:43/0-12 和 43/15-255。 在本规范中,不支持具有与封装接口传输相同或相似结果的用户定义功能码。

MODBUS是施耐德自动化有限公司的注册商标。

附件 B(资料性):CANOPEN 通用参考命令

请参阅 MODBUS 网站或 CiA(自动化中的 CAN)网站获取涵盖功能代码 43 MEI 类型 13 的副本和使用条款。

文档翻译自: