目录
Modbus协议基础概念
什么是Modbus
Modbus是一种串行通信协议,由Modicon公司(现为施耐德电气)于1979年发布。它是工业自动化领域中最常用的通信协议之一,具有以下特点:
- 开放性:免费使用,无需许可证
- 简单性:易于实现和维护
- 可靠性:具有错误检测机制
- 广泛支持:几乎所有PLC和工业设备都支持
主要变种
- Modbus RTU:基于RS232/RS485串行通信
- Modbus TCP:基于以太网TCP/IP通信
- Modbus ASCII:基于ASCII编码的串行通信
基本数据模型
Modbus定义了四种基本数据类型:
数据类型 | 地址范围 | 访问权限 | 说明 |
---|---|---|---|
线圈 (Coils) | 00001-09999 | 读/写 | 单比特,输出类型 |
离散输入 (Discrete Inputs) | 10001-19999 | 只读 | 单比特,输入类型 |
输入寄存器 (Input Registers) | 30001-39999 | 只读 | 16位,输入类型 |
保持寄存器 (Holding Registers) | 40001-49999 | 读/写 | 16位,输出类型 |
Modbus RTU详解
协议特点
- 传输方式:串行通信(RS232/RS485)
- 数据格式:二进制
- 错误检测:CRC16校验
- 传输效率:相对较高(二进制格式)
帧结构
Modbus RTU帧结构如下:
+----------+----------+----------+----------+----------+----------+
| 设备地址 | 功能码 | 数据域 | CRC校验 | 间隔 |
| 1 byte | 1 byte | N bytes | 2 bytes | 3.5字符 |
+----------+----------+----------+----------+----------+----------+
详细说明:
- 设备地址(1字节):从站设备地址,0为广播地址,1-247为有效设备地址
- 功能码(1字节):指定要执行的操作类型
- 数据域(可变长度):包含请求/响应的具体数据
- CRC校验(2字节):循环冗余校验,用于检测传输错误
- 静默间隔(3.5字符时间):帧之间的最小间隔
常用功能码
功能码 | 十六进制 | 功能描述 | 操作对象 |
---|---|---|---|
01 | 0x01 | 读线圈状态 | 线圈 |
02 | 0x02 | 读离散输入状态 | 离散输入 |
03 | 0x03 | 读保持寄存器 | 保持寄存器 |
04 | 0x04 | 读输入寄存器 | 输入寄存器 |
05 | 0x05 | 写单个线圈 | 线圈 |
06 | 0x06 | 写单个寄存器 | 保持寄存器 |
15 | 0x0F | 写多个线圈 | 线圈 |
16 | 0x10 | 写多个寄存器 | 保持寄存器 |
通信流程
- 主站发送请求:主站构造请求帧并发送给从站
- 从站接收处理:从站接收帧,校验CRC,解析功能码
- 从站响应:从站执行操作并返回响应帧
- 主站接收响应:主站接收响应,校验CRC,解析数据
Modbus TCP详解
协议特点
- 传输方式:以太网TCP/IP
- 数据格式:二进制
- 错误检测:依赖TCP协议的校验机制
- 传输效率:网络传输,速度快
帧结构
Modbus TCP在RTU基础上添加了MBAP头:
+----------+----------+----------+----------+----------+----------+----------+
| 事务ID | 协议ID | 长度域 | 单元ID | 功能码 | 数据域 |
| 2 bytes | 2 bytes | 2 bytes | 1 byte | 1 byte | N bytes |
+----------+----------+----------+----------+----------+----------+----------+
| MBAP头部 | PDU部分 |
详细说明:
- 事务ID(2字节):用于匹配请求和响应
- 协议ID(2字节):Modbus协议标识符,通常为0
- 长度域(2字节):后续数据的字节数
- 单元ID(1字节):目标设备标识符
- 功能码(1字节):与RTU相同的功能码
- 数据域(可变长度):实际的数据内容
与RTU的区别
- 无CRC校验:TCP层提供错误检测
- 添加MBAP头:提供事务管理和路由信息
- 网络传输:基于以太网,支持远程通信
- 并发连接:支持多个客户端同时连接
Spring Boot集成Modbus RTU
依赖配置
在pom.xml
中添加必要依赖:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- Modbus4j库 -->
<dependency>
<groupId>com.infiniteautomation</groupId>
<artifactId>modbus4j</artifactId>
<version>3.0.3</version>
</dependency>
<!-- 串口通信库 -->
<dependency>
<groupId>org.scream3r</groupId>
<artifactId>jssc</artifactId>
<version>2.8.0</version>
</dependency>
<!-- 或者使用RXTX -->
<dependency>
<groupId>org.rxtx</groupId>
<artifactId>rxtx</artifactId>
<version>2.1.7</version>
</dependency>
</dependencies>
配置类
@Configuration
@ConfigurationProperties(prefix = "modbus.rtu")
@Data
public class ModbusRtuConfig {
private String portName = "COM1";
private i