怎么在java中利用Rxtx实现串口通信调
作者
怎么在java中利用Rxtx实现串口通信调?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。
1、把rxtxParallel.dll、rxtxSerial.dll拷贝到:C:\WINDOWS\system32下。
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实现串口通信调问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注恰卡编程网行业资讯频道了解更多相关知识。
目录
推荐阅读
0 条评论
本站已关闭游客评论,请登录或者注册后再评论吧~