java modbus协议

java modbus协议javamodbus 协议

概念

Modbus是一种串行通信协议,Modbus协议目前存在用于串口、以太网以及其他支持互联网协议的网络的版本。
大多数Modbus设备通信通过串口EIA-485物理层进行。

通讯格式

地址域 功能码 数据 CRC校验(低字节在前)
1字节 1字节 N字节 2字节

功能码说明

实际用途中常用的功能码有:

  • 0x03用来读取单片机寄存器的数据
  • 0x06用来给单片机写入数据
功能码0x03:读单个或多个保持寄存器
设备地址(1字节) 功能码(1字节) 寄存器起始地址(2字节) 寄存器数量(2字节) CRC校验(2字节)
XX 03 XX XX XX XX XX XX

响应:

设备地址(1字节) 功能码(1字节) 数据长度(2字节) 数据(N字节) CRC校验(2字节)
XX 03 XX XX N字节 XX XX
设备地址(1字节) 功能码(1字节) 数据长度(2字节) 数据(N字节) CRC校验(2字节)
01 03 00 01 00 01 D5 CA

查询设备类型响应

设备地址(1字节) 功能码(1字节) 数据长度(2字节) 数据(N字节) CRC校验(2字节)
01 03 02 00 21 78 5C
功能码0x06:写单个寄存器
设备地址(1字节) 功能码(1字节) 寄存器地址(2字节) 数据(N字节) CRC校验(2字节)
XX 06 XX XX N字节 XX XX

响应:

设备地址(1字节) 功能码(1字节) 寄存器地址(2字节) 数据(N字节) CRC校验(2字节)
XX 06 XX XX N字节 XX XX
设备地址(1字节) 功能码(1字节) 寄存器地址(2字节) 数据(N字节) CRC校验(2字节)
01 06 00 14 00 00 C9 CE

Java版modbus协议代码:

package com.wrs.project.modbus; import java.util.ArrayList; import java.util.List; public class ModbusUtils { / * 读指令 * @param deviceAddress 设备地址 * @param registerAddress 寄存器起始地址 * @param registerCount 寄存器个数 * @return */ public static byte[] getReadModbus(int deviceAddress, int registerAddress, int registerCount) { int registerLow = registerAddress & 0xFF; int registerHigh = registerAddress >>> 8; int countLow = registerCount & 0xFF; int countHigh = registerCount >>> 8; int[] data = new int[]{registerHigh, registerLow, countHigh, countLow}; byte[] sendData = getModbusData(deviceAddress, 0x03, data); return sendData; } / * 写指令 * @param deviceAddress 设备地址 * @param registerAddress 寄存器起始地址 * @param writeData 寄存器个数 * @return */ public static byte[] getWriteModbus(int deviceAddress, int registerAddress, int[] writeData) { int registerLow = registerAddress & 0xFF; int registerHigh = registerAddress >>> 8; int[] data = new int[writeData.length + 2]; data[0] = registerHigh; data[1] = registerLow; for (int i = 0; i < writeData.length; i ++) { data[i + 2] = writeData[i]; } byte[] sendData = getModbusData(deviceAddress, 0x06, data); return sendData; } public static List 
  
    isValidModbusResponseData(List 
   
     list) { if (null != list && list.size() >= 4) { int size = list.size(); int leng = ByteUtils.byteToInt(list.get(2)); int totalSize = leng + 5; if (size < totalSize) { return null; } List tempList = list.subList(0, totalSize - 2); byte[] tempData = ArrayUtils.listTobyte(tempList); int crc = CRCUtils.getCRC(tempData); int low = crc & 0xFF; int high = crc >>> 8; byte lowData = list.get(totalSize - 2); byte hightData = list.get(totalSize - 1); if (low == ByteUtils.byteToInt(lowData) && high == ByteUtils.byteToInt(hightData)) { return list.subList(0, totalSize); } else { return null; } } else { return null; } } public static byte[] getModbusData(int address, int function, int[] data) { int leng = 2; if (null != data) { leng += data.length; } byte[] tempData = new byte[leng]; tempData[0] = ByteUtils.intToByte(address); tempData[1] = ByteUtils.intToByte(function); if (null != data) { for (int i = 0; i < data.length; i++) { tempData[i + 2] = ByteUtils.intToByte(data[i]); } } int crc = CRCUtils.getCRC(tempData); int low = crc & 0xFF; int high = crc >>> 8; List list = new ArrayList(); list.addAll(ArrayUtils.byteToList(tempData)); list.add(ByteUtils.intToByte(low)); list.add(ByteUtils.intToByte(high)); return ArrayUtils.listTobyte(list); } } 
    
  

项目源码:https://codechina.csdn.net/it1/modbusproject

如果觉得可以就点个?吧,欢迎粉丝收藏,土豪打赏,您的关注就是我们创作的动力!

读者有什么想看的相关技术篇章,欢迎评论留言!

交流群:

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/226643.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月16日 下午10:27
下一篇 2026年3月16日 下午10:27


相关推荐

  • 代码走查1

    代码走查1线上问 和研发一起简单的从代码层面去解决问题 略 low 代码走查 1 存在的问题 SQL 查询 1 对于业务上没有用的字段没必要添加比如 IsDel 在具体的业务上 删除数据是直接硬删除 直接删除了物理数据 所以 在 SQL 查询的时候 SQL 读着可能没有问题 但实际执行却没有意义 没必要添加 2 不等于 查空值 要和判断语句相符合 不要在 SQL 语句中否定 而 if 判断中肯定 很容易迷茫

    2025年10月24日
    5
  • pycharm整体缩进的快捷键

    pycharm整体缩进的快捷键选中多行 按 tab 进行缩进 按 tab shift 去除缩进

    2026年3月27日
    3
  • C++函数模板(模板函数)详解

    C++函数模板(模板函数)详解定义用法:函数模板的原理延申用法2.1为什么需要类模板2.2单个类模板语法2.3继承中的类模板语法案例1:案例2:2.4类模板的基础语法2.5类模板语法知识体系梳理1.所有的类模板函数写在类的内部复数类:2.所有的类模板函数写在类的外部,在一个cpp中2.5总结关于类模板的几点说明:2.6类模板中的static关键字案例2:以下来自:C++类模板遇上static关键字…

    2022年4月4日
    52
  • C#用什么开发_hbase写数据流程

    C#用什么开发_hbase写数据流程最近公司程序需要嵌入各个浏览器的插件。首先

    2025年5月28日
    4
  • iOS layoutSubviews 调用[通俗易懂]

    iOS layoutSubviews 调用[通俗易懂]在初始化时,使用init和-(instancetype)initWithFrame:(CGRect)frame,但是,在调用时是有系统区分的,iOS11.0以下,调用init和-(instancetype)initWithFrame:(CGRect)frame当frame为CGRectZero是不会调用的, 在调用addSubView时,这个跟添加的subView尺寸大小没有关系。 改变…

    2022年7月15日
    18
  • linux 实现不同网段网络互通[通俗易懂]

    linux 实现不同网段网络互通[通俗易懂]实现:网络:10.10.100.0/24网络:172.16.100.0/24网络:192.168.10.0/24server1:10.10.100.128/24server2:172.16.100.132/24server3:192.168.10.131/24server4:10.10.100.129/24172.16.100.133/24192.168.10.132/24在linux中实现网络互通实现不通网段的网络互通需要借助net-tools所以首先在每个设备上需要安装

    2025年10月31日
    6

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号