• 还是半年前接触的JAVA串口编程控制硬件,现在项目中又即将运用到,所以特别写成博客记录,同时分享交流。
  • Java环境中的JDK是本身不带有串口的jar包的,需要我们自己下载然后配置到本地的JDK之中,我们采用RXTX串口包(sun公司也提供了一个串口包但是十多年没更新了,不支持64位机器),RXTX是另外一个公司提供的,支持Windows和linux的。

官网下载地址:http://fizzed.com/oss/rxtx-for-java


自己选择版本下载压缩包,然后解压。我们这里用Windows64位的,解压后如下图

将这个配置到本地JDK中,步骤如下:
复制 RXTXcomm.jar —> <JAVA_HOME>\jre\lib\ext
复制 rxtxSerial.dll —> <JAVA_HOME>\jre\bin
复制 rxtxParallel.dll —> <JAVA_HOME>\jre\bin
注意:是JAVA_HOME里面的jdk目录,不是jre的目录
如我的是:
安装好本地JDK串口环境我们就可以在项目中使用了。

将需要控制的USB串口设备连接到你的电脑上,然后我们电脑上就会多一个串口,我们需要知道它的串口名字。

查看串口步骤:

计算机(我的电脑)–右键–管理–设备管理器–端口 如下图:
COM3就是我们插入的USB串口名字,我们在后面的代码中就是要根据这个COM3串口名对其进行硬件的控制。

import gnu.io.*;import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;/*** 警灯控制类 方法包括 init(PortName)初始化串口* closeSerialPort()关闭串口* openLamp(int second)开启警灯 到时间自动关闭* closeLamp()关闭警灯* <p>* 说明:无论是开启警灯和关闭警灯都需要先进行初始化串口*/
// 注:串口操作类一定要实现SerialPortEventListener
public class lamp implements SerialPortEventListener {// 检测系统中可用的通讯端口类private CommPortIdentifier portId;// 枚举类型private Enumeration<CommPortIdentifier> portList;// RS232串口private SerialPort serialPort;// 输入输出流private InputStream inputStream;private OutputStream outputStream;//实现接口SerialPortEventListener中的方法@Overridepublic void serialEvent(SerialPortEvent serialPortEvent) {switch (serialPortEvent.getEventType()) {case SerialPortEvent.BI:    //通讯中断case SerialPortEvent.OE:    //溢位错误case SerialPortEvent.FE:    //帧错误case SerialPortEvent.PE:    //奇偶校验错误case SerialPortEvent.CD:    //载波检测case SerialPortEvent.CTS:    //清除发送case SerialPortEvent.DSR:    //数据设备准备好case SerialPortEvent.RI:    //响铃侦测case SerialPortEvent.OUTPUT_BUFFER_EMPTY:    //输出缓冲区已清空break;case SerialPortEvent.DATA_AVAILABLE:    //有数据到达break;default:break;}}/*** 初始化  需要把串口名传入*/public String init(String PortName0) {//获取系统中所有的通讯端口portList = CommPortIdentifier.getPortIdentifiers();//把串口名进行优化,默认自动转成大写 让其传入值可忽略大小写String PortName = PortName0.toUpperCase();// 循环通讯端口while (portList.hasMoreElements()) {portId = portList.nextElement();// 判断是否是串口if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {// 比较串口名称是否是我们所要的那个if (PortName.equals(portId.getName())) {System.out.println("找到警灯串口" + PortName);try {//如果确实是我们需要的串口,则打开这个串口// 并且需要转化成非抽象的serialPort类才能进行操作serialPort = (SerialPort) portId.open(Object.class.getSimpleName(), 2000);System.out.println("获取到警灯串口对象," + PortName);//获取输入输出流outputStream = serialPort.getOutputStream();inputStream = serialPort.getInputStream();// 设置串口通讯参数// 波特率,数据位,停止位和校验方式// 波特率2400,偶校验serialPort.setSerialPortParams(9600, SerialPort.DATABITS_8,//SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);return "初始化成功";} catch (PortInUseException e) {System.out.println("该串口已经被占用");} catch (UnsupportedCommOperationException e) {System.out.println("为发现该串口");} catch (IOException e) {e.printStackTrace();}}}}return null;}/*** 关闭串口*/public void closeSerialPort() {if (serialPort != null) {serialPort.notifyOnDataAvailable(false);serialPort.removeEventListener();if (inputStream != null) {try {inputStream.close();inputStream = null;} catch (IOException e) {}}if (outputStream != null) {try {outputStream.close();outputStream = null;} catch (IOException e) {}}serialPort.close();System.out.println("串口已关闭");serialPort = null;}}
//------------------------------------下面是我自己写的,用来控制警灯的------------------------------------/*** 打开警灯 需要传入时间 单位:秒 当为0时则一直开启 不会自动关闭** 到时间后警灯会自动关闭** @param second*/
public void openLamp(int second) {//如果传入时间为0则默认一直开启  不会自动关闭String msg = "FE050000FF009835";//要发送的命令msgtry {outputStream.write(hexStringToBytes(msg));System.out.println("警灯已开启");if(second!=0){try {Thread.sleep(1000*second);closeLamp();System.out.println("警灯已关闭");} catch (Exception e) {e.printStackTrace();}}} catch (IOException e) {e.printStackTrace();}
}
//控制硬件基本都是16+进制,发送指令的时候需要16进制转成字节数组
//将输入的16进制string转成字节
public static byte[] hexStringToBytes(String hexString) {if (hexString == null || hexString.equals("")) {return null;}hexString = hexString.toUpperCase();int length = hexString.length() / 2;char[] hexChars = hexString.toCharArray();byte[] d = new byte[length];for (int i = 0; i < length; i++) {int pos = i * 2;d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));}return d;
}private static byte charToByte(char c) {return (byte) "0123456789ABCDEF".indexOf(c);
}/*** 关闭警灯**/
public void closeLamp() {//发送关闭警灯的命令String msg = "FE0500000000D9C5";try {outputStream.write(hexStringToBytes(msg));} catch (IOException e) {e.printStackTrace();}System.out.println("警灯已关闭");
}//-----------------------------------自己写的结束------------------------------------
}

测试类:

 /**** 警灯串口测试类** */public class lampTest1{public static void main(String[] args) {//实例化串口对象lamp lamp=new lamp();//传入串口名进行初始化  忽略大小写String com = lamp.init("com3");if(com!=null &&!"".equals(com)){//打开警灯 传入开启时间,到时间后自动关闭  单位为秒 如果为0则默认一直开启 不会自动关闭lamp.openLamp(5);// lamp.closeLamp();}else {System.out.println("初始化失败,请检查串口名是否错误或该串口是否存在");}lamp.closeSerialPort();}}

注意:发送什么指令需要你根据硬件的产品说明书来!!!!,每个产品是不一样的

到此就完成了连接串口设备,并发送指定操作的程序,如果需要进一步操作,比如对设备返回的数据进行获取操作的话,继续下面代码

其他深入操作:

对串口读:

SerialPortSimpleRead类

/** @(#)SimpleRead.java 1.12 98/06/25 SMI** Copyright (c) 1998 Sun Microsystems, Inc. All Rights Reserved.** Sun grants you ("Licensee") a non-exclusive, royalty free, license* to use, modify and redistribute this software in source and binary* code form, provided that i) this copyright notice and license appear* on all copies of the software; and ii) Licensee does not utilize the* software in a manner which is disparaging to Sun.** This software is provided "AS IS," without a warranty of any kind.* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,* INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A* PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND* ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY* LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE* SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS* BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES,* HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING* OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN* ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.** This software is not designed or intended for use in on-line control* of aircraft, air traffic, aircraft navigation or aircraft* communications; or in the design, construction, operation or* maintenance of any nuclear facility. Licensee represents and* warrants that it will not use or redistribute the Software for such* purposes.*/import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.io.IOException;
import java.io.InputStream;
import java.util.TooManyListenersException;/*** * 该类用来接收串口数据,并在新线程中处理* * 使用时如果需要对接收的进行数据处理,必须重写serialEvent(SerialPortEvent event)方法* @author zhe**/
public class SerialPortSimpleRead implements Runnable, SerialPortEventListener {Logger logger = LoggerFactory.getLogger(this.getClass());InputStream inputStream;SerialPort serialPort;public Thread readThread;private boolean isSingleMessage = true;//回传对象SerialPortManager serialPortManager;private String readStr = "";//串口参数int bautrate;int SerialPort_DATABIT;int SerialPort_STOPBIT;int SerialPort_PARITY;/*** 创建读取串口对象* @param serialPort 端口号的字符串,如:"COM5"* @param serialPortManager* @param isSingleMessage*/public SerialPortSimpleRead(SerialPort serialPort, SerialPortManager serialPortManager, boolean isSingleMessage) {System.out.println("创建接收对象");this.serialPort = serialPort;this.serialPortManager = serialPortManager;this.isSingleMessage = isSingleMessage;try {inputStream = serialPort.getInputStream();} catch (IOException e) {}try {serialPort.addEventListener(this);} catch (TooManyListenersException e) {}serialPort.notifyOnDataAvailable(true);//        try {//            serialPort.setSerialPortParams(115200,//                SerialPort.DATABITS_8,//                SerialPort.STOPBITS_1,//                SerialPort.PARITY_NONE);//        } catch (UnsupportedCommOperationException e) {}//readThread = new Thread(this);//readThread.start();}@Overridepublic void run() {try {Thread.sleep(20000);logger.info("串口接收二十秒超时,退出……");} catch (InterruptedException e) {logger.error("InterruptedException", e);}}@Overridepublic void serialEvent(SerialPortEvent event) {switch(event.getEventType()) {case SerialPortEvent.BI:case SerialPortEvent.OE:case SerialPortEvent.FE:case SerialPortEvent.PE:case SerialPortEvent.CD:case SerialPortEvent.CTS:case SerialPortEvent.DSR:case SerialPortEvent.RI:case SerialPortEvent.OUTPUT_BUFFER_EMPTY:break;case SerialPortEvent.DATA_AVAILABLE:byte[] readBuffer = new byte[128];try {while (inputStream.available() > 0) {int numBytes = inputStream.read(readBuffer);byte[] realBytes = new byte[numBytes];System.arraycopy(readBuffer, 0, realBytes, 0, numBytes);String receivedStr = encode(realBytes);//单条消息通过回调就能处理if (isSingleMessage){serialPortManager.serialReadNotify(receivedStr);readStr = receivedStr;} else {//非单条消息定时处理readStr = readStr + receivedStr;}}} catch (IOException e) {logger.error("inputStream read error.", e);}break;}}public static String hexStringToString(String s) {if (s == null || s.equals("")) {return null;}s = s.replace(" ", "");byte[] baKeyword = new byte[s.length() / 2];for (int i = 0; i < baKeyword.length; i++) {try {baKeyword[i] = (byte) (0xff & Integer.parseInt(s.substring(i * 2, i * 2 + 2), 16));} catch (Exception e) {e.printStackTrace();}}try {s = new String(baKeyword, "UTF-8");new String();} catch (Exception e1) {e1.printStackTrace();}return s;}/*** 16进制数字字符集*/private static String hexString = "0123456789ABCDEF";/** 将字符串编码成16进制数字,适用于所有字符(包括中文)*/public static String encode(byte[] str) {// 根据默认编码获取字节数组byte[] bytes = str;StringBuilder sb = new StringBuilder(bytes.length * 2);// 将字节数组中每个字节拆解成2位16进制整数for (int i = 0; i < bytes.length; i++) {sb.append(hexString.charAt((bytes[i] & 0xf0) >> 4));sb.append(hexString.charAt((bytes[i] & 0x0f) >> 0));}return sb.toString();}/*** 释放掉资源*/public void close(){if(readThread!=null){readThread.interrupt();;readThread = null;}if(serialPort!=null){serialPort.close();serialPort=null;}if(inputStream!=null){try {inputStream.close();inputStream = null;} catch (IOException e) {logger.error("inputStream.close error.", e);}}}public String getReadStr() {return readStr;}public void setReadStr(String readStr) {this.readStr = readStr;}}

对串口写:

SerialPortSimpleWrite类

/** @(#)SimpleWrite.java    1.12 98/06/25 SMI** Copyright (c) 1998 Sun Microsystems, Inc. All Rights Reserved.** Sun grants you ("Licensee") a non-exclusive, royalty free, license* to use, modify and redistribute this software in source and binary* code form, provided that i) this copyright notice and license appear* on all copies of the software; and ii) Licensee does not utilize the* software in a manner which is disparaging to Sun.** This software is provided "AS IS," without a warranty of any kind.* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,* INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A* PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND* ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY* LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE* SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS* BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES,* HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING* OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN* ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.** This software is not designed or intended for use in on-line control* of aircraft, air traffic, aircraft navigation or aircraft* communications; or in the design, construction, operation or* maintenance of any nuclear facility. Licensee represents and* warrants that it will not use or redistribute the Software for such* purposes.*/import gnu.io.SerialPort;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.io.*;public class SerialPortSimpleWrite {Logger logger = LoggerFactory.getLogger(this.getClass());SerialPort serialPort;public OutputStream outputStream;/*** 创建串口写数据对象* @param serialPort 窗口号字符串,如:"COM5"*/public SerialPortSimpleWrite(SerialPort serialPort) {//super();this.serialPort = serialPort;try {this.outputStream = serialPort.getOutputStream();} catch (IOException e) {logger.error("serialPort[{}] create SerialPortSimpleWrite error.", serialPort.getName(), e);}}/*** 串口输出一个字符* @param ch*/public void write(int ch){try {outputStream.write(ch);} catch (IOException e) {logger.error("serail write error.", e);}}/*** 给下位机单片机发送一行字符* @param datastr*/public void writeString(String datastr){try {outputStream.write(datastr.getBytes());} catch (IOException e) {logger.error("serail writeString error.", e);}}/*** 发送字符串给STM32F4* @param datastr* @param loopdelay 下位机串口轮询的周期,单位ms*/public void writeStringToSTM32(String datastr, int loopdelay){try {datastr = datastr.replaceAll(" ", "");//发送logger.info("发送数据 data[{}], 16进制[{}] loopdelay[{}ms]", new String[]{ datastr, new String(hex2byte(datastr)), loopdelay + ""});outputStream.write(hex2byte(datastr));Thread.sleep(loopdelay);} catch (Exception e) {logger.error("writeStringToSTM32 error.", e);}}public static byte[] hex2byte(String hex) {String digital = "0123456789ABCDEF";String hex1 = hex.replace(" ", "");char[] hex2char = hex1.toCharArray();byte[] bytes = new byte[hex1.length() / 2];byte temp;for (int p = 0; p < bytes.length; p++) {temp = (byte) (digital.indexOf(hex2char[2 * p]) * 16);temp += digital.indexOf(hex2char[2 * p + 1]);bytes[p] = (byte) (temp & 0xff);}return bytes;}/*** 发送文件给STM32,读出文本内容分行发给STM32* @param file 要传送文本文件* @param loopdelay*/public void writeFileToSTM32(final File file , final int loopdelay){Thread sendfileThread = new Thread(){public void run() {try {FileReader fr = new FileReader(file);BufferedReader br = new BufferedReader(fr);String line = null;while((line = br.readLine())!=null){System.out.println("发送:"+line);//发送一行writeStringToSTM32(line,loopdelay);}//发送结束标志"$$"SerialPortSimpleWrite.this.writeString("$$sendover");//延时Thread.sleep(loopdelay);br.close();} catch (Exception e) {e.printStackTrace();}}};sendfileThread.start();}/*** 关闭串口资源*/public void close(){if(outputStream != null){try {outputStream.close();outputStream = null;} catch (IOException e) {logger.error("outputStream close error.", e);}}if(serialPort != null){serialPort.close();}}
}

管理串口数据收发的类:

SerialPortManager

import com.alibaba.fastjson.JSON;
import gnu.io.CommPortIdentifier;
import gnu.io.PortInUseException;
import gnu.io.SerialPort;
import gnu.io.UnsupportedCommOperationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.TooManyListenersException;/*** 该类是用来管理串口数据收发的类,通过该类的静态方法可以获取系统可识别的端口* 使用时如果需要对接收的数据进行处理,处理代码添加在getPortSimpleReadInstance()中的serialEvent(SerialPortEvent event)方法***/
public abstract class SerialPortManager {static Logger logger = LoggerFactory.getLogger("serial");//定义串口收发变量private SerialPortSimpleRead portSimpleRead;private SerialPortSimpleWrite portSimpleWrite;@SuppressWarnings("rawtypes")static Enumeration portList;static CommPortIdentifier portId;static SerialPort serialPort;//通讯参数 默认值如下int bautrate = 9600;int serialPort_DATABIT = SerialPort.DATABITS_8;int serialPort_STOPBIT = SerialPort.STOPBITS_1;int serialPort_PARITY = SerialPort.PARITY_NONE;static{//获取系统COM列表portList = CommPortIdentifier.getPortIdentifiers();}/*** 用指定参数构造* @param comPort* @param bautrate* @param serialPort_DATABIT* @param serialPort_STOPBIT* @param serialPort_PARITY*/public SerialPortManager(String comPort, int bautrate, int serialPort_DATABIT,int serialPort_STOPBIT, int serialPort_PARITY, boolean isSingleMessage, boolean isOpenReadThread, boolean isOpenWriteThread) {this.bautrate = bautrate;this.serialPort_DATABIT = serialPort_DATABIT;this.serialPort_STOPBIT = serialPort_STOPBIT;this.serialPort_PARITY = serialPort_PARITY;SerialPortManager.serialPort = openPort(comPort, isSingleMessage, isOpenReadThread, isOpenWriteThread);}/*** 默认参数构造* @param comPort* @throws TooManyListenersException*/public SerialPortManager(String comPort, boolean isSingleMessage, boolean isOpenReadThread, boolean isOpenWriteThread) {super();//设置要管理的端口,打开串口SerialPortManager.serialPort = openPort(comPort, isSingleMessage, isOpenReadThread, isOpenWriteThread);}/*** 以字符串集合的方式返回当前系统可识别的串口(COM)号* @return 端口号的字符集合*/public synchronized static List<String> getAvailablePorts(){//重新获取系统COM列表portList = CommPortIdentifier.getPortIdentifiers();//列表保存成字符串集合List<String> portstrList = new ArrayList<>();//遍历集合while (portList.hasMoreElements()) {portId = (CommPortIdentifier) portList.nextElement();//如果端口是串口if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {logger.info("获取到的串口ID[{}], info[{}]", portId.getName(), JSON.toJSONString(portId));//添加到集合portstrList.add(portId.getName());}}return portstrList;}/*** 打开串口* @param comPort 端口号字符串 ,如:"COM5"* @return 返回打开的串口*/private synchronized SerialPort openPort(String comPort, boolean isSingleMessage, boolean isOpenReadThread, boolean isOpenWriteThread){//重新获取系统COM列表portList = CommPortIdentifier.getPortIdentifiers();if(portList.hasMoreElements()!=true){logger.error("打开端口失败,检测不到串口[{}]", comPort);return null;}SerialPort serialPort = null;//遍历集合while (portList.hasMoreElements()) {portId = (CommPortIdentifier) portList.nextElement();if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {logger.info("获取到的串口[{}]", portId.getName());if (portId.getName().equals(comPort)){try {serialPort = (SerialPort) portId.open("SerialPortManager", 2000);serialPort.setSerialPortParams(this.bautrate,this.serialPort_DATABIT,this.serialPort_STOPBIT,this.serialPort_PARITY);} catch (PortInUseException e) {logger.error("串口[{}]被占用", portId.getName());} catch (UnsupportedCommOperationException e) {logger.error("串口[{}]设置的参数不支持", portId.getName(), e);}  catch (Exception e) {logger.error("串口[{}]打开异常", portId.getName(), e);}}}}if (serialPort == null){logger.error("串口[{}]打开失败!", comPort);return null;}if (isOpenReadThread ){//开启一个接收线程portSimpleRead = new SerialPortSimpleRead(serialPort, this, isSingleMessage);logger.info("串口[{}]----开启接收线程", comPort);}if (isOpenWriteThread && serialPort != null){portSimpleWrite = new SerialPortSimpleWrite(serialPort);logger.info("串口[{}]----开启发送线程", comPort);}return serialPort;}/***  根据新参数再次打开 串口* @param comPort* @param isSingleMessage* @param isOpenReadThread* @param isOpenWriteThread* @return*/public synchronized SerialPort reOpenPort(String comPort, boolean isSingleMessage, boolean isOpenReadThread, boolean isOpenWriteThread){//关闭当前串口close();SerialPortManager.serialPort = openPort(comPort, isSingleMessage, isOpenReadThread, isOpenWriteThread);logger.info("串口重启成功----");return serialPort;}/*** 设置串口参数* @param bautrate* @param serialPort_DATABIT* @param serialPort_STOPBIT* @param serialPort_PARITY*/void setCommPrams(int bautrate,int serialPort_DATABIT,int serialPort_STOPBIT,int serialPort_PARITY){this.bautrate = bautrate;this.serialPort_DATABIT = serialPort_DATABIT;this.serialPort_STOPBIT = serialPort_STOPBIT;this.serialPort_PARITY = serialPort_PARITY;}/*** 关闭串口管理的资源*/public synchronized void close(){try {String portName = null;if (serialPort != null){portName = serialPort.getName();}logger.info("-----串口[{}]关闭-----", portName);if(SerialPortManager.serialPort!=null){SerialPortManager.serialPort.close();serialPort = null;}if (portSimpleRead != null){logger.info("-----串口[{}]关闭读线程-----", portName);portSimpleRead.close();}if (portSimpleWrite != null){logger.info("-----串口[{}]关闭写线程-----", portName);portSimpleWrite.close();}} catch (Exception e) {logger.error("close失败", e);}}/*** 处理串口读到数据后怎么处理* @param readStr*/public abstract void serialReadNotify(String readStr);public SerialPortSimpleRead getPortSimpleRead() {return portSimpleRead;}public void setPortSimpleRead(SerialPortSimpleRead portSimpleRead) {this.portSimpleRead = portSimpleRead;}public SerialPortSimpleWrite getPortSimpleWrite() {return portSimpleWrite;}public void setPortSimpleWrite(SerialPortSimpleWrite portSimpleWrite) {this.portSimpleWrite = portSimpleWrite;}
}

测试

测试类:SerialPortManagerTest

import cn.hutool.core.util.StrUtil;
import com.example.demo2.serial.SerialPortManager;
import com.example.demo2.serial.SerialPortSimpleRead;
import com.example.demo2.serial.SerialPortSimpleWrite;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.util.List;
import java.util.Timer;
import java.util.TimerTask;public class SerialPortManagerTest {static Logger logger = LoggerFactory.getLogger(SerialPortManagerTest.class);public static void main2(String[] agrs){//一般写测试for (int i = 0; i < 10; i++){SerialPortManager cabinetSerailManager = new SerialPortManager("COM3", false, true, true) {//响应串口接收读数据@Overridepublic void serialReadNotify(String readStr) {//应用程序,监听到数据读入System.out.println("应用程序,监听到数据读入:"+readStr);//读数据测试}};String message = "55 AA 01 0A 05 04 90 00 04 00 3F 68 86";write(cabinetSerailManager.getPortSimpleWrite(), cabinetSerailManager.getPortSimpleRead(), message);try {Thread.sleep(500L);} catch (InterruptedException e) {logger.error("", e);}//关闭串口cabinetSerailManager.close();}}public static void main(String[] agrs) throws InterruptedException {//一般写测试SerialPortSimpleRead simpleRead;SerialPortManager cabinetSerailManager = new SerialPortManager("COM4", true, true, false) {//响应串口接收读数据@Overridepublic void serialReadNotify(String message) {String msgStr = SerialPortSimpleRead.hexStringToString(message);//应用程序,监听到数据读入logger.info("监听串口接收数据[{}]", msgStr.trim());//调用后台程序}};while(true){if (!StrUtil.isEmpty(cabinetSerailManager.getPortSimpleRead().getReadStr())){//System.out.println(simpleRead.getReadStr());}Thread.sleep(1000L);}//关闭串口//cabinetSerailManager.close();}/*** 获取系统可以识别的串口* @return 返回端口的字符串集合*/public static List<String> getPortsList(){List<String> list = SerialPortManager.getAvailablePorts();return list;}/*** 发送数据*/public synchronized static void write(final SerialPortSimpleWrite simpleWrite, final SerialPortSimpleRead simpleRead, String message){simpleRead.setReadStr("");simpleWrite.writeStringToSTM32(message, 1000);Timer timer = new Timer();timer.schedule(new TimerTask() {public void run() {String returnValue = simpleRead.getReadStr();System.out.println("返回:" + returnValue);}}, 10);// 设定指定的时间time,此处为10毫秒}}

这些就包含了对串口的常用操作了,完结

Java串口编程控制硬件相关推荐

  1. java rxtx version_RXTX实现JAVA串口编程

    给大家分项下用RXTX库实现JAVA串口编程. 一 准备工作 1.1 下载资源文件 首先下载RXTX库对应的资源文件.下载地址 http://fizzed.com/oss/rxtx-for-java ...

  2. RXTX实现JAVA串口编程

    给大家分项下用RXTX库实现JAVA串口编程. 一 准备工作 1.1 下载资源文件 首先下载RXTX库对应的资源文件.下载地址 http://fizzed.com/oss/rxtx-for-java ...

  3. 软件编程控制硬件的关键——寄存器

    为什么软件能操控硬件? 1. 什么是寄存器?寄存器属于CPU外设的硬件组成部分. 2. CPU可以像访问内存一样访问寄存器(IO与内存统一编址) 3. 寄存器是CPU硬件设计者制定的,目的是留作外设被 ...

  4. java串口编程-读取称重仪表中净重

    一.需求说明 将仪表和计算机串口相连,计算机通过软件向仪表发送指令,然后仪表返回结果,在计算机软件界面上显示. 二.实现过程 1.查看仪表说明书 仪表型号为XK3190-A9,主要是查看相关参数(波特 ...

  5. JAVA 串口编程 (三)

    四.实例分析 同API一起下载的还有一个examples文件,里面有个最简单的读.写程序,对其进行注释,以增进了理. (1)读串口 1  import java.io.*; 2  import jav ...

  6. java串口编程程序_想成为程序员,学编程,Python、Go、Java、C++,你选什么?

    很多时候,我们都不得不做出选择.就拿想成为程序员学编程这件事来说,想学一门编程语言,是选择最新潮的Python.Go,还是选择比较传统的JAVA和C++呢? 要做出选择,就得先进行比较. 其实不同编程 ...

  7. Java串口编程学习1-环境配置(64位Win7)

    最近在做zigbee的课程设计,需要Java实现对串口数据的读写操作. 网上找了很多代码,好像都比较过时了,直接拿来用没法跑通--QAQ--然后自己写个教程留底,如有不当之处还请各位路过的大神赐教. ...

  8. 利用usb远程控制linux,Linux编程控制硬件(5) ---- 操作USB手柄

    Andrew Haung 转载请注明作者及联络方式 学员项目需要用到JoyStick来远程控制云台.以前在用SDL在游戏中很简单的就可以控制.但是现在需要在Linux C下直接调用C来控制JoySti ...

  9. JAVA 串口编程 (一)

    一.环境配置 (1)解压复制文件 解压javacomm20-win32.zip 把win32com.dll复制到<JAVA_HOME>/jre/bin 和<JDK>/bin目录 ...

  10. JAVA 串口编程(二)

    三.实例 (1)打开.关闭串口 首先使用CommPortIdentifier中的方法,获取可用的端口,并且选择一个端口打开作为通信端口. A:枚举可用端口 1  void listPortChoice ...

最新文章

  1. OpenCV的HSV空间度量与标准HSV不一样,使用的时候需要换算;另附一个调色取色的小工具
  2. c#语言中代替指针,如何在C#中使指针通用?
  3. 阿里云CentOS7.3搭建多用户私有git服务器(从安装git开始)
  4. JavaScript实现数据分页
  5. 整个互联网真的是呈现出一种勃勃的生机
  6. 2020网络数据平面峰会-无损网络,真的无损?-杨益锋
  7. 【C++】继承时构造函数和析构函数
  8. 自制导纳信号发生器 [原创cnblogs.com/helesheng]
  9. redis数据类型之Hash
  10. 重装系统后管家婆数据库丢失,数据库碎片扫描、提取、重组数据恢复
  11. hdoj 5510 Bazinga
  12. 135编辑器点击换图html,这5种换图姿势,只有排版高手才会!
  13. 三相变频电源整流有什么特征?
  14. 【前端html页面数据导出为pdf文件】
  15. Boggle问题积累
  16. 与Mr. Zuul男神的亲密接触 | 温哥华峰会Day3
  17. java开发平时看什么东西
  18. 魔兽争霸3在win10中调节亮度的办法
  19. 专题:拓扑排序(Topological sort)模式
  20. allegro 对齐元器件_Allegro怎么对元器件进行对齐

热门文章

  1. 人工智能重新定义管理
  2. Unity Container 应用示例
  3. 如何给视频加背景音乐?简单快速上手,制作抖音等小视频必备!
  4. 沟通成本:信任,外包永远的痛——外包实践(65)
  5. linux centos安装配置prosody
  6. PS常用快捷键操作记录
  7. linux基础-mkdir touch cp
  8. 微软推出 Go 语言免费中文教程,真香!
  9. linux 的 绘画软件,Drawing Linux(简单画图工具)
  10. 程序员在国外:在加拿大IT公司工作三年的一些感受