Java串口通信
程序员文章站
2022-04-19 10:57:40
JAVA 串口通信1.准备工具2.项目JAR包3. 窗口工具类4. 串口监听器5.调用案列1.准备工具JAVA串口通信准备工具下载这里只提供了win版本下的32位及64位,其他操作系统,请前往官网下载选择自己需要的RXTXcomm.jar1.将rxtxSerial.dll和rxtxParallel.dll拷贝至 %JAVA_HOME%\jre\bin目录下2.将RXTXcomm.jar 拷贝至 %JAVA_HOME%\jre\lib\ext 目录下2.项目JAR包创建Springboo...
1.准备工具
2.项目JAR包
<!-- 串口开发中用到的工具类 -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.5.9</version>
</dependency>
3. 串口工具类
/**
* 串口管理
* @author SmallDemon
*/
public class SerialPortManager {
/**
* 查找所有可用端口
*
* @return 可用端口名称列表
*/
@SuppressWarnings("unchecked")
public static final ArrayList<String> findPort() {
// 获得当前所有可用串口
Enumeration<CommPortIdentifier> portList = CommPortIdentifier.getPortIdentifiers();
ArrayList<String> portNameList = new ArrayList<String>();
// 将可用串口名添加到List并返回该List
while (portList.hasMoreElements()) {
String portName = portList.nextElement().getName();
portNameList.add(portName);
}
return portNameList;
}
/**
* 打开串口
*
* @param portName 端口名称
* @param baudrate 波特率
* @return 串口对象
* @throws SerialPortParameterFailure 设置串口参数失败
* @throws NotASerialPort 端口指向设备不是串口类型
* @throws NoSuchPort 没有该端口对应的串口设备
* @throws PortInUse 端口已被占用
*/
public static final SerialPort openPort(String portName, int baudrate) throws Exception {
try {
// 通过端口名识别端口
CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName);
// 打开端口,设置端口名与timeout(打开操作的超时时间)
CommPort commPort = portIdentifier.open(portName, 2000);
// 判断是不是串口
if (commPort instanceof SerialPort) {
SerialPort serialPort = (SerialPort) commPort;
try {
// 设置串口的波特率等参数
serialPort.setSerialPortParams(baudrate, SerialPort.DATABITS_8, SerialPort.STOPBITS_1,
SerialPort.PARITY_EVEN);
} catch (UnsupportedCommOperationException e) {
throw new Exception("设置串口参数失败", e);
}
return serialPort;
} else {
throw new Exception("不是串口");
}
} catch (NoSuchPortException e1) {
throw new Exception("没有该端口对应的串口设备", e1);
} catch (PortInUseException e2) {
throw new Exception("端口已被占用", e2);
}
}
/**
* 向串口发送数据
*
* @param serialPort 串口对象
* @param order 待发送数据
* @throws SendDataToSerialPortFailure 向串口发送数据失败
* @throws SerialPortOutputStreamCloseFailure 关闭串口对象的输出流出错
*/
public static void sendToPort(SerialPort serialPort, byte[] order) throws Exception {
OutputStream out = null;
try {
out = serialPort.getOutputStream();
out.write(order);
out.flush();
} catch (IOException e) {
throw new Exception("向串口发送数据失败",e);
} finally {
try {
if (out != null) {
out.close();
out = null;
}
} catch (IOException e) {
throw new Exception("关闭串口对象的输出流出错",e);
}
}
}
/**
* 从串口读取数据
*
* @param serialPort 当前已建立连接的SerialPort对象
* @return 读取到的数据
* @throws ReadDataFromSerialPortFailure 从串口读取数据时出错
* @throws SerialPortInputStreamCloseFailure 关闭串口对象输入流出错
*/
public static byte[] readFromPort(SerialPort serialPort) throws Exception {
InputStream in = null;
byte[] bytes = null;
try {
in = serialPort.getInputStream();
// 获取buffer里的数据长度
int bufflenth = in.available();
while (bufflenth != 0) {
// 初始化byte数组为buffer中数据的长度
bytes = new byte[bufflenth];
in.read(bytes);
bufflenth = in.available();
}
} catch (IOException e) {
throw new Exception("从串口读取数据时出错",e);
} finally {
try {
if (in != null) {
in.close();
in = null;
}
} catch (IOException e) {
throw new Exception("关闭串口对象输入流出错",e);
}
}
return bytes;
}
/**
* 添加监听器
*
* @param port 串口对象
* @param listener 串口监听器
* @throws TooManyListeners 监听类对象过多
*/
public static void addListener(SerialPort port, SerialPortEventListener listener) throws Exception {
try {
// 给串口添加监听器
port.addEventListener(listener);
// 设置当有数据到达时唤醒监听接收线程
port.notifyOnDataAvailable(true);
// 设置当通信中断时唤醒中断线程
port.notifyOnBreakInterrupt(true);
} catch (TooManyListenersException e) {
throw new Exception("监听类对象过多", e);
}
}
/**
* 关闭串口
*
* @param serialport 待关闭的串口对象
*/
public static void closePort(SerialPort serialPort) {
if (serialPort != null) {
serialPort.close();
serialPort = null;
}
}
}
4. 串口监听器
/**
* 监听串口通信中断及其接收信息
* @author SmallDemon
*/
public abstract class SerialListener implements SerialPortEventListener{
private SerialPort serialPort = null;
public SerialListener(SerialPort serialPort) {
this.serialPort = serialPort;
}
@Override
public void serialEvent(SerialPortEvent serialPortEvent) {
// TODO Auto-generated method stub
switch (serialPortEvent.getEventType()) {
case SerialPortEvent.BI: // 10 通讯中断
closeSerial(serialPort);
break;
case SerialPortEvent.OE: // 7 溢位(溢出)错误
case SerialPortEvent.FE: // 9 帧错误
case SerialPortEvent.PE: // 8 奇偶校验错误
case SerialPortEvent.CD: // 6 载波检测
case SerialPortEvent.CTS: // 3 清除待发送数据
case SerialPortEvent.DSR: // 4 待发送数据准备好了
case SerialPortEvent.RI: // 5 振铃指示
case SerialPortEvent.OUTPUT_BUFFER_EMPTY: // 2 输出缓冲区已清空
break;
case SerialPortEvent.DATA_AVAILABLE: // 1 串口存在可用数据
byte[] data = null;
try {
data = SerialPortManager.readFromPort(serialPort);
readString(data);
} catch (Exception e) {
// 发生读取错误时显示错误信息后退出系统
System.exit(0);
}
break;
default:
break;
}
}
public abstract void readString(byte[] data);
public abstract void closeSerial(SerialPort serialPort);
}
5.调用案列
public static void main(String[] args) throws Exception {
ArrayList<String> findPort = SerialPortManager.findPort();
System.err.println("查找出的串口:" + findPort);
SerialPort openPort = SerialPortManager.openPort(findPort.get(0), 9600);
SerialListener serialListener = new SerialListener(openPort) {
@Override
public void readString(byte[] data) {
// 解析数据
String decodeHexStr = HexUtil.decodeHexStr(HexUtil.encodeHexStr(data), CharsetUtil.CHARSET_UTF_8);
System.err.println(decodeHexStr);
}
@Override
public void closeSerial(SerialPort serialPort) {
System.err.println("串口连接中断");
}
};
SerialPortManager.addListener(openPort, serialListener);
String send = "测试发送串口信息";
byte[] decodeHex = HexUtil.decodeHex(HexUtil.encodeHexStr(send));
SerialPortManager.sendToPort(openPort, decodeHex);
}
参考文档:https://blog.csdn.net/kong_gu_you_lan/article/details/52302075
本文地址:https://blog.csdn.net/qq_36296155/article/details/114264470