怎么在java中利用Rxtx实现串口通信调

怎么在java中利用Rxtx实现串口通信调?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

1、把rxtxParallel.dll、rxtxSerial.dll拷贝到:C:\WINDOWS\system32下。

怎么在java中利用Rxtx实现串口通信调

2、RXTXcomm.jar 添加到项目类库中。

代码:

packageserialPort;

importjava.io.IOException;
importjava.io.InputStream;
importjava.io.OutputStream;
importjava.util.ArrayList;
importjava.util.Enumeration;
importjava.util.List;
importjava.util.TooManyListenersException;

importgnu.io.CommPort;
importgnu.io.CommPortIdentifier;
importgnu.io.NoSuchPortException;
importgnu.io.PortInUseException;
importgnu.io.SerialPort;
importgnu.io.SerialPortEventListener;
importgnu.io.UnsupportedCommOperationException;

/**串口服务类,提供打开、关闭串口,读取、发送串口数据等服务
*/
publicclassSerialTool{

privatestaticSerialToolserialTool=null;

static{
//在该类被ClassLoader加载时就初始化一个SerialTool对象
if(serialTool==null){
serialTool=newSerialTool();
}
}

//私有化SerialTool类的构造方法,不允许其他类生成SerialTool对象
privateSerialTool(){}
/**
*获取提供服务的SerialTool对象
*@returnserialTool
*/
publicstaticSerialToolgetSerialTool(){

if(serialTool==null){
serialTool=newSerialTool();
}
returnserialTool;
}
/**
*查找所有可用端口
*@return可用端口名称列表
*/
publicstaticfinalList<String>findPort(){

//获得当前所有可用串口
@SuppressWarnings("unchecked")
Enumeration<CommPortIdentifier>portList=CommPortIdentifier.getPortIdentifiers();
List<String>portNameList=newArrayList<>();
//将可用串口名添加到List并返回该List
while(portList.hasMoreElements()){
StringportName=portList.nextElement().getName();
portNameList.add(portName);
}
returnportNameList;
}
/**
*打开串口
*@paramportName端口名称
*@parambaudrate波特率
*@return串口对象
*@throwsUnsupportedCommOperationException
*@throwsPortInUseException
*@throwsNoSuchPortException
*/
publicstaticfinalSerialPortopenPort(StringportName,intbaudrate)throwsUnsupportedCommOperationException,PortInUseException,NoSuchPortException{

//通过端口名识别端口
CommPortIdentifierportIdentifier=CommPortIdentifier.getPortIdentifier(portName);
//打开端口,并给端口名字和一个timeout(打开操作的超时时间)
CommPortcommPort=portIdentifier.open(portName,2000);
//判断是不是串口
if(commPortinstanceofSerialPort){
SerialPortserialPort=(SerialPort)commPort;
//设置一下串口的波特率等参数
serialPort.setSerialPortParams(baudrate,SerialPort.DATABITS_8,SerialPort.STOPBITS_1,SerialPort.PARITY_NONE);
returnserialPort;
}
returnnull;
}
/**
*关闭串口
*@paramserialport待关闭的串口对象
*/
publicstaticvoidclosePort(SerialPortserialPort){

if(serialPort!=null){
serialPort.close();
serialPort=null;
}
}
/**
*往串口发送数据
*@paramserialPort串口对象
*@paramorder待发送数据
*@throwsIOException
*/
publicstaticvoidsendToPort(SerialPortserialPort,byte[]order)throwsIOException{

OutputStreamout=null;
out=serialPort.getOutputStream();
out.write(order);
out.flush();
out.close();
}
/**
*从串口读取数据
*@paramserialPort当前已建立连接的SerialPort对象
*@return读取到的数据
*@throwsIOException
*/
publicstaticbyte[]readFromPort(SerialPortserialPort)throwsIOException{

InputStreamin=null;
byte[]bytes=null;
try{
in=serialPort.getInputStream();
intbufflenth=in.available();//获取buffer里的数据长度
while(bufflenth!=0){
bytes=newbyte[bufflenth];//初始化byte数组为buffer中数据的长度
in.read(bytes);
bufflenth=in.available();
}
}catch(IOExceptione){
throwe;
}finally{
if(in!=null){
in.close();
in=null;
}
}
returnbytes;
}
/**添加监听器
*@paramport串口对象
*@paramlistener串口监听器
*@throwsTooManyListenersException
*/
publicstaticvoidaddListener(SerialPortport,SerialPortEventListenerlistener)throwsTooManyListenersException{

//给串口添加监听器
port.addEventListener(listener);
//设置当有数据到达时唤醒监听接收线程
port.notifyOnDataAvailable(true);
//设置当通信中断时唤醒中断线程
port.notifyOnBreakInterrupt(true);
}
}
packageserialPort;

importjava.awt.Color;
importjava.awt.Font;
importjava.awt.Image;
importjava.awt.Toolkit;
importjava.awt.event.ActionEvent;
importjava.awt.event.ActionListener;
importjava.awt.event.MouseAdapter;
importjava.awt.event.MouseEvent;
importjava.io.IOException;
importjava.time.Instant;
importjava.time.LocalDateTime;
importjava.time.ZoneId;
importjava.time.format.DateTimeFormatter;
importjava.util.List;
importjava.util.Timer;
importjava.util.TimerTask;
importjava.util.TooManyListenersException;

importjavax.swing.JButton;
importjavax.swing.JComboBox;
importjavax.swing.JFrame;
importjavax.swing.JLabel;
importjavax.swing.JOptionPane;
importjavax.swing.JScrollPane;
importjavax.swing.JTextArea;
importjavax.swing.border.TitledBorder;

importgnu.io.NoSuchPortException;
importgnu.io.PortInUseException;
importgnu.io.SerialPort;
importgnu.io.SerialPortEvent;
importgnu.io.SerialPortEventListener;
importgnu.io.UnsupportedCommOperationException;

/**
*监测数据显示类
*@authorZhong
*
*/
publicclassSerialViewextendsJFrame{

/**
*/
privatestaticfinallongserialVersionUID=1L;

//设置window的icon
ToolkittoolKit=getToolkit();
Imageicon=toolKit.getImage(SerialView.class.getResource("computer.png"));
DateTimeFormatterdf=DateTimeFormatter.ofPattern("YYYY-MM-ddHH:mm:ss.SSS");

privateJComboBox<String>commChoice;
privateJComboBox<String>bpsChoice;
privateJButtonopenSerialButton;
privateJButtonsendButton;
privateJTextAreasendArea;
privateJTextAreareceiveArea;
privateJButtoncloseSerialButton;

privateList<String>commList=null;//保存可用端口号
privateSerialPortserialPort=null;//保存串口对象

/**类的构造方法
*@paramclient
*/
publicSerialView(){

init();
TimerTasktask=newTimerTask(){
@Override
publicvoidrun(){
commList=SerialTool.findPort();//程序初始化时就扫描一次有效串口
//检查是否有可用串口,有则加入选项中
if(commList==null||commList.size()<1){
JOptionPane.showMessageDialog(null,"没有搜索到有效串口!","错误",JOptionPane.INFORMATION_MESSAGE);
}else{
commChoice.removeAllItems();
for(Strings:commList){
commChoice.addItem(s);
}
}
}
};
Timertimer=newTimer();
timer.scheduleAtFixedRate(task,0,10000);
listen();

}
/**
*/
privatevoidlisten(){

//打开串口连接
openSerialButton.addActionListener(newActionListener(){

publicvoidactionPerformed(ActionEvente){
//获取串口名称
StringcommName=(String)commChoice.getSelectedItem();
//获取波特率
StringbpsStr=(String)bpsChoice.getSelectedItem();
//检查串口名称是否获取正确
if(commName==null||commName.equals("")){
JOptionPane.showMessageDialog(null,"没有搜索到有效串口!","错误",JOptionPane.INFORMATION_MESSAGE);
}else{
//检查波特率是否获取正确
if(bpsStr==null||bpsStr.equals("")){
JOptionPane.showMessageDialog(null,"波特率获取错误!","错误",JOptionPane.INFORMATION_MESSAGE);
}else{
//串口名、波特率均获取正确时
intbps=Integer.parseInt(bpsStr);
try{
//获取指定端口名及波特率的串口对象
serialPort=SerialTool.openPort(commName,bps);
SerialTool.addListener(serialPort,newSerialListener());
if(serialPort==null)return;
//在该串口对象上添加监听器
closeSerialButton.setEnabled(true);
sendButton.setEnabled(true);
openSerialButton.setEnabled(false);
Stringtime=df.format(LocalDateTime.ofInstant(Instant.ofEpochMilli(System.currentTimeMillis()),ZoneId.of("Asia/Shanghai")));
receiveArea.append(time+"["+serialPort.getName().split("/")[3]+"]:"+"连接成功..."+"\r\n");
receiveArea.setCaretPosition(receiveArea.getText().length());
}catch(UnsupportedCommOperationException|PortInUseException|NoSuchPortException|TooManyListenersExceptione1){
e1.printStackTrace();
}
}
}
}
});
//发送数据
sendButton.addMouseListener(newMouseAdapter(){
@Override
publicvoidmouseClicked(MouseEvente){
if(!sendButton.isEnabled())return;
Stringmessage=sendArea.getText();
//"FE0400030001D5C5"
try{
SerialTool.sendToPort(serialPort,hex2byte(message));
}catch(IOExceptione1){
e1.printStackTrace();
}
}
});
//关闭串口连接
closeSerialButton.addMouseListener(newMouseAdapter(){
@Override
publicvoidmouseClicked(MouseEvente){
if(!closeSerialButton.isEnabled())return;
SerialTool.closePort(serialPort);
Stringtime=df.format(LocalDateTime.ofInstant(Instant.ofEpochMilli(System.currentTimeMillis()),ZoneId.of("Asia/Shanghai")));
receiveArea.append(time+"["+serialPort.getName().split("/")[3]+"]:"+"断开连接"+"\r\n");
receiveArea.setCaretPosition(receiveArea.getText().length());
openSerialButton.setEnabled(true);
closeSerialButton.setEnabled(false);
sendButton.setEnabled(false);
}
});
}
/**
*主菜单窗口显示;
*添加JLabel、按钮、下拉条及相关事件监听;
*/
privatevoidinit(){

this.setBounds(WellcomView.LOC_X,WellcomView.LOC_Y,WellcomView.WIDTH,WellcomView.HEIGHT);
this.setTitle("串口调试");
this.setIconImage(icon);
this.setBackground(Color.gray);
this.setLayout(null);

Fontfont=newFont("微软雅黑",Font.BOLD,16);

receiveArea=newJTextArea(18,30);
receiveArea.setEditable(false);
JScrollPanereceiveScroll=newJScrollPane(receiveArea);
receiveScroll.setBorder(newTitledBorder("接收区"));
//滚动条自动出现FE0400030001D5C5
receiveScroll.setHorizontalScrollBarPolicy(
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
receiveScroll.setVerticalScrollBarPolicy(
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
receiveScroll.setBounds(52,20,680,340);
this.add(receiveScroll);

JLabelchuankou=newJLabel("串口选择:");
chuankou.setFont(font);
chuankou.setBounds(50,380,100,50);
this.add(chuankou);

JLabelbotelv=newJLabel("波特率:");
botelv.setFont(font);
botelv.setBounds(290,380,100,50);
this.add(botelv);

//添加串口选择选项
commChoice=newJComboBox<String>();//串口选择(下拉框)
commChoice.setBounds(145,390,100,30);
this.add(commChoice);

//添加波特率选项
bpsChoice=newJComboBox<String>();//波特率选择
bpsChoice.setBounds(380,390,100,30);
bpsChoice.addItem("1500");
bpsChoice.addItem("2400");
bpsChoice.addItem("4800");
bpsChoice.addItem("9600");
bpsChoice.addItem("14400");
bpsChoice.addItem("19500");
bpsChoice.addItem("115500");
this.add(bpsChoice);

//添加打开串口按钮
openSerialButton=newJButton("连接");
openSerialButton.setBounds(540,390,80,30);
openSerialButton.setFont(font);
openSerialButton.setForeground(Color.darkGray);
this.add(openSerialButton);

//添加关闭串口按钮
closeSerialButton=newJButton("关闭");
closeSerialButton.setEnabled(false);
closeSerialButton.setBounds(650,390,80,30);
closeSerialButton.setFont(font);
closeSerialButton.setForeground(Color.darkGray);
this.add(closeSerialButton);

sendArea=newJTextArea(30,20);
JScrollPanesendScroll=newJScrollPane(sendArea);
sendScroll.setBorder(newTitledBorder("发送区"));
//滚动条自动出现
sendScroll.setHorizontalScrollBarPolicy(
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
sendScroll.setVerticalScrollBarPolicy(
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
sendScroll.setBounds(52,450,500,100);
this.add(sendScroll);

sendButton=newJButton("发送");
sendButton.setBounds(610,520,120,30);
sendButton.setFont(font);
sendButton.setForeground(Color.darkGray);
sendButton.setEnabled(false);
this.add(sendButton);

this.setResizable(false);//窗口大小不可更改
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
}

/**字符串转16进制
*@paramhex
*@return
*/
privatebyte[]hex2byte(Stringhex){

Stringdigital="0123456789ABCDEF";
Stringhex1=hex.replace("","");
char[]hex2char=hex1.toCharArray();
byte[]bytes=newbyte[hex1.length()/2];
bytetemp;
for(intp=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);
}
returnbytes;
}
/**字节数组转16进制
*@paramb
*@return
*/
privateStringprintHexString(byte[]b){

StringBuffersbf=newStringBuffer();
for(inti=0;i<b.length;i++){
Stringhex=Integer.toHexString(b[i]&0xFF);
if(hex.length()==1){
hex='0'+hex;
}
sbf.append(hex.toUpperCase()+"");
}
returnsbf.toString().trim();
}
/**
*以内部类形式创建一个串口监听类
*@authorzhong
*/
classSerialListenerimplementsSerialPortEventListener{

/**
*处理监控到的串口事件
*/
publicvoidserialEvent(SerialPortEventserialPortEvent){

switch(serialPortEvent.getEventType()){
caseSerialPortEvent.BI://10通讯中断
JOptionPane.showMessageDialog(null,"与串口设备通讯中断","错误",JOptionPane.INFORMATION_MESSAGE);
break;
caseSerialPortEvent.OE://7溢位(溢出)错误
break;
caseSerialPortEvent.FE://9帧错误
break;
caseSerialPortEvent.PE://8奇偶校验错误
break;
caseSerialPortEvent.CD://6载波检测
break;
caseSerialPortEvent.CTS://3清除待发送数据
break;
caseSerialPortEvent.DSR://4待发送数据准备好了
break;
caseSerialPortEvent.RI://5振铃指示
break;
caseSerialPortEvent.OUTPUT_BUFFER_EMPTY://2输出缓冲区已清空
break;
caseSerialPortEvent.DATA_AVAILABLE://1串口存在可用数据
Stringtime=df.format(LocalDateTime.ofInstant(Instant.ofEpochMilli(System.currentTimeMillis()),ZoneId.of("Asia/Shanghai")));
byte[]data;//FE0400030001D5C5
try{
data=SerialTool.readFromPort(serialPort);
receiveArea.append(time+"["+serialPort.getName().split("/")[3]+"]:"+printHexString(data)+"\r\n");
receiveArea.setCaretPosition(receiveArea.getText().length());
}catch(IOExceptione){
e.printStackTrace();
}
break;
default:
break;
}
}
}
}
packageserialPort;

importjava.awt.Color;
importjava.awt.Font;
importjava.awt.Image;
importjava.awt.Toolkit;
importjava.awt.event.KeyAdapter;
importjava.awt.event.KeyEvent;

importjavax.swing.JFrame;
importjavax.swing.JLabel;


/**
*@authorbh
*如果运行过程中抛出java.lang.UnsatisfiedLinkError错误,
*请将rxtx解压包中的rxtxParallel.dll,rxtxSerial.dll这两个文件复制到C:\Windows\System32目录下即可解决该错误。
*/
publicclassWellcomView{

/**程序界面宽度*/
publicstaticfinalintWIDTH=800;
/**程序界面高度*/
publicstaticfinalintHEIGHT=620;
/**程序界面出现位置(横坐标)*/
publicstaticfinalintLOC_X=200;
/**程序界面出现位置(纵坐标)*/
publicstaticfinalintLOC_Y=70;

privateJFramejFrame;

/**主方法
*@paramargs//
*/
publicstaticvoidmain(String[]args){

newWellcomView();
}
publicWellcomView(){

init();
listen();
}
/**
*/
privatevoidlisten(){

//添加键盘监听器
jFrame.addKeyListener(newKeyAdapter(){
publicvoidkeyReleased(KeyEvente){
intkeyCode=e.getKeyCode();
if(keyCode==KeyEvent.VK_ENTER){//当监听到用户敲击键盘enter键后执行下面的操作
jFrame.setVisible(false);//隐去欢迎界面
newSerialView();//主界面类(显示监控数据主面板)
}
}
});
}
/**
*显示主界面
*/
privatevoidinit(){

jFrame=newJFrame("串口调试");
jFrame.setBounds(LOC_X,LOC_Y,WIDTH,HEIGHT);//设定程序在桌面出现的位置
jFrame.setLayout(null);
//设置window的icon(这里我自定义了一下Windows窗口的icon图标,因为实在觉得哪个小咖啡图标不好看==)
ToolkittoolKit=jFrame.getToolkit();
Imageicon=toolKit.getImage(WellcomView.class.getResource("computer.png"));
jFrame.setIconImage(icon);
jFrame.setBackground(Color.white);//设置背景色

JLabelhuanyin=newJLabel("欢迎使用串口调试工具");
huanyin.setBounds(170,80,600,50);
huanyin.setFont(newFont("微软雅黑",Font.BOLD,40));
jFrame.add(huanyin);

JLabelbanben=newJLabel("Version:1.0PoweredBy:cyq");
banben.setBounds(180,390,500,50);
banben.setFont(newFont("微软雅黑",Font.ITALIC,26));
jFrame.add(banben);

JLabelenter=newJLabel("————点击Enter键进入主界面————");
enter.setBounds(100,480,600,50);
enter.setFont(newFont("微软雅黑",Font.BOLD,30));
jFrame.add(enter);

jFrame.setResizable(false);//窗口大小不可更改
jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jFrame.setVisible(true);//显示窗口
}
}

关于怎么在java中利用Rxtx实现串口通信调问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注恰卡编程网行业资讯频道了解更多相关知识。

发布于 2021-03-26 01:49:36
收藏
分享
海报
0 条评论
158
上一篇:怎么在易语言中使用选择框组件 下一篇:怎么在Python使用pandas实现差分运算
目录

    0 条评论

    本站已关闭游客评论,请登录或者注册后再评论吧~

    忘记密码?

    图形验证码