Java|Java串口通信(RXTX)

这几天要用到串口通信,而我最会的Java,所以我就去学了一下怎么用Java进行串口通信
用的jar包是RXTX官网:http://rxtx.qbang.org/
下载地址:http://fizzed.com/oss/rxtx-for-java
下载好Jar包后,首先需要配置,这里我用的Eclipse
Window->Preferences->Java->Build Path->User Library
Java|Java串口通信(RXTX)
文章图片

添加一个库,然后添加RXTX的jar包,下载好在lib目录

Java|Java串口通信(RXTX)
文章图片

然后将Native Library修改为lib目录
Java|Java串口通信(RXTX)
文章图片

配置完成 接下来开始写代码
在项目中添加此Library,AddLibrary->userLibrary 选中刚新建的Library
在这 我奉上我记录的API

gnu.io包 CommPortIdentifier类 getPortIdentifiers(); 返回一个Enumeration getPortIdentifiers(String s); 返回一个CommPortIdentifier,通过指定的COM名 getName(); 返回当前通讯端口标识符名 open(String appName,int timeOut); 返回一个CommPort,通过名称和超时,可强转成SerialPort SerialPort抽象类(串行端口) setSerialPortParams(波特率,数据位,停止位,奇偶效验); 设置串口的参数 getInputStream(); 获取输入流 getOutputStream(); 获取输出流 addEventListener(SerialPortEvent); 给打开的串口添加一个监听 notifyOnDataAvailable(boolean); 是否打开监听 SerialPortEvent类(串行端口事件) BIBreak Interrupt 通讯中断 OEOverrun Error 溢位错误 FEFraming Error 传帧错误 PEParity Error 效验错误 CDCarrier Detect 载波检测 CTSClear To Send 清除发送 DSRData Set Ready 数据设备就绪 RIRing Indicator 响铃指示 OUTPUT_BUFFER_EMPTY 输出缓冲区清空 DATA_AVAILABLE端口有可用数据serialEvent(ServialPortEvent); 监听,调用此方法

一个简单的串口通信 --
import java.io.BufferedInputStream; import java.io.IOException; import java.io.OutputStream; import java.util.TooManyListenersException; import com.utils.Protocal; import com.utils.Serial; import gnu.io.CommPortIdentifier; import gnu.io.NoSuchPortException; import gnu.io.PortInUseException; import gnu.io.SerialPort; import gnu.io.SerialPortEvent; import gnu.io.SerialPortEventListener; import gnu.io.UnsupportedCommOperationException; public class MyTest implements SerialPortEventListener { //串口 private static SerialPort serialPort = null; private static CommPortIdentifier comm = null; private static BufferedInputStream bufferInput; public MyTest() { try { //获取通信端口标识符 comm = Serial.getCommPortIdentifierByName("COM1"); //打开串口 serialPort = (SerialPort) comm.open("Read",2000); //设置串口的参数 波特率 数据位 停止位 奇偶效验 serialPort.setSerialPortParams(Serial.getBaudRate(),Serial.getDataBits(),Serial.getStopBits(),Serial.getParity()); //如果串口不为空的话 则监听获取信息 否则报错 OutputStream output = null; if (serialPort != null) { try { //获取输入输出流 bufferInput = new BufferedInputStream(serialPort.getInputStream()); output = serialPort.getOutputStream(); //添加监听 serialPort.addEventListener(this); serialPort.notifyOnDataAvailable(true); //发送数据 char[] hex = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; Serial.sendData(output,Protocal.getDataHead(),"52 52 52 01",crc,Protocal.getDataTail()); System.out.println(crc); } } } } } catch (TooManyListenersException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } else { throw new RuntimeException("串口获取失败-serialPort为null"); } } catch (NoSuchPortException e) { e.printStackTrace(); } catch (PortInUseException e) { e.printStackTrace(); } catch (UnsupportedCommOperationException e) { e.printStackTrace(); } } public static void main(String[] args) { new MyTest(); } /** * -串口的监听 */ @Override public void serialEvent(SerialPortEvent ev) { //判断数据类型 switch (ev.getEventType()) { //通讯中断 Break Interrupt case SerialPortEvent.BI: System.out.println("BI"); break; //溢位错误 Overrun Error case SerialPortEvent.OE: System.out.println("OE"); break; //传帧错误 Framing Error case SerialPortEvent.FE: System.out.println("FE"); break; //效验错误 Parity Error case SerialPortEvent.PE: System.out.println("PE"); break; //载波检测 Carrier Detect case SerialPortEvent.CD: System.out.println("CD"); break; //清除发送 Clear To Send case SerialPortEvent.CTS: System.out.println("CTS"); break; //数据设备就绪 Data Set Ready case SerialPortEvent.DSR: System.out.println("DSR"); break; //响铃指示 Ring Indicator case SerialPortEvent.RI: System.out.println("RI"); break; //输出缓冲区清空 Output Buffer Empty case SerialPortEvent.OUTPUT_BUFFER_EMPTY: System.out.println("output"); break; //端口有可用数据 Data Available case SerialPortEvent.DATA_AVAILABLE: //读取数据 try { byte[] bytes = null; byte[] tempBytes = new byte[1024]; int len = -1; while ((len = bufferInput.read(tempBytes)) != -1) { //将数据写入bytes中 并更改bytes的长度 if (bytes != null) { byte[] b = bytes; bytes = new byte[bytes.length + len]; for (int i = 0; i < bytes.length; i++) { if (i < len) { bytes[i] = b[i]; } else { bytes[i] = tempBytes[i]; } } } else { bytes = new byte[len]; for (int i = 0; i < bytes.length; i++) { bytes[i] = tempBytes[i]; } } } //输出数据 System.out.println("字符串形式:"+ new String(bytes)); System.out.println("16进制形式:"+ Protocal.switchByteToHexadecimal(bytes)); } catch (IOException e) { e.printStackTrace(); } break; } } }

奉上我的两个工具类
import java.io.BufferedOutputStream; import java.io.IOException; import java.io.OutputStream; import gnu.io.CommPortIdentifier; import gnu.io.NoSuchPortException; import gnu.io.SerialPort; /** * -串口通讯工具类 * @author Shendi * */ public class Serial { private static int baudRate = 19200; //波特率 默认为19200 private static int dataBits = SerialPort.DATABITS_8; //数据位 默认为8 private static int stopBits = SerialPort.STOPBITS_1; //停止位 默认为1 private static int parity = SerialPort.PARITY_NONE; //奇偶效验 默认为无 public static int getBaudRate() { return baudRate; } public static void setBaudRate(int baudRate) { Serial.baudRate = baudRate; } public static int getDataBits() { return dataBits; } public static void setDataBits(int dataBits) { Serial.dataBits = dataBits; } public static int getStopBits() { return stopBits; } public static void setStopBits(int stopBits) { Serial.stopBits = stopBits; } public static int getParity() { return parity; } public static void setParity(int parity) { Serial.parity = parity; } /** * -获取通信端口标识符通过端口名 * @param commName 端口名 * @return 实例通讯端口标识符 * @throws NoSuchPortException */ public static CommPortIdentifier getCommPortIdentifierByName(String commName) throws NoSuchPortException { //如果名称为空 则返回null if ("".equals(commName)) { return null; } CommPortIdentifier comm = CommPortIdentifier.getPortIdentifier(commName); return comm; } /** * -发送数据 * @param serialPortOutput 输出流 * @param dataHead 数据头 * @param data 数据 * @param CRC 校验位 * @param dataTail 数据尾 */ public static void sendData(OutputStream serialPortOutput,String dataHead,String data,String CRC,String dataTail) { //组合字符串 数据头+数据+校验位+数据尾 StringBuffer str = new StringBuffer(); if (dataHead != null) { str.append(dataHead); } if (data != null) { str.append(data); } if (CRC != null) { str.append(CRC); } if (dataTail != null) { str.append(dataTail); } System.out.println(str.toString()); //将字符串变成16进制存进byte中 byte[] bytes = Protocal.switchStringToHexadecimal(str.toString()); //发送数据 try { serialPortOutput.write(bytes); } catch (IOException e) { e.printStackTrace(); } } } ----------------------------------------------------- import javax.xml.bind.annotation.adapters.HexBinaryAdapter; /** * -协议工具类 * @author Shendi * */ public class Protocal { //数据头 数据尾 private static String dataHead = "7B 01 00 16 31 33 39 31 34 30 30 30 31 37 39 42 42 42 42 42 42 42 42 42 53"; private static String dataTail = "45"; private static String CRC = "40 55 "; //CRC效验码 默认为 40 55 /** * -将字符串转换为byte数组 16进制 * @param str 要转换的字符串 * @return 如果为null 则转换失败 否则返回byte数组 */ public static byte[] switchStringToHexadecimal(String str) { //将空格清除 str = str.replaceAll(" ",""); //将字符串按照2个一组拆分 存入byte中 byte[] bytes = new byte[str.length()/2]; for (int i = 0; i < bytes.length; i++) { bytes[i] = (byte) Integer.parseInt(str.substring(i+i, i+i+2),16); System.out.print(bytes[i]+" "); } System.out.println("\n"); return bytes; } public static String switchByteToHexadecimal(byte[] bytes) { StringBuffer data = https://www.it610.com/article/new StringBuffer(); char[] hex = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; for (int i = 0; i < bytes.length; i++) { int num = bytes[i]; String str = ""; if (num == 0) { str = "00"; } else { while (num != 0) { str = hex[num % 16]+str; num /= 16; } } //如果字符串长度不等于2的话 则添加一位0 if (str.length() < 2) { str = "0"+str; } //获取16进制 data.append(str+" "); } return data.toString(); } public static String getDataHead() { return dataHead; } public static String getDataTail() { return dataTail; } public static String getCRC() { return CRC; } }

【Java|Java串口通信(RXTX)】大概就是这样了,关注我,获取更多~

    推荐阅读