这几天要用到串口通信,而我最会的Java,所以我就去学了一下怎么用Java进行串口通信
用的jar包是RXTX官网:http://rxtx.qbang.org/
下载地址:http://fizzed.com/oss/rxtx-for-java
下载好Jar包后,首先需要配置,这里我用的Eclipse
Window->Preferences->Java->Build Path->User Library
文章图片
添加一个库,然后添加RXTX的jar包,下载好在lib目录
文章图片
然后将Native Library修改为lib目录
文章图片
配置完成 接下来开始写代码
在项目中添加此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)】大概就是这样了,关注我,获取更多~
推荐阅读
- Java|Java基础——数组
- 人工智能|干货!人体姿态估计与运动预测
- java简介|Java是什么(Java能用来干什么?)
- Java|规范的打印日志
- Linux|109 个实用 shell 脚本
- 程序员|【高级Java架构师系统学习】毕业一年萌新的Java大厂面经,最新整理
- Spring注解驱动第十讲--@Autowired使用
- SqlServer|sql server的UPDLOCK、HOLDLOCK试验
- jvm|【JVM】JVM08(java内存模型解析[JMM])
- 技术|为参加2021年蓝桥杯Java软件开发大学B组细心整理常见基础知识、搜索和常用算法解析例题(持续更新...)