用C#读取Modbus温度传感器

传感器地址表

寄存器地址 类型 功能描述 数据格式 示例值
0x0000 (0)
Input Register (只读)
温度值,高精度(浮点型,双寄存器)
浮点数
25.2°C(IEEE格式)
0x0001 (1)
Input Register (只读)
湿度值(如果是温湿一体设备)
浮点数
60.1%
0x0100 (256)
Holding Register (可读写)
单位配置 (0=°C, 1=°F)
16 位整数
0(摄氏度)
0x0200 (512)
Coil (线圈,可读写)
报警启用标志
1 位布尔值
1(启用报警提示)
0x0300 (768)
Discrete Input (只读)
故障状态指示
1 位布尔值
0(无故障)

安装相关依赖

在C#项目中,需要一个库来实现Modbus通讯功能。推荐使用NModbus,它是一个流行且易用的开源库。

步骤:

  • 1.打开Visual Studio。
  • 2.使用NuGet Package Manager安装NModbus:
Install-Package NModbus

001

设置Modbus通讯

Modbus常见的两种通讯方式是串口(Modbus RTU)TCP(Modbus TCP/IP)。下面以Modbus TCP为例。

代码示例:

using System;
using System.Net.Sockets;
using NModbus;

classProgram
{
    static void Main(string[] args)
    {
        string ipAddress = "192.168.1.100"; // 替换为传感器IP
        int port = 502; // 默认的Modbus TCP端口

        try
        {
            // 建立TCP连接
            using (var tcpClient = new TcpClient(ipAddress, port))
            {
                var factory = new ModbusFactory();
                var master = factory.CreateMaster(tcpClient);

                // 读取温度值(寄存器0地址)
                ushort startAddress = 0; // 温度地址
                ushort[] registers = master.ReadInputRegisters(1, startAddress, 2);

                // 将寄存器数据转换为浮点型
                float temperature = ConvertToFloat(registers[0], registers[1]);
                Console.WriteLine($"当前温度: {temperature} °C");
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"错误: {ex.Message}");
        }
    }

    // 双寄存器转浮点数
    static float ConvertToFloat(ushort high, ushort low)
    {
        byte[] data = newbyte[4];
        Buffer.BlockCopy(BitConverter.GetBytes(low), 0, data, 0, 2);
        Buffer.BlockCopy(BitConverter.GetBytes(high), 0, data, 2, 2);
        return BitConverter.ToSingle(data, 0);
    }
}

解析Modbus地址与数据

  • 1.Modbus寄存器:
    温度传感器通常储存在输入寄存器(Input Register)或保持寄存器(Holding Register)。实际使用前,需要查阅设备文档确认其寄存器地址。
  • 2.数据转换:
    常见的温度数据格式包括整型或浮点型,需要在获取后根据传感器需求做相应处理。

调试注意事项

  • 1.确保网络或串口连接正常,并确认IP地址和端口匹配实际设备。
  • 2.校对寄存器地址,如果数据异常需检查设备手册。
  • 3.检查协议类型,确定使用Modbus TCP还是RTU协议。

常见错误处理:

  • 连接超时: 确认防火墙是否拦截。
  • 数据不正确: 检查是否需要字节顺序(Byte Order)调整。

 

 

Java怎么做一个Modbus服务

ModbusTCP 是一种客户端/服务器模式的通信协议。服务器负责监听端口,等待客户端发起请求,并依据请求返回数据或执行操作。例如,读取传感器数据、写入控制命令等,是 ModbusTCP 服务器的常见应用场景。

Java 语言因其跨平台性和丰富的类库,成为构建 ModbusTCP 服务器的一种高效选择。借助第三方库如 JamodModbus4J,我们可以快速实现协议的解析与响应。

1.添加依赖

选择一个成熟的 Modbus 库,例如 Modbus4J,将其引入项目。以下是 Maven 配置:

<dependency>
  <groupId>com.ghgande</groupId>
  <artifactId>modbus4j</artifactId>
  <version>3.0.7</version>
</dependency>

2.编写代码

下面是一段简单的 ModbusTCP 服务器实现代码:

import com.serotonin.modbus4j.base.ModbusUtils;
import com.serotonin.modbus4j.ip.tcp.TcpSlave;
import com.serotonin.modbus4j.processimage.BasicProcessImage;

publicclass ModbusTCPServer {
    public static void main(String[] args) {
        try {
            // 创建服务器实例
            TcpSlave server = new TcpSlave(false);
            server.setPort(502);

            // 构建模拟设备数据
            BasicProcessImage spi = new BasicProcessImage(1);
            spi.setHoldingRegister(0, 12345); // 模拟寄存器数据
            server.addProcessImage(spi);

            // 启动服务
            server.start();
            System.out.println("ModbusTCP 服务器已启动,监听端口 502");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

3.运行程序并测试

运行后,使用 Modbus Poll 或其他客户端工具测试通信功能,可验证读取寄存器数据的正确性。

001

测试结果如下:

Request: Read Holding Registers
Response: [12345]

Java 实现 ModbusTCP 服务器非常简单,通过像 Modbus4J 这样的第三方库,无需深入底层协议解析,即可快速构建稳定可靠的工业通信服务器。同时,你可以根据具体需求扩展功能,例如加入多线程处理、日志记录等。

Modbus 资料总结

Modbus 是工业通信设备中最常用的协议之一,网关向 Modbus 设备发送命令以获取设备的值。

在 Modbus 网络上的所有设备中,通常只有一个主设备,它会向其他从设备发送不同的命令。Modbus 主设备会向网络上的所有设备广播消息,但只有分配了 Modbus 地址来接受命令的设备才会接受该命令,其余设备将拒绝该命令。基本的 Modbus 命令可以指示 RTU 更改其某个寄存器中的值、控制或读取 I/O 端口,以及命令设备发回其寄存器中包含的一个或多个值。

在工业环境中使用 Modbus 的主要原因是:

  • 它是专为工业应用而开发的
  • 它是公开发布的,免版税
  • 它易于部署和维护
  • 它移动原始位或字,而不会对供应商施加太多限制
  • 在 Modbus 协议上轻松获得 SCADA 系统

Modbus 协议有多种类型:

  • Modbus TCP
  • Modbus RTU
  • Modbus ASCII
  • Modbus Plus
  • Modbus Daniels
  • Modbus Tek-Air
  • Modbus Omniflow

其中最流行的是 Modbus RTU 和 Modbus TCP/IP。

ModbusRTU 是一种串行通信协议,可连接同一网络上的不同设备,并使它们之间可以进行通信。

ModbusTCP 涵盖使用 TCP/IP 协议通过“内部网”或“互联网”环境进行 Modbus 通信。目前,该协议最常见的用途是将 PLC、I/O 模块和网关通过以太网连接到其他简单现场总线或 I/O 网络。

总会有这样一个问题:为什么使用面向连接的 TCP/IP 协议而不是面向数据报的 UDP。主要原因是通过将单个“通信”隔离在可以识别、取消和监督的连接中来保持对单个“通信”的控制,而无需对客户端和服务器应用程序执行特定操作。这使该机制能够容忍网络性能变化,并且还提供了添加防火墙和代理等安全功能的空间。

MODBUS/TCP/IP 处理两种不同的情况。在协议层面上,连接很容易被识别。单个连接可用于执行多个独立通信。此外,TCP/IP 允许大量并发连接,因此用户决定重新使用旧连接或重新连接到常用连接。

MODBUS 内存模型/MODBUS 存储模型

MODBUS 具有独特的寻址模式。Modbus 设备会将其中的每个值存储在特定地址。例如,功率计将仅在 Modbus 地址 40001 处存储 Volt A-N 值。

有四种 Modbus 数据类型:

Modbus 数据类型 数据格式和通用名称 地址起始位置
线圈状态 位,二进制值 00001 此类数据可由 I/O 系统提供。
离散输入状态 二进制值 10001 此类型数据可由应用层更改。
输入寄存器 二进制值 30001 此类数据可由 I/O 系统提供。
保持寄存器 模拟值 40001 此类数据可由应用层更改。

MODBUS RTU 如何工作?

  • Modbus通过设备之间的串行线路传输。最简单的设置是使用一条串行电缆连接两个设备(主设备和从设备)上的串行端口。
  • 数据以一系列 1 和 0(称为位)的形式发送。每个位都以电压的形式发送。0以正电压的形式发送,1以负电压的形式发送。位发送得非常快。典型的传输速度为 9600 波特(每秒位数)。

Modbus TCP 如何工作?

可以使用网关上的以太网端口连接 Modbus 设备。我们可以使用任何标准 Modbus 扫描仪进行查询,以从 Modbus 设备中提取值。所有请求都通过注册端口 502 上的 TCP/IP 发送。

Modbus RTU、TCP 和 ASCII 之间有什么区别?

Modbus 协议定义了一个独立于底层通信层的协议数据单元 (PDU)。 Modbus RTU 是最常用的,它是 PDU 的二进制表示,在 PDU 之前有寻址,末尾附加有 CRC。Modbus ASCII 是使用所有可打印字符(通常是两倍的字节数)表示的相同 PDU。Modbus TCP 本质上与 Modbus RTU 完全相同,只是 CRC 不在应用层字节字符串中,而留给 TCP 层自动处理。RTU 数据包的 TCP 封装中还有一些额外的寻址字节。

无论协议变体如何,功能代码、寄存器编号和寻址都是相同的。寄存器类型相同,即为 Modbus 设备定义了相同的数据块。

OSI 模型上的 MODBUS 协议

标准 Modbus 中如何存储数据?

  • 从设备中的信息存储在四个不同的表中。
  • 每个表有 9999 个数据点,可以存储不同的值。

每个线圈有 1 位,并给出 x0000 和 x9999 之间的数据地址。

每个寄存器是 1 个字 = 16 位 = 2 个字节,并且数据地址在 x0000 和 x9999 之间。

数字40001、10000等应作为位置的地址。这些数字永远不会显示在实际消息中。实际地址将是存储数字的偏移量。因此,如果设备具有 Modbus 的 ADU(应用程序定义单元)寻址,则地址 0001 将位于偏移量 40001 处,而对于 PDU(协议定义单元),它将位于偏移量 40002 处。

Modbus 中的从属 ID 或设备 ID

网络中的每个设备都必须分配一个唯一的单元地址,该地址可以介于 1 和 255 之间。当主设备请求数据时,它发送的第一个字节是设备/从属地址。因此,只有在发送第一个字节后,从属设备才会决定响应或忽略。

Modbus 映射

Modbus 映射是支持 Modbus 作为通信协议的任何特定设备的简单点列表。

Modbus 映射应包含以下信息:

  • 设备读取和存储什么类型的数据(例如温度或压力)
  • 数据存储在哪个地址(例如 40001 处的电压 A-N)
  • 数据存储的格式是什么(例如位、UINT16、SINT16 等)
  • 如果需要,提供点的工程单位。
  • 有关设备是否具有 ADU 或 PDU 寻址的信息。

大多数设备都预装了 Modbus 寄存器。在某些情况下,制造商还允许操作员根据自己的要求配置设备。

MODBUS 错误检查

MODBUS 网络采用两种错误检查方法:奇偶校验

  • 数据字符帧的奇偶校验(偶校验、奇校验或无奇偶校验)
  • 消息帧内的帧校验(RTU 模式下的循环冗余校验或 ASCII 模式下的纵向冗余校验)。

奇偶校验

MODBUS 设备可以配置为偶校验或奇校验,或无奇偶校验。这决定了字符数据帧的奇偶校验位的设置方式。如果选择偶校验或奇校验,则计算每个字符帧数据部分中的 1 位数量。RTU 模式下的每个字符包含 8 位。然后,奇偶校验位将设置为 0 或 1,从而导致 1 位总数为偶数(偶校验)或奇数(奇校验)。

帧检查

LRC 纵向冗余校验(仅限 ASCII 模式)在 ASCII 传输模式下,字符帧包含一个 LRC 字段,作为 CRLF 字符之前的最后一个字段。此字段包含两个 ASCII 字符,表示除起始冒号字符和结束 CR LF 字符对之外的所有字段的纵向冗余计算结果。

CRC 错误检查(仅限 RTU 模式)

RTU 模式消息帧包括一种基于循环冗余校验 (CRC) 的错误检查方法。消息帧的错误检查字段包含一个 16 位值(两个 8 位字节),其中包含对消息内容执行的循环冗余校验 (CRC) 计算的结果。

Modbus 定义的功能代码:

主设备发送的第二个字节是功能代码。此数字告诉从设备要访问哪个表以及是否从表中读取或写入。

功能代码 操作 表名称
01 (十六进制 01) 读取 离散输出线圈
05 (十六进制 05) 写入单个 离散输出线圈
15 (十六进制 0F) 写入多个 离散输出线圈
02 (十六进制 02) 读取 离散输入触点
04 (十六进制 04) 读取 模拟输入寄存器
03 (十六进制 03) 读取 模拟输出保持寄存器
06 (十六进制 06) 写入单个 模拟输出保持寄存器
16 (十六进制 10) 写入多个 模拟输出保持寄存器

Modbus 异常代码

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

版权声明

Modbus 疑难解答

我从哪里开始与我的 Modbus 设备通信?

以下是需要了解的几件事:

(1) 物理连接是什么?

Modbus RTU 使用 RS-485 或 RS-232。Modbus TCP 使用以太网。如果您正在寻找网关,则需要选择与要连接的设备的电气接口相匹配的型号。

(2) 寄存器如何映射?

当使用网关将 Modbus 设备连接到非 Modbus 网络时,您需要从设备制造商处获取描述可用寄存器及其寻址方法的文档。Modbus 协议不提供寄存器自动识别自身的方法。

(3) 通信参数是什么?

Modbus RTU 要求您了解或定义波特率、字符格式(8 位无奇偶校验等)和从站 ID(又称从属地址、单元编号、单元 ID)。任何一项不匹配都将导致无法通信。

Modbus TCP 要求您了解或定义网络上的 IP 地址。在某些情况下,您还需要单元 ID。 Modbus TCP 设备可能会使用单元 ID,也可能会忽略它,具体取决于设备和应用程序。

Modbus:当 40001 真正意味着 1,或 0 真正意味着 1 时

Modbus 的文档没有很好的标准化。实际上有一个标准,但在文档方面没有得到很好的遵循。您必须执行以下一项或多项操作才能解读制造商真正指的是哪个寄存器:

a) 查找寄存器描述,例如保持寄存器、线圈等。如果文档中说的是 #1,并告诉您它们是保持寄存器,那么您拥有的就是保持寄存器 #1。您还拥有用户友好的文档。

b) 查看数字本身。如果您看到列表中的第一个寄存器的编号为 40001,这实际上告诉您它是寄存器 #1,并且它是一个保持寄存器。这种表示形式通常被称为旧的 Modicon 约定。

c) 查找要使用的功能代码的定义。如果您看到寄存器 #1,以及告诉您使用功能代码 3 和 16 的表示法,这也告诉您它是保持寄存器 #1。

重要提示:寄存器 1 的地址为 0。请继续阅读……

d) 文档中的数字是指寄存器编号还是地址?寄存器 #1 的地址为零。如果您的文档中提到的是寄存器还是地址不清楚,并且您没有得到预期的结果,请尝试将寄存器编号加一或减一。有些产品均在配置软件或网页中引用寄存器编号。但是,一些制造商在记录其设备时显示的是地址,而不是寄存器编号。

40001:Modicon 寄存器的 Modicon 约定符号

Modbus 最初由 Gould-Modicon(现为施耐德电气)开发。Modicon 最初使用的符号至今仍经常使用,尽管目前的 Modbus-IDA 标准认为它已过时。使用 Modicon 符号的优点是,一个数字中包含两条信息:(a) 寄存器类型;(b) 寄存器编号。寄存器编号偏移量定义类型。

Modbus 设备中引用的寄存器类型支持的寄存器类型包括:

  • 线圈(离散输出)
  • 离散输入(或状态输入)
  • 输入寄存器
  • 保持寄存器

对于上述每种寄存器类型,Modbus 最初定义的有效地址范围为 0 到 9999。当前规范中允许的有效范围为 0 到 65,535。

地址范围适用于每种类型的寄存器,需要查看 Modbus 消息包中的功能代码来确定引用的寄存器类型。Modicon 约定使用寄存器引用的第一位数字来识别寄存器类型。

使用 Modicon 符号识别的寄存器类型和引用范围如下:

  • 0x = 线圈 = 00001-09999
  • 1x = 离散输入 = 10001-19999
  • 3x = 输入寄存器 = 30001-39999
  • 4x = 保持寄存器 = 40001-49999

有时,需要访问超过 10,000 个寄存器类型。基于最初的约定,还有另一个看起来非常相似的事实上的标准。使用 Modicon 表示法识别的其他寄存器类型和参考范围如下:

  • 0x = 线圈 = 000001-065535
  • 1x = 离散输入 = 100001-165535
  • 3x = 输入寄存器 = 300001-365535
  • 4x = 保持寄存器 = 400001-465535

当使用扩展寄存器引用时,所有寄存器引用必须恰好是六位数字。

寄存器是 16 位 – 如何读取浮点或 32 位数据?

Modbus 协议将保持寄存器定义为 16 位宽;但是,对于读取和写入宽度超过 16 位的数据,存在一个广泛使用的事实标准。最常见的是 IEEE 754 浮点和 32 位整数。该约定也可以扩展到双精度浮点和 64 位整数数据。

宽数据仅由两个连续的“寄存器”组成,被视为单个宽寄存器。32 位 IEEE 754 标准中的浮点和 32 位整数数据被广泛使用。尽管寄存器对的约定得到广泛认可,但关于高阶或低阶寄存器应该先出现的约定尚未标准化。因此,许多设备都支持“交换”选项。这意味着,在某些情况下,“交换”选项更明确地标识为“高阶数据在第一个寄存器中”或类似内容。

大多数产品默认将高位寄存器放在第一位,或放在低位寄存器中。这称为“大端”,与 Modbus 协议一致,该协议本身就是大端。所有 16 位值的字节顺序都是最高有效字节在前。

40001:7 等符号是什么意思?

这是引用寄存器中各个位的常用符号。此特定示例引用(Modicon 表示法)寄存器 40001,位 7。位通常从位 0 开始编号,这是 Modbus 寄存器中 16 位字段中的最低有效位或最右边的位。如果使用此样式表示法,您可能会看到 40001:0 到 40001:15。

如何读取寄存器中的各个位?

每个 Modbus 设备的文档往往略有不同。但是,如果您的设备将多个位打包到一个保持寄存器中,文档将记录在同一寄存器编号或地址中找到的最多 16 个不同项目。这些位可以用“Bn”或“Dn”或只是“位 n”来标识。大多数情况下,最低有效位将称为位 0,最高有效位将是位 15。您可能会找到对位 1 到位 16 的引用,在这种情况下,只需从数字中减一即可参考下表。

您无法从保持寄存器中只读取一位。没有办法做到这一点 – Modbus 协议根本不提供该功能。您必须读取所有 16 位,然后测试您感兴趣的单个位是真还是假(1 或 0)。

Modbus 网络上可以有多少个设备?

从逻辑上讲,您可以寻址超过 250 个设备;然而,RS-485 收发器无法物理驱动那么多设备。 Modbus 协议规定限制为 32 个设备,大多数 RS-485 收发器都同意这一点。只有当网络上的所有设备都具有低负载收发器时,您才能拥有超过 32 个设备。

在哪里可以获取 Modbus 协议规范的副本?

您可以访问 www.modbus.org 获取 Modbus 协议规范的副本。主要关注三个文件: (1) 应用层协议,定义功能代码和寻址; (2)串行线路(RTU)使用的定义; (3)以太网使用(TCP)的定义。您将被要求接受使用条款,但这些规范无需支付任何费用。

Modbus 中的功能码和异常码

可视化 Modbus 设备中的数据

Modbus 从设备可以想象为具有一个内部电子表格,其中填满了数字。Modbus 主设备将向从设备询问其在给定行和列中找到的数据值或数字,从设备将通过将该数据发送回主设备来响应。当然,这个过程可以逆转,Modbus 主设备告诉从设备在给定行和列处将什么数字放入其数据表中。

Modbus 设备“电子表格”中的“列”更正式地称为寄存器类型。寄存器类型可能是线圈、离散输入(又称状态输入)、输入寄存器或保持寄存器。

Modbus 设备“电子表格”中的“行”只是寄存器编号。通常,这些行从 1 开始并按顺序递增。某些设备可能没有寄存器 1,例如,它们的第一个寄存器可能是 100。如果从设备中不存在寄存器编号,它将发回一个异常消息。该异常提供了一个错误代码,提示“没有这样的寄存器”(异常代码 2,非法数据地址)。

什么是 Modbus TCP?

Modbus TCP 将 Modbus RTU 请求和响应数据包封装在通过标准以太网网络传输的 TCP 数据包中。单元号仍包含在内,其解释因应用程序而异 – 单元或从站地址不是 TCP 中的主要寻址方式。这里最重要的地址是 IP 地址,例如 192.168.1.100。Modbus TCP 的标准端口是 502,但如果需要,通常可以重新分配端口号。

TCP 数据包中省略了通常位于 RTU 数据包末尾的校验和字段。对于 Modbus TCP,校验和和错误处理由以太网处理。

Modbus 的 TCP 版本遵循 OSI 网络参考模型。Modbus TCP 定义了 OSI 模型中的表示层和应用层。

Modbus TCP 使主设备和从设备的定义不那么明显,因为以太网允许对等通信。客户端和服务器的定义在基于以太网的网络中更为人所知。在这种情况下,从设备成为服务器,主设备成为客户端。可以有多个客户端从服务器获取数据。在 Modbus 术语中,这意味着可以有多个主设备和多个从设备。现在,系统设计人员的责任是创建主设备和从设备功能之间的逻辑关联,而不是逐个物理设备地定义主设备和从设备。

什么是 Modbus ASCII?

Modbus ASCII 是一种较旧的实现,它包含 RTU 数据包的所有元素,但完全以可打印的 ASCII 字符表示。Modbus ASCII 被认为已弃用,很少再使用,并且未包含在正式的 Modbus 协议规范中。

Modbus 寄存器类型回顾

Modbus 设备中引用的寄存器类型包括:

  • 线圈(离散输出)
  • 离散输入(或状态输入)
  • 输入寄存器
  • 保持寄存器

特定设备是否包含所有这些寄存器类型取决于制造商。所有 I/O 都仅映射到保持寄存器的情况非常常见。线圈是 1 位寄存器,用于控制离散输出,可以读取或写入。离散输入是用作输入的 1 位寄存器,只能读取。输入寄存器是用于输入的 16 位寄存器,只能读取。保持寄存器是最通用的 16 位寄存器,可以读取或写入,可用于各种用途,包括输入、输出、配置数据或任何“保持”数据的要求。

当网关为主控或以直接模式(Babel Buster SP-GW)运行时,网关将支持所有寄存器类型。将非 Modbus 设备连接到 Modbus 网络的控制解决方案网关在某些情况下将仅使用保持寄存器来表示非 Modbus 设备数据。

大多数控制解决方案 I/O 设备都使用保持寄存器来表示所有类型的输入和输出。在大多数情况下,相同的 I/O 也可以像其他寄存器类型一样访问,并且 I/O 状态或值在多个寄存器中镜像。

Modbus 功能码

Modbus 协议定义了几个用于访问 Modbus 寄存器的功能代码。Modbus 定义了四个不同的数据块,每个数据块中的地址或寄存器编号重叠。因此,要完整定义在何处查找数据,需要地址(或寄存器编号)和功能代码(或寄存器类型)。

下表列出了 Modbus 设备最常识别的功能代码。这只是可用代码的一个子集 – 其中一些代码具有通常不适用的特殊应用。

功能码 寄存器类型
1 读取线圈
2 读取离散输入
3 读取保持寄存器
4 读取输入寄存器
5 写入单个线圈
6 写入单个保持寄存器
15 写入多个线圈
16 写入多个保持寄存器

Modbus 异常(错误)代码

当 Modbus 从站识别出数据包,但确定请求中存在错误时,它将返回异常代码回复,而不是数据回复。异常回复由从站地址或单元号、设置了高位的功能代码副本和异常代码组成。例如,如果功能代码为 3,则异常回复中的功能代码将为 0x83。异常代码将是以下之一:

异常码 说明 详细说明
1 非法的功能码 查询中收到的功能代码不被从站识别或不被从站允许。
2 非法的数据地址 查询中收到的数据地址(寄存器编号)不是从站允许的地址,即寄存器不存在。如果请求多个寄存器,则至少有一个寄存器不被允许。
3 非法的数据值 查询数据字段中包含的值对于从站来说是不可接受的。
4 从设备故障 从站尝试执行请求的操作时发生不可恢复的错误
6 从设备忙 从属设备正在处理一个长持续时间的命令。主设备应稍后重试。
10 网关路径不可用 与网关结合使用的专门用途,通常意味着网关配置错误或超载
11 网关目标设备无法响应 专门与网关结合使用,表示未从目标设备收到响应。
12
 
Copyright © 2008-2021 lanxinbase.com Rights Reserved. | 粤ICP备14086738号-3 |