Java 实现 Modbus RTU 协议

Modbus RTU 是一种用于工业设备之间通讯的串行通信协议,广泛应用于监控和控制系统。它以主从模式运作,主设备通过请求从设备生成数据。在这篇文章中,我们将探讨如何使用 Java 语言实现 Modbus RTU 协议。

1. Modbus RTU 协议简介

Modbus RTU 协议的基本结构包括设备地址、功能码、数据和 CRC 校验码。每个数据帧通常遵循以下格式:

| 开始符 | 地址 | 功能码 | 数据 | CRC |
  • 开始符:用于标识帧的开头
  • 地址:目标设备的地址
  • 功能码:指示要执行的操作
  • 数据:操作所需的参数
  • CRC:循环冗余校验,用于数据完整性校验

2. Java 代码实现

为了实现 Modbus RTU 协议,我们可以使用 Java 的串口通信库,例如 javax.comm 库,或常用的 jSerialComm 库。以下是一个简单的例子,演示如何发送 Modbus RTU 命令读取寄存器。

依赖库设置: 在 pom.xml 中添加 jSerialComm 依赖:

<dependency>
    <groupId>com.fazecast</groupId>
    <artifactId>jSerialComm</artifactId>
    <version>2.9.0</version>
</dependency>

Java 代码示例

import com.fazecast.jSerialComm.SerialPort;

public class ModbusRTU {

    private SerialPort serialPort;

    public ModbusRTU(String portName) {
        serialPort = SerialPort.getCommPort(portName);
        serialPort.setComPortParameters(9600, 8, 1, 0);
        serialPort.openPort();
    }

    public void close() {
        serialPort.closePort();
    }

    public void sendRequest(byte address, byte functionCode, byte[] data) {
        byte[] request = new byte[5 + data.length];
        request[0] = address;    // 设备地址
        request[1] = functionCode; // 功能码
        System.arraycopy(data, 0, request, 2, data.length); // 数据
        int crc = calculateCRC(request);
        request[request.length - 2] = (byte) (crc & 0xFF); // CRC 低字节
        request[request.length - 1] = (byte) ((crc >> 8) & 0xFF); // CRC 高字节

        serialPort.writeBytes(request, request.length);
    }

    private int calculateCRC(byte[] buffer) {
        int crc = 0xFFFF;
        for (byte b : buffer) {
            crc ^= b;
            for (int i = 0; i < 8; i++) {
                if ((crc & 0x0001) != 0) {
                    crc = (crc >> 1) ^ 0xA001;
                } else {
                    crc >>= 1;
                }
            }
        }
        return crc;
    }

    public static void main(String[] args) {
        ModbusRTU modbus = new ModbusRTU("COM3");
        modbus.sendRequest((byte) 0x01, (byte) 0x03, new byte[] {0x00, 0x00, 0x00, 0x02}); // 读取寄存器
        modbus.close();
    }
}

3. 序列图描述

下面是一个简单的序列图,展示了 Modbus 主从设备通信的过程:

sequenceDiagram
    participant 主设备
    participant 从设备

    主设备->>从设备: 发送 Modbus 请求
    从设备->>主设备: 返回 Modbus 响应

结论

本文介绍了如何使用 Java 实现 Modbus RTU 协议,包括串口通信的基本设置、发送请求基本流程,以及 CRC 校验的实现。通过这个示例,您可以进一步扩展功能,例如添加对不同功能码的支持、处理从设备的响应等。希望本篇文章能为您的项目开发提供帮助,祝您编程愉快!