Modbus 协议详解

news2024/11/24 20:06:35

Modbus 协议详解

通信协议是指双方实体完成通信或服务所必须遵循的规则和约定,例如我们为实现人与人之间的交流需要约定统一的语言,统一的文字,规定语速等等。

而对于设备之间,协议定义了数据单元使用的格式(例如大端小端模式,编码解码方式,加密解密规则),信息单元应该包含的信息与含义,连接方式,信息发送和接收的时序,从而确保数据顺利地传送到对方。

1. 前言

Modbus 属于串行通信协议,是 Modicon (即现在的施耐德)公司于 1979 年为可编程逻辑控制器 PLC 通信而发表,所以现在知道为什么以 Mod 开头了吧,目前不仅 PLC 使用,实际已经成为工业领域通信协议的标准,是现代工业电子设备之间常用的连接方式。 Modbus 公开发表且无版权要求,易于部署和维护。

下面我们来了解一下 Modbus 协议相关的细节,以及 Modbus 协议的应用方式。

并行通信:数据各位同时传送。

串行通信:数据一位一位顺序依次传送。

2. 物理接口

Modbus 协议属于应用层协议,协议本身并没有像 SPII2CTCP/IP 定义物理层,只定义了数据包组织结构和内容的公共格式。所以它没有自己专属的数据链路层和物理层,所以需要依赖其他可用的物理层和数据链路层来传输数据。

例如可以选用串口(例如 RS232,RS485 和 RS422),也可以选择以太网口,但目前大多数应用都是通过串口 RS-485 作为物理层,如下图。

请添加图片描述

实际上不仅限于以上物理接口,由于 Modbus 属于应用层协议所以协议本身不管数据是经过何种网络进行通信的。所以还能以 USB,蓝牙,WiFi 等其他一切能够串行传输数据的总线作为物理层和数据链路层传输数据。

标准的 Modbus 口是使用 RS-232C 兼容串行接口,该接口定义了连接口的针脚,电缆,信号位,传输波特率,奇偶校验,这样控制器能直接或经由 Modem 组网。

3. 协议版本

Modbus 协议目前分别定义了基于串口和以太网传输数据的规则,其中串口规则两种 Modbus RTU 和 Modbus ASCII,以太网规则一种 Modbus TCP/IP。

其中 Modbus RTU 和 Modbus ASCII 协议应用于串口链接(RS232,RS485,RS422,光纤,无线),Modbus TCP/IP 协议应用于以太网链接。


Modbus 还有有一个扩展版本 Modbus PLUS(也叫 Modbus+ 或者 MB+),不过此协议是 Modicon 公司专有的,和 Modbus 不同。它需要一个专门的协处理器来处理类似 HDLC 的高速令牌旋转。

我们不使用 MB+ 所以不深入去了解,我们只要了解 Modbus-TCP/IP,Modbus-RTU,Modbus-ASCII 这三种模式即可。

4. 工作模式

Modbus 协议是属于主从(Master/Slave)通信方式的协议。在所有节点中其中一个为 Master 节点,其余为 Slave 节点,在整个通信网络中 Master 节点至少且只有 1 个。

主从通信以 请求/应答 为主,每次通讯都是主站先发送指令(可以是广播指令,或是向特定从站的单播指令),从站响应指令,并按要求应答,或者报告异常。当主站不发送请求时,从站不会自己发出数据,从站和从站之间不能直接通讯(也就是说从站之间不能相互发送指令或访问)。

无论主站发送的是广播指令还是单播指令,实际上所有从设备都会完整接收命令。但单播指令只有指令中指明的 编号/地址 与设备 编号/地址 相同时设备才会执行及回应指令,编号/地址 与指令指明的 编号/地址 不同的从机将接收到的所有内容丢弃,而广播指令所有收到指令的设备都会执行指令,但不会给主机回应指令。

半双工通信

Modbus 由于请求/应答机制所以不能同步通信(同步通信需要收发双方以相同的节奏发送和接收数据),总线上每次只有一帧数据进行传输,属于半双工通信。

Modbus 没有支持忙机制处理,例如主机给从机发送命令, 如果从机正在处理其他任务,此时从机将无法响应主机,所以需要通过软件的方式来判断是否正常接收。

5. 协议概述

(1) 控制器通信使用主/从模式,即仅主设备能发送查询和操作命令,其它从设备根据主设备查询/操作命令作出相应反应。

(2) 主设备可单独和从设备通信,也能以广播方式和所有从设备通信。如果单独通信,从设备必须返回一消息作为给主机的回应,如果是以广播方式查询的,则从机不作任何回应。

(3) Modbus 协议建立了主设备查询的协议格式,内容包含:从设备(或广播)地址,功能代码,所有要发送的数据,错误检测域(协议校验码)。

(4) 从设备回应消息也要遵循 Modbus 协议,内容包括确认要行动的域,任何要返回的数据,和错误检测域(协议校验码)。如果在消息接收过程中发生一错误,或从设备不能执行其命令,从设备需要生成一条错误消息并把它作为回应发送给主设备,主设备接收后就知道从设备发生了错误,以及可知道发生了何种错误。

6. 报文格式

Modbus 协议的报文(或帧)的基本组成格式是:

协议头(Header) + 功能码(Function Code) + 数据区(Data) + 校验码(Checksum)

功能码(Function Code)和数据区(Data)在不同类型的网络都是固定不变的。

协议头(Header)和校验码(Checksum)则因网络底层的实现方式不同而有所区别。协议头包含了从站的地址,功能码告诉从站要执行何种功能,数据区是具体的数据内容。

报文定义了一个与物理层无关的协议数据单元(简称 PDU),PDU 协议字段组成如下:

PDU = 功能码(Function Code) + 数据域(Data)(功能码 1 Byte,数据域不确定)

对于不同类型的网络,Modbus 的协议层实现是一样的,区别在于下层的实现方式,常见的有 TCP/IP串行通讯 两种。

请添加图片描述

如上图所示,Modbus 串行传输的物理层是 RS-485/422 或 RS-232,数据链路层是 Modbus 的串行传输协议。

Modbus TCP 传输的 1-4 层和我们日常使用的以太网,因特网一样,分别为物理层,数据链路层,网络层,传输层。同时标准规定 Modbus-TCP 默认采用的 TCP 端口号是 502。

6.1 Modbus-TCP/IP

在 Modbus TCP 模式下,主站被称为客户端(Client),从站被称为服务器(Server)因为 Modbus 主站总是向 Modbus 从站查询操作数据,这和客户端与服务器的运作模式是相同的。

6.1.1 数据帧

对于 TCP/IP 通信 Modbus 协议引入一些附加域映射成应用数据单元(ADU)而 ADU 可分为 MBAP 和 PDU 两部分,这两部分如下关系:

PDU = 功能码(Function Code) + 数据域(Data)(功能码 1 Byte,数据域长度不确定)。
ADU = MBAP+PDU

数据帧组成如下图:

请添加图片描述

其中 MBAP(报文头)占 7 Bytes,功能码 1 Byte,数据域长度不确定,由具体功能决定,如下所示:

事务处理标识协议标识长度单元标识符
2 Byte2 Byte2 Byte1 Byte

事务处理标识,可以理解为报文的序列号,一般每次通信之后就要加 1 以区别不同的通信数据报文。

协议标识符,例如 00 00 表示的是 Modbus-TCP/IP 协议。

长度,表示接下来的数据长度,单位为字节。

单元标识符,可以理解为设备地址。

将 ADU 报文详细展开后如下图:

请添加图片描述

6.1.2 数据帧变化

请添加图片描述

(1) 取消了校验位,TCP/IP 协议的数据链路层上就进行了 CRC-32 的校验,同时TCP/IP 是面向连接的可靠性的协议,因此应用层没必要再加上校验位。

(2) Slave 地址变成了单元标识符,当网络中的设备都使用 TCP/IP 协议,该地址是没有意义的,因为使用 IP 地址就能进行路由寻址,如果网络里还有串行通讯的设备,则需要使用网关来实现 Modbus-TCP/IP 到 Modbus-RTU/ASCII 之间的协议转换,这时用 Unit Identifier 来标识网关后面的每个串行通讯设备。

(3) 长度是指后面的字节总数,实际上数据区的长度是能确定的,有的功能码就可以确定数据区的长度(例如读寄存器功能码),有的功能码虽不能确定数据区长度,但是 Modbus 协议数据区包含有字节计数(这后面会说明)。表头增加的长度是为了应对有些情况下TCP/IP 协议会将应用层的数据拆包传输的场景。

(4) 事物处理标识符和协议标识符由 Client 生成,Server 的响应将复制这些参数。

6.1.3 端口号

IANA(Internet Assigned Numbers Authority)互联网编号分配管理机构给Modbus 协议赋予 TCP 端口号为 502,这是目前 Modbus 在仪表与自动化行业中唯一分配到的端口号。

6.1.4 通信流程

在使用 TCP/IP 通信时,主站为 Client 端,主动与服务器建立连接。从站为 Server端,等待 Client 连接。

注意,在使用 Modbus 通信之前需要先建立 TCP 连接,通信任务结束时,需要关闭 TCP 连接,这和 PC 客户端连接服务器的规则是相同的。

6.2 Modbus-串行

Modbus 使用异步串行链路传输时,可以选择传输模式 ASCII 或 RTU 两种中的任意一种。使用异步串行传输需要确保每个设备的串口通信硬件配置参数(波特率,校验方式等)是相同的。

6.2.1 Modbus-ASCII

在 Modbus ASCII 模式下,主站是 Master,从站是 Slave。

起始位设备地址功能代码数据数量数据LRC 高字节LRC 低字节结束符
:2*8 Bit2*8 Bitnn*8 Bit8 Bit8 BitCR, LF(回车换行)

Modbus 以 ASCII 模式通信,在消息中的每个 8 Bit 字节都作为两个 ASCII 字符发送,也就是说使用两个字符来表示 1 个字节的十六进制值,可见所见即所得。

例如表示十六进制 35 需要使用 35 这两个字符,而每个字符都占用 1 个字节,字符 3 实际值为十六进制 33,字符 5 实际值为 35,所以为了表示 30 需要使用 16 Bits 数据,所以实际发送的数据为 00110011, 00110101,但这并不是最终使用的数据,接收端需要将其转换为原始值才能够使用。

ASCII 帧间隔

使用 ASCII 模式,消息以 : 冒号字符(ASCII 码 3A)开始,以回车换行符结束ASCII 码 0D0A

其它域可以用于表达十六进制数值的字符是 0-9A-F。网络上的设备不断侦测 : 冒号字符,当每个节点设备接收到一个 : 冒号时,每个设备都解码下个域(设备地址域)来判断是否发给自己的。

消息中字符间发送的时间间隔最长不能超过 1 秒,否则接收的设备将认为传输错误,一个典型 ASCII 消息帧如下所示:

起始位设备地址功能代码数据LRC 校验结束符
1 个字符2 个字符2 个字符n 个字符2 个字符2 个字符

6.2.2 Modbus-RTU

在 Modbus RTU 模式下,主站是 Master,从站是 Slave。

起始位设备地址功能代码数据数量数据CRC 低字节CRC 高字节结束符
8 Bit8 Bitnn*8 Bit8 Bit8 Bit

Modbus 以 RTU 模式通信,其发送的字节数据即为原始字节数据,接收端接收后无需再次转换。

例如,要传输十六进制 35,实际发送的数据就为原始值 0011, 0101

RTU 帧间隔

使用 RTU 模式,消息发送至少要以 3.5 个字符时间的停顿间隔开始。在网络波特率下多样的字符时间,这是最容易实现的(如下图的 T1-T2-T3-T4 所示)。传输的第一个域是设备地址。可以使用的传输字符是十六进制的 0-9A-F。网络设备不断侦测网络总线,包括停顿间隔时间内。当第一个域(地址域)接收到,每个设备都进行解码以判断是否发往自己的。在最后一个传输字符之后,一个至少 3.5个字符时间的停顿标定了消息的结束。一个新的消息可在此停顿后开始。

整个消息帧必须作为一连续的流转输。如果在帧完成之前有超过 1.5 个字符时间的停顿时间,接收设备将刷新不完整的消息并假定下一字节是一个新消息的地址域。同样地,如果一个新消息在小于 3.5 个字符时间内接着前个消息开始,接收的设备将认为它是前一消息的延续。这将导致一个错误,因为在最后的 CRC 域的值不可能是正确的,一典型的 RTU 消息帧如下所示:

起始位设备地址功能代码数据CRC 校验结束符
T1-T2-T3-T48Bit8Bitn个8Bit16BitT1-T2-T3-T4
字符时间

所谓字符传输时间指的是传输一个 ASCII 字符需要花费的时间,一个 ASCII 字符包含 1 个字节(8 bits),所以传输一个字符需要花费传输 8 个数据位的时间(所以这里字符传输时间并不是真的字面意思传输字符,而是指代传输字节)。

然而实际上传输 1 个字节数据需要花费的时间并不只 8 个位时间,因为除了传输固有的 1 字节数据,还需要传输一些辅助功能位。例如发送 1 个字节需要固定起始位 1 位,数据位 8 位,校验位 1 位(可选的),停止位 1 位,其中 8 位数据位才是真正的有效数据,所以有如下公式来计算字符时间。

字符时间 = 1 s 波特率 × 字符总位数。 字符时间 = \frac{1s}{波特率} \times 字符总位数。 字符时间=波特率1s×字符总位数。

例如:固定起始位 1 位,数据位 8 位,奇/偶校验位 1 位,停止位 1 位,波特率为9600 bps,计算单个字符传输时间为:

字符时间 = 1000 m s 9600 × ( 1 + 8 + 1 + 1 ) = 1.145833 m s 字符时间 = \frac{1000ms}{9600} \times (1+8+1+1)=1.145833ms 字符时间=96001000ms×(1+8+1+1)=1.145833ms

7. 帧字段分析

7.1 地址域

消息帧的地址域可能的从设备地址是 0-247。单个设备的地址范围是 1-247

主设备通过将要联络的从设备的地址放入消息中的地址域来选通从设备。当从设备发送回应消息时,需要把自己的地址放入回应的地址域中,以便主设备知道是哪一个设备作出的回应。

地址 0 被用作广播地址,以使所有的从设备都能认识。当 Modbus 协议用于更高水准的网络,广播可能不允许或以其它方式代替。

7.2 功能域

消息帧中的功能代码域可能的代码范围是十进制的 1-255。当然,有些代码是适用于所有控制器,有此是应用于某种控制器,还有些保留以备后用。

当消息从主设备发往从设备时,功能代码域将告之从设备需要执行哪些行为。例如去读取输入的开关状态,读一组寄存器的数据内容,读从设备的诊断状态,允许调入、记录、校验在从设备中的程序等。

当从设备回应时,它使用功能代码域来指示是正常回应(无误)还是有某种错误发生(称作异议回应)。对正常回应,从设备仅回应相应的功能代码。对异议回应,从设备返回一等同于正常代码的代码,但最重要的位(功能码最高位)置为逻辑 1
例如:一从主设备发往从设备的消息要求读一组保持寄存器,将产生如下功能代码:0000, 0011 (十六进制 03)对正常回应,从设备仅回应同样的功能代码。对异议回应,它返回:1000, 0011 (十六进制 83)。

除功能代码因异议错误作了修改外,从设备将一独特的代码放到回应消息的数据域中,这能告诉主设备发生了什么错误。

主设备应用程序得到异议的回应后,将重发消息或者诊断发给从设备的消息并报告给设备管理员。

7.3 数据域

数据域是由两个十六进制数集合构成的,每个字节数据取值范围 00-FF

从主设备发给从设备消息的数据域包含附加的信息:从设备必须用于进行执行由功能代码所定义的所为。这包括了象不连续的寄存器地址,要处理项的数目,域中实际数据字节数。

例子

如果主设备需要从设备读取一组保持寄存器(功能代码 03),数据域指定了起始寄存器以及要读的寄存器数量(这里不等同于字节数量)。

如果主设备写一组从设备的寄存器(功能代码 10),数据域则指明了要写的起始寄存器以及要写的寄存器数量(这里不等同于字节数量),数据域的数据字节数,要写入寄存器的数据。

如果没有错误发生,从从设备返回的数据域包含请求的数据。如果有错误发生,此域包含一条异议代码,主设备应用程序可以用异议代码来判断发生的问题以采取下一步行动。

在某种消息中数据域可以是不存在的(即 0 长度)。例如,主设备要求从设备回应通信事件记录(功能代码 0B),从设备不需主设备提供任何附加的信息。

7.4 错误检测域

标准的 Modbus 网络有两种错误检测方法,错误检测域的内容视所选的检测方法而定。

ASCII 模式,错误检测域包含两个 ASCII 字符。这是使用 LRC(纵向冗长检测)方法对消息内容计算得出的,不包括开始的冒号符及回车换行符。LRC 字符附加在回车换行符前面。

RTU模式,错误检测域包含 16Bits 值,并被拆分为两个字节,分为高字节和低字节。错误检测域的内容是通过对消息内容进行循环冗长检测方法得出的。CRC 域附加在消息的最后,添加时先是低字节然后是高字节。故 CRC 的高位字节是发送消息的最后一个字节。

7.4.1 LRC 校验

LRC 域检测了消息域中除开始的冒号及结束的回车换行号外的内容, LRC 域是一个包含一个 8 位二进制值的字节。LRC 值由传输设备来计算并放到消息帧中,接收设备在接收消息的过程中计算 LRC,并与接收到报文中的 LRC 值比较,如果两值不等,说明有错误。

LRC 方法是将消息中的 8 Bit 的字节连续累加,累加时丢弃累加进位。

unsigned char LRC(unsigned char * auchMsg, unsigned short dataLen)
{
    unsigned char authLRC = 0; /* LRC 字节初始化 */

    while (dataLen--) { /* 传送消息 */
        authLRC += (*auchMsg)++; /* 累加 */
    }
    return ((unsigned char)(-authLRC));
}

7.4.2 CRC 校验

CRC 域检测了整个消息的内容,CRC 域是两个字节,包含一 16 位的二进制值。它由传输设备计算后加入到消息中。接收设备重新计算收到消息的 CRC,并与接收到报文中的 CRC 域中的值比较,如果两值不同,则有误。

CRC 添加到消息中时,低字节先加入报文,然后高字节。

8. 数据模型

Modbus 协议最开始被用于 PLC 通信中,为了抽象 PLC 中可访问的数据 Modbus 协议定义了 数据模型 概念,数据模型定义了四种可访问的数据类型,分别是:

(1) 输出线圈(Coils),大小只有 1 Bit,属于开关量,数值范围 ONOFF,权限是 可读可写,既可以是一个输出量输出点,也可以是数字量输入点。

(2) 输入离散量(Discrete Input),属于离散量,大小只有 1 Bit,数值范围 ONOFF,权限是 只读,即数字量输出点。

(3) 输入寄存器(Input Registers),16 Bit 的寄存器,权限是 只读,可以用作模拟量或 16 位打包输入点。

(4) 保持寄存器(Holding Registers),16 Bit 的寄存器,权限是 可读可写,既可以是一个模拟量或 16 位打包输入点,也可以是模拟量或 16 位打包输出点。

实际上以上的数据类型都属于可编程逻辑控制器(PLC)中的术语,所以表达上总是不符合我们的直觉,搞得我们使用 MCU 单片机思维难以理解。

9. 数据地址模型

数据模型是一种抽象,在实际使用时必须将其映射到真实的物理存储区才能被访问。

Modbus 协议允许设备将四种数据分别映射到不同的存储区块中,各个区块之间相互独立,使用不同的功能码可读取到不同的数值,如下图所示:

请添加图片描述

数据模型中的每一种数据类型都最多允许有 65536 个元素(编号 1-65536),元素的地址编号从 0 开始,因此地址的范围为:0-65535

需要说明的是:65536 是 Modbus 协议允许的最大元素范围,但并不要求我们全部实现。Modbus 协议允许设备根据自己的实际情况实现部分元素,甚至不要求实现模型中全部四种数据(比如只实现保持寄存器类型数据的读写)。

为了简化数据模型与设备存储区的对应关系,引入了一种地址模型。该模型通过编号的方式对不同类型数据进行区分,各数据的地址编号请看下面的表格:

地址模型Modbus 地址编号
线圈(Coils)0
离散输入(Discrete Input)1
输入寄存器(Input Registers)3
保持寄存器(Holding Registers)4

Modbus 地址模型的编号从 1 开始,由于每一种数据都最大支持 65536 个元素,因此我们可以得到以下四种数据类型的地址范围(最前面的 0 即为地址编号):

(1) 输出线圈(Coils),其地址范围为:000001-065536

(2) 离散量输入(Discrete Input),其地址范围为:100001-165536

(3) 输入寄存器(Input Registers),其地址范围为:300001-365536

(4) 保持寄存器(Holding Registers),其地址范围为:400001-465536

然而由于 65536 是比较大的数值,实际应用中一般不需要这么大的存储区,因此 PLC 厂家普遍采用的是 10000 以内的地址范围,因此我们可以得到以下四种数据类型的地址范围:

(1) 输出线圈(Coils),其地址范围为:00001-09999

(2) 离散量输入(Discrete Input)其地址范围为:10001-19999

(3) 输入寄存器(Input Registers)其地址范围为:30001-39999

(4) 保持寄存器(Holding Registers)其地址范围为:40001-49999

单片机映射方法

对于我们使用单片机我们可以通过以下方式来映射 Modbus 的虚拟地址,定义一个数组,定义寄存器起使地址,寄存器数量,寄存器数量最多可以有 9999 个,但是我们实际情况下通常没有这么多,按照实际使用数量来定义,比如这里我定义了 9 个(即 9999 - 9000)。

#define COILS_ADDR_START             (1)
#define COILS_COUNT                  (9999 - 9000)

#define DISCRETE_INPUT_ADDR_START    (10001)
#define DISCRETE_INPUT_COUNT         (9999 - 9000)

#define INPUT_REGISTERS_ADDR_START   (30001)
#define INPUT_REGISTERS_COUNT        (9999 - 9000)

#define HOLDING_REGISTERS_ADDR_START (40001)
#define HOLDING_REGISTERS_COUNT      (9999 - 9000)

bool coilsBuf[COILS_COUNT];
bool discreteInputBuf[COILS_COUNT];
unsigned short inputRegistersBuf[COILS_COUNT];
unsigned short holdingRegistersBuf[COILS_COUNT];

根据主机提供的读地址或写地址减去我们定义的寄存器起使地址,就可以转化为对应数据的数组索引,再根据主机提供的读数量或写数量(注意数量是寄存器个数,而不是字节数)就可以知道数组索引范围。

10. 功能码

前面我们了解到主设备可以访问或修改从机设备中的存储的数据,为了便于主设备使用 Modbus 协议访问和修改从设备中存储的数据,Modbus 协议根据数据模型和功能制定了一系列的功能代码,功能码和描述如下表所示。

功能码名称功能描述
01读线圈状态读位(读 N 个 bit)读从机线圈寄存器,位操作
02读输入离散量读位(读 N 个 bit)读离散输入寄存器,位操作
03读多个寄存器读整型,字符型,状态字,浮点型(读N 个 word)读保持寄存器,字节操作
04读输入寄存器读整型,状态字,浮点型(读 N 个word)读输入寄存器,字节操作
05写单个线圈写位(写 1 个 bit)—写线圈寄存器,位操作
06写单个保持寄存器写整型,字符型,状态字,浮点型(写一个 word )写保持寄存器,字节操作
07读取异常状态取得 8 个内部线圈的通断状态,这 8 个线圈的地址由控制器决定,用户逻辑可以将这些线圈定义,以说明从机状态,短报文适宜于迅速读取状态
08回送诊断校验把诊断校验报文送从机,以对通信处理进行评鉴
09编程(只用于 484)使主机模拟编程器作用,修改 PC 从机逻辑
0A控询(只用于 484)可使主机与一台正在执行长程序任务从机通信,探询该从机是否已完成其操作任务,仅在含有功能码 9 的报文发送后,本功能码才发送
0B读取事件计数可使主机发出单询问,并随即判定操作是否成功,尤其是该命令或其他应答产生通信错误时
0C读取通讯事件记录可是主机检索每台从机的 ModBus 事务处理通信事件记录。如果某项事务处理完成,记录会给出有关错误
0D编程(184/384/484/584)可使主机模拟编程器功能修改 PC 从机逻辑
0E探询(184/384/484/584)可使主机与正在执行任务的从机通信,定期控询该从机是否已完成其程序操作,仅在含有功能 13 的报文发送后,本功能码才得发送
0F写多个线圈可以写多个线圈强置一串连续逻辑线圈的通断
10写多个保持寄存器写多个保持寄存器把具体的二进制值装入一串连续的保持寄存器
11报告从机标识可使主机判断编址从机的类型及该从机运行指示灯的状态
12(884 和 MICRO84)可使主机模拟编程功能,修改 PC 状态逻辑
13重置通信链路发生非可修改错误后,是从机复位于已知状态,可重置顺序字节
14读取通用参数(584L)显示扩展存储文件中的数据信息
15写入通用参数(584L)把通用参数写入扩展存储文件
16~40保留做扩展功能备用
41~48保留以备用户功能所用留作用户功能的扩展编码
49~77非法功能
78~7F保留留作内部作用
80~FF保留用于异常应答

Modbus 定义了大量的功能代码,但是更为常用的功能代码只有如下部分功能代码。

功能码名称功能对应的地址类型
01读线圈状态读位(读 N 个 bit)读从机线圈寄存器,位操作0x
02读输入离散量读位(读 N 个 bit)读离散输入寄存器,位操作1x
03读多个寄存器读整型,字符型,状态字,浮点型(读 N 个 word)读保持寄存器,字节操作4X
04读输入寄存器读整型,状态字,浮点型(读 N 个word)读输入寄存器,字节操作3x
05写单个线圈写位(写 1 个 bit)写线圈寄存器,位操作0x
06写单个保持寄存器写整型,字符型,状态字,浮点型(写一个 word)写保持寄存器,字节操作4x
0F写多个线圈写位(写 N 个 bit)强置一串连续逻辑线圈的通断0x
10写多个保持寄存器写整形,字符型,状态字,浮点型(写 N 个 word)把具体的二进制值装入一串连续的保持寄存器4x

11. 错误码

前面说过当主从设备通信出现错误后,从设备可以将一个独特的代码放入到回应消息帧的数据域中,主设备接收到消息后能够大致判断从设备发生了什么错误,Modbus 定义的常用错误代码如下表所示。

异常码名称描述
01 (01H)非法功能在请求中接收的功能代码不是从设备的一个授权操作。从设备可能处于错误状态,无法处理特定请求。
02 (02H)非法数据地址从设备接收的数据地址不是从设备的一个授权地址。
03 (03H)非法数据值指定的数据超过范围或者不允许使用。
04 (04H)从站设备故障从设备未能执行一个请求的操作,因为出现了一个无法修复的错误。
05 (05H)确认从站设备已经接受请求,并且正在处理这个请求,但是需要长持续时间进行这些操作,返回这个响应防止在客户机(或主站)中发生超时错误,客户机(或主机)可以继续发送轮询程序完成报文来确认是否完成处理。
06 (06H)从站设备忙从设备忙于处理另一个命令。主设备必须在从设备空闲后发送请求。
07 (07H)否定确认从站设备无法执行主站设备发送的请求。
08 (08H)存储奇偶性差错从设备在尝试读取扩展存储器的时候从存储器中检测到一个奇偶校验错误。
10 (0AH)不可用的网关路径与网关一起使用,指示网关不能为处理请求分配输入端口值输出端口的内部通信路径。通常意味着网关是错误配置的或过载的。
11 (0BH)网关目标设备响应失败与网关一起使用,指示没有从目标设备中获得响应,通常意味着设备未在网络中。

后续还会继续更新和完善 Modbus 协议相关内容,这篇文章篇幅较长,所以其他内容比如 Modbus 调试工具使用方法会在下一篇文章展开。

文章内容如果有帮助的话赶紧点个赞给我一些鼓励吧,如果内容有问题感谢留言。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/422001.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

四、数组、切片,映射

一、一维数组 //声明一个包含5个元素的整型数组 var array [5]int //具体数值填充数组 array : [5]int{1, 2, 3, 4, 5} //容量由初始化值的数量决定 array : [...]int{1, 2, 3, 4, 5) //只初始化索引为1和2的元素 array : [5]int{1: 10, 2: 20} //修改索引为2的元素的值 array…

Linux文件系统、虚拟内存、进程与线程、锁

文章目录文件系统suLinux 中默认没有 super 命令/proc/etc/var/root/home/bin/dev/lib/sbintmp句柄maxfdPWDpathhomeexportwdfdu虚拟内存jobsLinux下一切皆文件swaponmkswap进程与线程nohup子进程与父进程unix进程间的通信方式线程的同步方式sedtarhistory硬链接ln(…

Go分布式爬虫笔记(二十一)

文章目录21 切片和哈希表切片底层结构截取扩容哈希表原理哈希碰撞拉链法开放寻址法(Open Addressing)读取重建原理删除原理思考题Go 的哈希表为什么不是并发安全的?在实践中,怎么才能够并发安全地操作哈希表?拉链法开放…

软件设计师笔记-----程序设计语言与语言处理程序基础

文章目录七、程序设计语言与语言处理程序基础7.1、编译与解释(低频)7.2、文法(低频)7.3、有限自动机与正规式(几乎每次都会考到)有限自动机正规式7.4、表达式(偶尔考到)7.5、传值和传…

2023-详解实时数仓建设

一、实时数仓建设背景 1. 实时需求日趋迫切 目前各大公司的产品需求和内部决策对于数据实时性的要求越来越迫切,需要实时数仓的能力来赋能。传统离线数仓的数据时效性是 T1,调度频率以天为单位,无法支撑实时场景的数据需求。即使能将调度频…

网狐大联盟增加账号登陆功能

1. UI设计 2. 发布CSB文件,并添加到前端工程资源目录下 打开已发布csb文件所有目录 复制到工程目录 如果有用到其它目录的资源也要同步复制到工程资源对应目录中: 2.脚本功能编写 增加前端结构: -- 帐号登录 login.CMD_MB_LogonAccounts= {{t = "word", k = &#

企业电子招标采购系统源码—企业战略布局下的采购寻源

​ 智慧寻源 多策略、多场景寻源,多种看板让寻源过程全程可监控,根据不同采购场景,采取不同寻源策略, 实现采购寻源线上化管控;同时支持公域和私域寻源。 询价比价 全程线上询比价,信息公开透明&#xff…

一站式智慧仓储物流方案,免费帮你一屏搞定,领导不重用你都难!

在江苏无锡,菜鸟已经通过柔性自动化技术搭建了亚洲规模最大的无人仓,超过1000台无人车可以快速组合、分拆作业,生产效率可提升一倍多,大大节省了人工成本。智慧仓储物流作为物流的重要一环,也吸引了广泛关注。2022年双…

如何使用 Jetpack Compose 创建翻转卡片效果

如何使用 Jetpack Compose 创建翻转卡片效果 介绍 在电子商务和银行应用程序中输入卡信息是很常见的情况。我认为让用户更轻松地处理这种情况并创建更吸引眼球的 UI 将很有用。大多数应用程序/网站都喜欢它。 执行 在开发阶段,您需要做的是打开一个 Android 项目…

vim命令模式指令一览

提示:本文介绍了linux下vim中的快捷指令。 文章目录注意:本文所有指令都只在命令行模式下有效!!! vim指令图: 指令解析命令解析h光标向左移动j光标向下移动k光标向上移动l光标向下移动yy/nyy复制当前行/赋…

2023最新面试题-Java-1

知其然知其所以然 Java之父:詹姆斯高斯林 (James Gosling)。 什么是Java Java是一门面向对象编程语言,不仅吸收了C语言的各种优点,还摒弃了C里难以理解的多继承、指针等概念。意思Java不支持多继承、指针。Java语言具有功能强大和简单易用…

《花雕学AI》14:免费打开就可用,ChatGPT国内12个镜像站盘点与测试

引言 人工智能聊天机器人是能和人说话的智能系统,它可以帮人做很多事。现在,人工智能聊天机器人很厉害,很多人想试试。ChatGPT是一个很厉害的人工智能聊天机器人,是OpenAI做的。它可以和人一样说话,还可以回答问题、承…

无线耳机哪个音质比较好?四百内音质最好的无线耳机排行

蓝牙耳机常常作为手机的伴生产品而出现在人们的日常生活当中,其使用场景也越来越广泛。而随着蓝牙技术的发展,蓝牙耳机在音质上的表现也越来越好。下面,我来给大家推荐几款四百内音质最好的无线耳机,一起来看看吧。 一、南卡小音舱…

射频功率放大器在液体超声声强的光电测量中的应用

实验名称:液体中超声声强的光电测量 研究方向:光电测量 测试目的: 声强是描述声场的基本物理量口,超声效应直接与声强有关。例如在工程技术领域,液体中的声场分布直接影响流场分布口,声强的大小影响着超声波…

腾讯云GPU云服务器、CVM云服务器、轻量应用服务器配置价格表

这就是腾讯云GPU云服务器、CVM云服务器、轻量应用服务器配置价格表,最近整理的。目前腾讯云服务器分为轻量应用服务器、CVM云服务器和GPU云服务器,首先介绍一下这三种服务器。 1、GPU 云服务器(Cloud GPU Service,GPU)…

主从模式、哨兵模式、集群模式(cluster)

主从模式、哨兵模式、集群模式(cluster) redis 实现高可用的方式分为 主从模式、哨兵模式、集群模式(cluster) 1. 主从模式(又称为主从复制) 表现为1个主节点,多个从节点,主节点负…

2023年Python选择题及答案解析【35道】

2023年Python练习题及答案解析1、在Python3中,运行结果为:2、在Python3中,字符串的变换结果为:3、在Python3中,下列程序运行结果为:4、在Python3中,下列程序结果为:5、a与b定义如下&…

【C++】基础篇

C基础篇什么是C命名空间命名空间的三种使用方式C的输入和输出缺省参数缺省参数分类函数重载引用引用的使用场景常引用指针和引用的区别auto关键字auto使用细则auto不能推导的场景基于范围的for循环范围for的使用条件指针空值nullptr什么是C 1982年,Bjarne Stroustr…

AutoGPT保姆级使用教程

1. 介绍Auto-GPT是一个基于ChatGPT的工具,他能帮你自动完成各种任务,比如写代码、写报告、做调研等等。使用它时,你只需要告诉他要扮演的角色和要实现的目标,然后他就会利用ChatGPT和谷歌搜索等工具,不断“思考”如何接…

目标检测【Object Detection】

文章目录基本概念两阶段目标检测算法R-CNNFast R-CNNFaster R-CNNFPNMask R-CNN一阶段目标检测算法SSDYOLOv1YOLOv2YOLOv3目标检测的常用数据集目标检测的标注工具基本概念 目标检测是计算机视觉中的一个重要问题,它的目的是从图像或视频序列中识别出特定的目标&am…