java中用byte数组模拟modbus线圈和离散变量,核心是将每个byte视为8个独立bit,通过位运算存取开关状态;线圈地址映射为字节索引=address/8、位偏移=address%8;支持设置、读取、批量初始化等操作,并需区分线圈(可读写)与离散输入(只读)的语义及地址空间。
java 中用 byte 模拟 modbus 线圈和离散变量,核心是把 1 个 byte 当作 8 个独立的位(bit)来存取开关状态,而不是当数值用。线圈(coil)和离散输入(discrete input)都是单 bit 的只读或可写信号,协议规定它们按位打包传输,所以必须做位运算操作。
理解 byte 与线圈地址的映射关系
Modbus 线圈地址从 0 开始编号,每 8 个连续线圈正好占 1 个字节:
- 线圈 0~7 → 第 0 字节(索引 0),bit0~bit7 分别对应 coil0~coil7
- 线圈 8~15 → 第 1 字节(索引 1),bit0~bit7 对应 coil8~coil15
- 以此类推:字节索引 = coilAddress / 8,位偏移 = coilAddress % 8
例如:读取线圈地址 13 → 落在第 1 个字节(13/8=1),第 5 位(13%8=5),即该字节的 bit5(从低位开始数,0 起始)。
用 byte 数组模拟一组线圈状态
定义一个 byte[] coils 表示多个线圈,每个元素存 8 个状态。常用操作包括:
当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。
-
设置某线圈为 true(ON):
coils[index] |= (1 -
设置某线圈为 false(OFF):
coils[index] &= ~(1 -
读取某线圈值:
((coils[index] >> bitPos) & 0x01) == 1或更简洁地(coils[index] & (1 -
批量初始化(全 OFF):
Arrays.fill(coils, (byte)0);
注意:Java 中 byte 是有符号类型,但位操作时只需关注低 8 位,无需转 int;解析响应报文时直接按无符号逻辑处理即可。
处理 Modbus 响应报文中的线圈数据
功能码 01(读线圈)或 02(读离散输入)的响应中,数据区是紧凑的位流。例如读取 13 个线圈,需 2 字节(13÷8 向上取整 = 2),末字节高位补零:
- 假设响应数据为
new byte[]{(byte)0xCD, (byte)0x02}(十六进制 CD=11001101,02=00000010) - 共 16 位,对应线圈 0~15;其中线圈 13 的位置是第 1 字节 + bit5 →
0x02 & (1?不对——实际顺序是:第一个字节最低位是线圈 0,所以线圈 13 应查第 1 字节(索引 1)的 bit5 → <code>(0x02 & (1 → true - 推荐封装工具方法:
getCoil(byte[] data, int coilAddr),内部自动算 index 和 bitPos
区分线圈与离散输入的语义处理
虽然二者底层都用 bit 表示,但权限和用途不同,模拟时建议分开建模:
-
线圈(Coil):声明为可读写数组(如
volatile byte[] coils),支持 set/get;写操作需触发控制逻辑(如继电器动作) -
离散输入(Discrete Input):声明为只读数组(如
final byte[] inputs),仅由外部事件更新(如传感器中断置位),应用层不提供写入口 - 两者地址空间独立:线圈地址通常为 00001–09999,离散输入为 10001–19999,模拟时可用不同数组或带 type 标识的统一结构
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










