package com.xlaapp.modbus.serial.send;
import com.xlaapp.modbus.serial.other.ByteArrayWriter;
import com.xlaapp.modbus.serial.other.CRC16;
import com.xlaapp.modbus.serial.ModbusDataHandle;
import com.xlaapp.modbus.serial.error.ModbusError;
import com.xlaapp.modbus.serial.error.ModbusErrorType;
import com.xlaapp.modbus.serial.other.ModbusFunction;
import tp.xmaihh.serialport.SerialHelper;
public class ModbusRtuMaster {
private SerialHelper serialHelper;
//第1种使用serialport第三方库
public ModbusRtuMaster(SerialHelper serialHelper) {
this.serialHelper = serialHelper;
}
/**
* 组装Modbus RTU消息帧
* @param slave 从站地址号
* @param function_code 功能码
* @param starting_address 读取寄存器起始地址 / 写入寄存器地址 / 写入寄存器起始地址
* @param quantity_of_x 读取寄存器个数 / 写入寄存器个数
* @param output_value 需要写入单个寄存器的数值
* @param output_values 需要写入多个寄存器的数组
* @return 将整个消息帧转成byte[]
* @throws ModbusError Modbus错误
*/
synchronized private byte[] execute(int slave, int function_code, int starting_address, int quantity_of_x,
int output_value, int[] output_values) throws ModbusError {
//检查参数是否符合协议规定
if (slave < 0 || slave > 0xff) {
throw new ModbusError(ModbusErrorType.ModbusInvalidArgumentError, "Invalid slave " + slave);
}
if (starting_address < 0 || starting_address > 0xffff) {
throw new ModbusError(ModbusErrorType.ModbusInvalidArgumentError, "Invalid starting_address " + starting_address);
}
if (quantity_of_x < 1 || quantity_of_x > 0xff) {
throw new ModbusError(ModbusErrorType.ModbusInvalidArgumentError, "Invalid quantity_of_x " + quantity_of_x);
}
// 构造request
ByteArrayWriter request = new ByteArrayWriter();
//写入从站地址号
request.writeInt8(slave);
//根据功能码组装数据区
//如果为读取寄存器指令
if (function_code == ModbusFunction.READ_COILS || function_code == ModbusFunction.READ_DISCRETE_INPUTS
|| function_code == ModbusFunction.READ_INPUT_REGISTERS || function_code == ModbusFunction.READ_HOLDING_REGISTERS) {
request.writeInt8(function_code);
request.writeInt16(starting_address);
request.writeInt16(quantity_of_x);
} else if (function_code == ModbusFunction.WRITE_SINGLE_COIL || function_code == ModbusFunction.WRITE_SINGLE_REGISTER) {//写单个寄存器指令
if (function_code == ModbusFunction.WRITE_SINGLE_COIL)
if (output_value != 0) output_value = 0xff00;//如果为线圈寄存器(写1时为 FF 00,写0时为00 00)
request.writeInt8(function_code);
request.writeInt16(starting_address);
request.writeInt16(output_value);
} else if (function_code == ModbusFunction.WRITE_COILS) {//写多个线圈寄存器
request.writeInt8(function_code);
request.writeInt16(starting_address);
request.writeInt16(quantity_of_x);
//计算写入字节数
int writeByteCount = (quantity_of_x / 8) + 1;/// 满足关系-> (w /8) + 1
//写入数量 == 8 ,则写入字节数为1
if (quantity_of_x % 8 == 0) {
writeByteCount -= 1;
}
request.writeInt8(writeByteCount);
int index = 0;
//如果写入数据数量 > 8 ,则需要拆分开来
int start = 0;//数组开始位置
int end = 7;//数组结束位置
int[] splitData = new int[8];
//循环写入拆分数组,直到剩下最后一组 元素个数 <= 8 的数据
while (writeByteCount > 1) {
writeByteCount--;
int sIndex = 0;
for (index = start; index <= end; index++){
splitData [sIndex++] = output_values[index];
}
//数据反转 对于是否要反转要看你传过来的数据,如果高低位顺序正确则不用反转
splitData = ModbusDataHandle.reverseArr(splitData);
//写入拆分数组
request.writeInt8(ModbusDataHandle.toDecimal(splitData));
start = index;
end += 8;
}
//写入最后剩下的数据
int last = quantity_of_x - index;
int[] tData = new int[last];
System.arraycopy(output_values, index, tData, 0, last);
//数据反转 对于是否要反转要看你传过来的数据,如果高低位顺序正确则不用反转
tData = ModbusDataHandle.reverseArr(tData);
request.writeInt8(ModbusDataHandle.toDecimal(tData));
} else if (function_code == ModbusFunction.WRITE_HOLDING_REGISTERS) {//写多个保持寄存器
request.writeInt8(function_code);
request.writeInt16(starting_address);
request.writeInt16(quantity_of_x);
request.writeInt8(2 * quantity_of_x);
//写入数据
for (int v : output_values) {
request.writeInt16(v);
}
} else {
throw new ModbusError(ModbusErrorType.ModbusFunctionNotSupportedError, "Not support function " + function_code);
}
byte[] bytes = request.toByteArray();
//计算CRC校验码
int crc = CRC16.compute(bytes);
request.writeInt16Reversal(crc);
bytes = request.toByteArray();
return bytes;
}
/**
* 读多个线圈寄存器
* @param slave 从站地址
* @param startAddress 起始地址
* @param numberOfPoints 读取线圈寄存器个数
* @throws ModbusError Modbus错误
*/
public void readCoils(int slave, int startAddress, int numberOfPoints) throws ModbusError {
byte[] sendBytes = execute(slave, ModbusFunction.READ_COILS, startAddress, numberOfPoints, 0, null);
this.serialHelper.send(sendBytes);
}
//读单个线圈寄存器
public void readCoil(int slave, int address) throws ModbusError {
readCoils(slave, address, 1);
}
/**
* 读多个保持寄存器
* @param slave 从站地址
* @param startAddress 起始地址
* @param numberOfPoints 读取保持寄存器个数
* @throws ModbusError Modbus错误
*/
public void readHoldingRegisters(int slave, int startAddress, int numberOfPoints) throws ModbusError {
byte[] sendBytes = execute(slave, ModbusFunction.READ_HOLDING_REGISTERS, startAddress, numberOfPoints, 0, null);
this.serialHelper.send(sendBytes);
}
//读单个保持寄存器
public void readHoldingRegister(int slave, int address) throws ModbusError {
readHoldingRegisters(slave, address, 1);
}
/**
* 读多个输入寄存器
* @param slave 从站地址
* @param startAddress 起始地址
* @param numberOfPoints 读取输入寄存器个数
* @throws ModbusError Modbus错误
*/
public void readInputRegisters(int slave, int startAddress, int numberOfPoints) throws ModbusError {
byte[] sendBytes = execute(slave, ModbusFunction.READ_INPUT_REGISTERS, startAddress, numberOfPoints, 0, null);
this.serialHelper.send(sendBytes);
}
//读单个输入寄存器
public void readInputRegister(int slave, int address) throws ModbusError {
readInputRegisters(slave, address, 1);
}
/**
* 读多个离散输入寄存器
* @param slave 从站地址
* @param st
没有合适的资源?快使用搜索试试~ 我知道了~
Modbus串口通信源码
共15个文件
java:15个
5星 · 超过95%的资源 需积分: 49 15 下载量 109 浏览量
2022-06-15
15:55:22
上传
评论
收藏 14KB ZIP 举报
温馨提示
Modbus串口通信源码,文章讲解链接:https://blog.csdn.net/zhouhangzooo/article/details/122998110 安卓设置(服务端)与上位机(客户端)之间通信,通过RS232或者RS485串口线链接两端设置,两端配置端口号打开串口,通过Mobdus协议进行通信。 此zip包包含串口通信安卓端源码,包括接收上位机,解析功能码,读取处理,响应报文等。
资源详情
资源评论
资源推荐
收起资源包目录
serial.zip (15个子文件)
serial
IModbusListener.java 119B
receive
ModbusParse.java 4KB
ModbusResponse.java 4KB
other
ByteUtil.java 6KB
CRC16.java 9KB
ModbusFunction.java 842B
ByteArrayWriter.java 1KB
send
ModbusRtuMaster.java 10KB
ModbusUtil.java 3KB
ModbusConfig.java 161B
error
ModbusErrorType.java 448B
ModbusError.java 670B
execute
ModbusReadCoil.java 819B
ModbusWriteCoil.java 820B
ModbusDataHandle.java 3KB
共 15 条
- 1
zhouhangzooo
- 粉丝: 35
- 资源: 9
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
评论5