java使用Rxtx实现串口通信调试工具
程序员文章站
2024-02-26 11:36:46
本文实例为大家分享了java使用rxtx实现串口通信调试工具的具体代码,供大家参考,具体内容如下
最终效果如下图:
1、把rxtxparallel.dll、rxtx...
本文实例为大家分享了java使用rxtx实现串口通信调试工具的具体代码,供大家参考,具体内容如下
最终效果如下图:
1、把rxtxparallel.dll、rxtxserial.dll拷贝到:c:\windows\system32下。
2、rxtxcomm.jar 添加到项目类库中。
代码:
package serialport; import java.io.ioexception; import java.io.inputstream; import java.io.outputstream; import java.util.arraylist; import java.util.enumeration; import java.util.list; import java.util.toomanylistenersexception; import gnu.io.commport; import gnu.io.commportidentifier; import gnu.io.nosuchportexception; import gnu.io.portinuseexception; import gnu.io.serialport; import gnu.io.serialporteventlistener; import gnu.io.unsupportedcommoperationexception; /**串口服务类,提供打开、关闭串口,读取、发送串口数据等服务 */ public class serialtool { private static serialtool serialtool = null; static { //在该类被classloader加载时就初始化一个serialtool对象 if (serialtool == null) { serialtool = new serialtool(); } } //私有化serialtool类的构造方法,不允许其他类生成serialtool对象 private serialtool() {} /** * 获取提供服务的serialtool对象 * @return serialtool */ public static serialtool getserialtool() { if (serialtool == null) { serialtool = new serialtool(); } return serialtool; } /** * 查找所有可用端口 * @return 可用端口名称列表 */ public static final list<string> findport() { //获得当前所有可用串口 @suppresswarnings("unchecked") enumeration<commportidentifier> portlist = commportidentifier.getportidentifiers(); list<string> portnamelist = new arraylist<>(); //将可用串口名添加到list并返回该list while (portlist.hasmoreelements()) { string portname = portlist.nextelement().getname(); portnamelist.add(portname); } return portnamelist; } /** * 打开串口 * @param portname 端口名称 * @param baudrate 波特率 * @return 串口对象 * @throws unsupportedcommoperationexception * @throws portinuseexception * @throws nosuchportexception */ public static final serialport openport(string portname, int baudrate) throws unsupportedcommoperationexception, portinuseexception, nosuchportexception { //通过端口名识别端口 commportidentifier portidentifier = commportidentifier.getportidentifier(portname); //打开端口,并给端口名字和一个timeout(打开操作的超时时间) commport commport = portidentifier.open(portname, 2000); //判断是不是串口 if (commport instanceof serialport) { serialport serialport = (serialport) commport; //设置一下串口的波特率等参数 serialport.setserialportparams(baudrate, serialport.databits_8, serialport.stopbits_1, serialport.parity_none); return serialport; } return null; } /** * 关闭串口 * @param serialport 待关闭的串口对象 */ public static void closeport(serialport serialport) { if (serialport != null) { serialport.close(); serialport = null; } } /** * 往串口发送数据 * @param serialport 串口对象 * @param order 待发送数据 * @throws ioexception */ public static void sendtoport(serialport serialport, byte[] order) throws ioexception { outputstream out = null; out = serialport.getoutputstream(); out.write(order); out.flush(); out.close(); } /** * 从串口读取数据 * @param serialport 当前已建立连接的serialport对象 * @return 读取到的数据 * @throws ioexception */ public static byte[] readfromport(serialport serialport) throws ioexception { inputstream in = null; byte[] bytes = null; try { in = serialport.getinputstream(); int bufflenth = in.available(); //获取buffer里的数据长度 while (bufflenth != 0) { bytes = new byte[bufflenth]; //初始化byte数组为buffer中数据的长度 in.read(bytes); bufflenth = in.available(); } } catch (ioexception e) { throw e; } finally { if (in != null) { in.close(); in = null; } } return bytes; } /**添加监听器 * @param port 串口对象 * @param listener 串口监听器 * @throws toomanylistenersexception */ public static void addlistener(serialport port, serialporteventlistener listener) throws toomanylistenersexception { //给串口添加监听器 port.addeventlistener(listener); //设置当有数据到达时唤醒监听接收线程 port.notifyondataavailable(true); //设置当通信中断时唤醒中断线程 port.notifyonbreakinterrupt(true); } }
package serialport; import java.awt.color; import java.awt.font; import java.awt.image; import java.awt.toolkit; import java.awt.event.actionevent; import java.awt.event.actionlistener; import java.awt.event.mouseadapter; import java.awt.event.mouseevent; import java.io.ioexception; import java.time.instant; import java.time.localdatetime; import java.time.zoneid; import java.time.format.datetimeformatter; import java.util.list; import java.util.timer; import java.util.timertask; import java.util.toomanylistenersexception; import javax.swing.jbutton; import javax.swing.jcombobox; import javax.swing.jframe; import javax.swing.jlabel; import javax.swing.joptionpane; import javax.swing.jscrollpane; import javax.swing.jtextarea; import javax.swing.border.titledborder; import gnu.io.nosuchportexception; import gnu.io.portinuseexception; import gnu.io.serialport; import gnu.io.serialportevent; import gnu.io.serialporteventlistener; import gnu.io.unsupportedcommoperationexception; /** * 监测数据显示类 * @author zhong * */ public class serialview extends jframe { /** */ private static final long serialversionuid = 1l; //设置window的icon toolkit toolkit = gettoolkit(); image icon = toolkit.getimage(serialview.class.getresource("computer.png")); datetimeformatter df= datetimeformatter.ofpattern("yyyy-mm-dd hh:mm:ss.sss"); private jcombobox<string> commchoice; private jcombobox<string> bpschoice; private jbutton openserialbutton; private jbutton sendbutton; private jtextarea sendarea; private jtextarea receivearea; private jbutton closeserialbutton; private list<string> commlist = null; //保存可用端口号 private serialport serialport = null; //保存串口对象 /**类的构造方法 * @param client */ public serialview() { init(); timertask task = new timertask() { @override public void run() { commlist = serialtool.findport(); //程序初始化时就扫描一次有效串口 //检查是否有可用串口,有则加入选项中 if (commlist == null || commlist.size()<1) { joptionpane.showmessagedialog(null, "没有搜索到有效串口!", "错误", joptionpane.information_message); }else{ commchoice.removeallitems(); for (string s : commlist) { commchoice.additem(s); } } } }; timer timer = new timer(); timer.scheduleatfixedrate(task, 0, 10000); listen(); } /** */ private void listen(){ //打开串口连接 openserialbutton.addactionlistener(new actionlistener() { public void actionperformed(actionevent e) { //获取串口名称 string commname = (string) commchoice.getselecteditem(); //获取波特率 string bpsstr = (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 { //串口名、波特率均获取正确时 int bps = integer.parseint(bpsstr); try { //获取指定端口名及波特率的串口对象 serialport = serialtool.openport(commname, bps); serialtool.addlistener(serialport, new seriallistener()); if(serialport==null) return; //在该串口对象上添加监听器 closeserialbutton.setenabled(true); sendbutton.setenabled(true); openserialbutton.setenabled(false); string time=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 | toomanylistenersexception e1) { e1.printstacktrace(); } } } } }); //发送数据 sendbutton.addmouselistener(new mouseadapter() { @override public void mouseclicked(mouseevent e) { if(!sendbutton.isenabled())return; string message= sendarea.gettext(); //"fe0400030001d5c5" try { serialtool.sendtoport(serialport, hex2byte(message)); } catch (ioexception e1) { e1.printstacktrace(); } } }); //关闭串口连接 closeserialbutton.addmouselistener(new mouseadapter() { @override public void mouseclicked(mouseevent e) { if(!closeserialbutton.isenabled())return; serialtool.closeport(serialport); string time=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、按钮、下拉条及相关事件监听; */ private void init() { this.setbounds(wellcomview.loc_x, wellcomview.loc_y, wellcomview.width, wellcomview.height); this.settitle("串口调试"); this.seticonimage(icon); this.setbackground(color.gray); this.setlayout(null); font font =new font("微软雅黑", font.bold, 16); receivearea=new jtextarea(18, 30); receivearea.seteditable(false); jscrollpane receivescroll = new jscrollpane(receivearea); receivescroll.setborder(new titledborder("接收区")); //滚动条自动出现 fe0400030001d5c5 receivescroll.sethorizontalscrollbarpolicy( jscrollpane.horizontal_scrollbar_as_needed); receivescroll.setverticalscrollbarpolicy( jscrollpane.vertical_scrollbar_as_needed); receivescroll.setbounds(52, 20, 680,340); this.add(receivescroll); jlabel chuankou=new jlabel(" 串口选择: "); chuankou.setfont(font); chuankou.setbounds(50, 380, 100,50); this.add(chuankou); jlabel botelv=new jlabel(" 波 特 率: "); botelv.setfont(font); botelv.setbounds(290, 380, 100,50); this.add(botelv); //添加串口选择选项 commchoice = new jcombobox<string>(); //串口选择(下拉框) commchoice.setbounds(145, 390, 100, 30); this.add(commchoice); //添加波特率选项 bpschoice = new jcombobox<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 = new jbutton("连接"); openserialbutton.setbounds(540, 390, 80, 30); openserialbutton.setfont(font); openserialbutton.setforeground(color.darkgray); this.add(openserialbutton); //添加关闭串口按钮 closeserialbutton = new jbutton("关闭"); closeserialbutton.setenabled(false); closeserialbutton.setbounds(650, 390, 80, 30); closeserialbutton.setfont(font); closeserialbutton.setforeground(color.darkgray); this.add(closeserialbutton); sendarea=new jtextarea(30,20); jscrollpane sendscroll = new jscrollpane(sendarea); sendscroll.setborder(new titledborder("发送区")); //滚动条自动出现 sendscroll.sethorizontalscrollbarpolicy( jscrollpane.horizontal_scrollbar_always); sendscroll.setverticalscrollbarpolicy( jscrollpane.vertical_scrollbar_always); sendscroll.setbounds(52, 450, 500,100); this.add(sendscroll); sendbutton = new jbutton("发 送"); 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进制 * @param hex * @return */ private 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; } /**字节数组转16进制 * @param b * @return */ private string printhexstring(byte[] b) { stringbuffer sbf=new stringbuffer(); for (int i = 0; i < b.length; i++) { string hex = integer.tohexstring(b[i] & 0xff); if (hex.length() == 1) { hex = '0' + hex; } sbf.append(hex.touppercase()+" "); } return sbf.tostring().trim(); } /** * 以内部类形式创建一个串口监听类 * @author zhong */ class seriallistener implements serialporteventlistener { /** * 处理监控到的串口事件 */ public void serialevent(serialportevent serialportevent) { switch (serialportevent.geteventtype()) { case serialportevent.bi: // 10 通讯中断 joptionpane.showmessagedialog(null, "与串口设备通讯中断", "错误", joptionpane.information_message); break; case serialportevent.oe: // 7 溢位(溢出)错误 break; case serialportevent.fe: // 9 帧错误 break; case serialportevent.pe: // 8 奇偶校验错误 break; case serialportevent.cd: // 6 载波检测 break; case serialportevent.cts: // 3 清除待发送数据 break; case serialportevent.dsr: // 4 待发送数据准备好了 break; case serialportevent.ri: // 5 振铃指示 break; case serialportevent.output_buffer_empty: // 2 输出缓冲区已清空 break; case serialportevent.data_available: // 1 串口存在可用数据 string time=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 (ioexception e) { e.printstacktrace(); } break; default: break; } } } }
package serialport; import java.awt.color; import java.awt.font; import java.awt.image; import java.awt.toolkit; import java.awt.event.keyadapter; import java.awt.event.keyevent; import javax.swing.jframe; import javax.swing.jlabel; /** * @author bh * 如果运行过程中抛出 java.lang.unsatisfiedlinkerror 错误, * 请将rxtx解压包中的 rxtxparallel.dll,rxtxserial.dll 这两个文件复制到 c:\windows\system32 目录下即可解决该错误。 */ public class wellcomview { /** 程序界面宽度*/ public static final int width = 800; /** 程序界面高度*/ public static final int height = 620; /** 程序界面出现位置(横坐标) */ public static final int loc_x = 200; /** 程序界面出现位置(纵坐标)*/ public static final int loc_y = 70; private jframe jframe; /**主方法 * @param args // */ public static void main(string[] args) { new wellcomview(); } public wellcomview() { init(); listen(); } /** */ private void listen() { //添加键盘监听器 jframe.addkeylistener(new keyadapter() { public void keyreleased(keyevent e) { int keycode = e.getkeycode(); if (keycode == keyevent.vk_enter) { //当监听到用户敲击键盘enter键后执行下面的操作 jframe.setvisible(false); //隐去欢迎界面 new serialview(); //主界面类(显示监控数据主面板) } } }); } /** * 显示主界面 */ private void init() { jframe=new jframe("串口调试"); jframe.setbounds(loc_x, loc_y, width, height); //设定程序在桌面出现的位置 jframe.setlayout(null); //设置window的icon(这里我自定义了一下windows窗口的icon图标,因为实在觉得哪个小咖啡图标不好看 = =) toolkit toolkit = jframe.gettoolkit(); image icon = toolkit.getimage(wellcomview.class.getresource("computer.png")); jframe.seticonimage(icon); jframe.setbackground(color.white); //设置背景色 jlabel huanyin=new jlabel("欢迎使用串口调试工具"); huanyin.setbounds(170, 80,600,50); huanyin.setfont(new font("微软雅黑", font.bold, 40)); jframe.add(huanyin); jlabel banben=new jlabel("version:1.0 powered by:cyq"); banben.setbounds(180, 390,500,50); banben.setfont(new font("微软雅黑", font.italic, 26)); jframe.add(banben); jlabel enter=new jlabel("————点击enter键进入主界面————"); enter.setbounds(100, 480,600,50); enter.setfont(new font("微软雅黑", font.bold, 30)); jframe.add(enter); jframe.setresizable(false); //窗口大小不可更改 jframe.setdefaultcloseoperation(jframe.exit_on_close); jframe.setvisible(true); //显示窗口 } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。