欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Java串口通信

程序员文章站 2022-09-20 09:41:21
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

相关标签: Java 串口通信