使用Java实现串口通信
程序员文章站
2024-03-11 14:12:19
本文实例为大家分享了java实现串口通信的具体代码,供大家参考,具体内容如下
1.介绍
使用java实现的串口通信程序,支持十六进制数据的发送与接收。
源码:ser...
本文实例为大家分享了java实现串口通信的具体代码,供大家参考,具体内容如下
1.介绍
使用java实现的串口通信程序,支持十六进制数据的发送与接收。
源码:serialportdemo
效果图如下:
2.rxtxcomm
java串口通信依赖的jar包rxtxcomm.jar
下载地址:
内含32位与64位版本
使用方法:
拷贝 rxtxcomm.jar 到 java_home\jre\lib\ext目录中;
拷贝 rxtxserial.dll 到 java_home\jre\bin目录中;
拷贝 rxtxparallel.dll 到 java_home\jre\bin目录中;
java_home为jdk安装路径
3.串口通信管理
serialportmanager实现了对串口通信的管理,包括查找可用端口、打开关闭串口、发送接收数据。
package com.yang.serialport.manage; 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; import java.io.ioexception; import java.io.inputstream; import java.io.outputstream; import java.util.arraylist; import java.util.enumeration; import java.util.toomanylistenersexception; import com.yang.serialport.exception.nosuchport; import com.yang.serialport.exception.notaserialport; import com.yang.serialport.exception.portinuse; import com.yang.serialport.exception.readdatafromserialportfailure; import com.yang.serialport.exception.senddatatoserialportfailure; import com.yang.serialport.exception.serialportinputstreamclosefailure; import com.yang.serialport.exception.serialportoutputstreamclosefailure; import com.yang.serialport.exception.serialportparameterfailure; import com.yang.serialport.exception.toomanylisteners; /** * 串口管理 * * @author yangle */ public class serialportmanager { /** * 查找所有可用端口 * * @return 可用端口名称列表 */ @suppresswarnings("unchecked") public static final arraylist<string> findport() { // 获得当前所有可用串口 enumeration<commportidentifier> portlist = commportidentifier .getportidentifiers(); arraylist<string> portnamelist = new arraylist<string>(); // 将可用串口名添加到list并返回该list while (portlist.hasmoreelements()) { string portname = portlist.nextelement().getname(); portnamelist.add(portname); } return portnamelist; } /** * 打开串口 * * @param portname * 端口名称 * @param baudrate * 波特率 * @return 串口对象 * @throws serialportparameterfailure * 设置串口参数失败 * @throws notaserialport * 端口指向设备不是串口类型 * @throws nosuchport * 没有该端口对应的串口设备 * @throws portinuse * 端口已被占用 */ public static final serialport openport(string portname, int baudrate) throws serialportparameterfailure, notaserialport, nosuchport, portinuse { try { // 通过端口名识别端口 commportidentifier portidentifier = commportidentifier .getportidentifier(portname); // 打开端口,设置端口名与timeout(打开操作的超时时间) commport commport = portidentifier.open(portname, 2000); // 判断是不是串口 if (commport instanceof serialport) { serialport serialport = (serialport) commport; try { // 设置串口的波特率等参数 serialport.setserialportparams(baudrate, serialport.databits_8, serialport.stopbits_1, serialport.parity_none); } catch (unsupportedcommoperationexception e) { throw new serialportparameterfailure(); } return serialport; } else { // 不是串口 throw new notaserialport(); } } catch (nosuchportexception e1) { throw new nosuchport(); } catch (portinuseexception e2) { throw new portinuse(); } } /** * 关闭串口 * * @param serialport * 待关闭的串口对象 */ public static void closeport(serialport serialport) { if (serialport != null) { serialport.close(); serialport = null; } } /** * 向串口发送数据 * * @param serialport * 串口对象 * @param order * 待发送数据 * @throws senddatatoserialportfailure * 向串口发送数据失败 * @throws serialportoutputstreamclosefailure * 关闭串口对象的输出流出错 */ public static void sendtoport(serialport serialport, byte[] order) throws senddatatoserialportfailure, serialportoutputstreamclosefailure { outputstream out = null; try { out = serialport.getoutputstream(); out.write(order); out.flush(); } catch (ioexception e) { throw new senddatatoserialportfailure(); } finally { try { if (out != null) { out.close(); out = null; } } catch (ioexception e) { throw new serialportoutputstreamclosefailure(); } } } /** * 从串口读取数据 * * @param serialport * 当前已建立连接的serialport对象 * @return 读取到的数据 * @throws readdatafromserialportfailure * 从串口读取数据时出错 * @throws serialportinputstreamclosefailure * 关闭串口对象输入流出错 */ public static byte[] readfromport(serialport serialport) throws readdatafromserialportfailure, serialportinputstreamclosefailure { inputstream in = null; byte[] bytes = null; try { in = serialport.getinputstream(); // 获取buffer里的数据长度 int bufflenth = in.available(); while (bufflenth != 0) { // 初始化byte数组为buffer中数据的长度 bytes = new byte[bufflenth]; in.read(bytes); bufflenth = in.available(); } } catch (ioexception e) { throw new readdatafromserialportfailure(); } finally { try { if (in != null) { in.close(); in = null; } } catch (ioexception e) { throw new serialportinputstreamclosefailure(); } } return bytes; } /** * 添加监听器 * * @param port * 串口对象 * @param listener * 串口监听器 * @throws toomanylisteners * 监听类对象过多 */ public static void addlistener(serialport port, serialporteventlistener listener) throws toomanylisteners { try { // 给串口添加监听器 port.addeventlistener(listener); // 设置当有数据到达时唤醒监听接收线程 port.notifyondataavailable(true); // 设置当通信中断时唤醒中断线程 port.notifyonbreakinterrupt(true); } catch (toomanylistenersexception e) { throw new toomanylisteners(); } } }
4.程序主窗口
/* * mainframe.java * * created on 2016.8.19 */ package com.yang.serialport.ui; import gnu.io.serialport; import gnu.io.serialportevent; import gnu.io.serialporteventlistener; import java.awt.color; import java.awt.graphicsenvironment; import java.awt.point; import java.awt.event.actionevent; import java.awt.event.actionlistener; import java.util.list; import javax.swing.borderfactory; import javax.swing.jbutton; import javax.swing.jcombobox; import javax.swing.jframe; import javax.swing.jlabel; import javax.swing.jpanel; import javax.swing.jscrollpane; import javax.swing.jtextarea; import javax.swing.jtextfield; import com.yang.serialport.exception.nosuchport; import com.yang.serialport.exception.notaserialport; import com.yang.serialport.exception.portinuse; import com.yang.serialport.exception.senddatatoserialportfailure; import com.yang.serialport.exception.serialportoutputstreamclosefailure; import com.yang.serialport.exception.serialportparameterfailure; import com.yang.serialport.exception.toomanylisteners; import com.yang.serialport.manage.serialportmanager; import com.yang.serialport.utils.byteutils; import com.yang.serialport.utils.showutils; /** * 主界面 * * @author yangle */ public class mainframe extends jframe { /** * 程序界面宽度 */ public static final int width = 500; /** * 程序界面高度 */ public static final int height = 360; private jtextarea dataview = new jtextarea(); private jscrollpane scrolldataview = new jscrollpane(dataview); // 串口设置面板 private jpanel serialportpanel = new jpanel(); private jlabel serialportlabel = new jlabel("串口"); private jlabel baudratelabel = new jlabel("波特率"); private jcombobox commchoice = new jcombobox(); private jcombobox baudratechoice = new jcombobox(); // 操作面板 private jpanel operatepanel = new jpanel(); private jtextfield datainput = new jtextfield(); private jbutton serialportoperate = new jbutton("打开串口"); private jbutton senddata = new jbutton("发送数据"); private list<string> commlist = null; private serialport serialport; public mainframe() { initview(); initcomponents(); actionlistener(); initdata(); } private void initview() { // 关闭程序 setdefaultcloseoperation(javax.swing.windowconstants.exit_on_close); // 禁止窗口最大化 setresizable(false); // 设置程序窗口居中显示 point p = graphicsenvironment.getlocalgraphicsenvironment() .getcenterpoint(); setbounds(p.x - width / 2, p.y - height / 2, width, height); this.setlayout(null); settitle("串口通讯"); } private void initcomponents() { // 数据显示 dataview.setfocusable(false); scrolldataview.setbounds(10, 10, 475, 200); add(scrolldataview); // 串口设置 serialportpanel.setborder(borderfactory.createtitledborder("串口设置")); serialportpanel.setbounds(10, 220, 170, 100); serialportpanel.setlayout(null); add(serialportpanel); serialportlabel.setforeground(color.gray); serialportlabel.setbounds(10, 25, 40, 20); serialportpanel.add(serialportlabel); commchoice.setfocusable(false); commchoice.setbounds(60, 25, 100, 20); serialportpanel.add(commchoice); baudratelabel.setforeground(color.gray); baudratelabel.setbounds(10, 60, 40, 20); serialportpanel.add(baudratelabel); baudratechoice.setfocusable(false); baudratechoice.setbounds(60, 60, 100, 20); serialportpanel.add(baudratechoice); // 操作 operatepanel.setborder(borderfactory.createtitledborder("操作")); operatepanel.setbounds(200, 220, 285, 100); operatepanel.setlayout(null); add(operatepanel); datainput.setbounds(25, 25, 235, 20); operatepanel.add(datainput); serialportoperate.setfocusable(false); serialportoperate.setbounds(45, 60, 90, 20); operatepanel.add(serialportoperate); senddata.setfocusable(false); senddata.setbounds(155, 60, 90, 20); operatepanel.add(senddata); } @suppresswarnings("unchecked") private void initdata() { commlist = serialportmanager.findport(); // 检查是否有可用串口,有则加入选项中 if (commlist == null || commlist.size() < 1) { showutils.warningmessage("没有搜索到有效串口!"); } else { for (string s : commlist) { commchoice.additem(s); } } baudratechoice.additem("9600"); baudratechoice.additem("19200"); baudratechoice.additem("38400"); baudratechoice.additem("57600"); baudratechoice.additem("115200"); } private void actionlistener() { serialportoperate.addactionlistener(new actionlistener() { @override public void actionperformed(actionevent e) { if ("打开串口".equals(serialportoperate.gettext()) && serialport == null) { openserialport(e); } else { closeserialport(e); } } }); senddata.addactionlistener(new actionlistener() { @override public void actionperformed(actionevent e) { senddata(e); } }); } /** * 打开串口 * * @param evt * 点击事件 */ private void openserialport(java.awt.event.actionevent evt) { // 获取串口名称 string commname = (string) commchoice.getselecteditem(); // 获取波特率 int baudrate = 9600; string bps = (string) baudratechoice.getselecteditem(); baudrate = integer.parseint(bps); // 检查串口名称是否获取正确 if (commname == null || commname.equals("")) { showutils.warningmessage("没有搜索到有效串口!"); } else { try { serialport = serialportmanager.openport(commname, baudrate); if (serialport != null) { dataview.settext("串口已打开" + "\r\n"); serialportoperate.settext("关闭串口"); } } catch (serialportparameterfailure e) { e.printstacktrace(); } catch (notaserialport e) { e.printstacktrace(); } catch (nosuchport e) { e.printstacktrace(); } catch (portinuse e) { e.printstacktrace(); showutils.warningmessage("串口已被占用!"); } } try { serialportmanager.addlistener(serialport, new seriallistener()); } catch (toomanylisteners e) { e.printstacktrace(); } } /** * 关闭串口 * * @param evt * 点击事件 */ private void closeserialport(java.awt.event.actionevent evt) { serialportmanager.closeport(serialport); dataview.settext("串口已关闭" + "\r\n"); serialportoperate.settext("打开串口"); } /** * 发送数据 * * @param evt * 点击事件 */ private void senddata(java.awt.event.actionevent evt) { // 输入框直接输入十六进制字符,长度必须是偶数 string data = datainput.gettext().tostring(); try { serialportmanager.sendtoport(serialport, byteutils.hexstr2byte(data)); } catch (senddatatoserialportfailure e) { e.printstacktrace(); } catch (serialportoutputstreamclosefailure e) { e.printstacktrace(); } } private class seriallistener implements serialporteventlistener { /** * 处理监控到的串口事件 */ public void serialevent(serialportevent serialportevent) { switch (serialportevent.geteventtype()) { case serialportevent.bi: // 10 通讯中断 showutils.errormessage("与串口设备通讯中断"); break; case serialportevent.oe: // 7 溢位(溢出)错误 case serialportevent.fe: // 9 帧错误 case serialportevent.pe: // 8 奇偶校验错误 case serialportevent.cd: // 6 载波检测 case serialportevent.cts: // 3 清除待发送数据 case serialportevent.dsr: // 4 待发送数据准备好了 case serialportevent.ri: // 5 振铃指示 case serialportevent.output_buffer_empty: // 2 输出缓冲区已清空 break; case serialportevent.data_available: // 1 串口存在可用数据 byte[] data = null; try { if (serialport == null) { showutils.errormessage("串口对象为空!监听失败!"); } else { // 读取串口数据 data = serialportmanager.readfromport(serialport); dataview.append(byteutils.bytearraytohexstring(data, true) + "\r\n"); } } catch (exception e) { showutils.errormessage(e.tostring()); // 发生读取错误时显示错误信息后退出系统 system.exit(0); } break; } } } public static void main(string args[]) { java.awt.eventqueue.invokelater(new runnable() { public void run() { new mainframe().setvisible(true); } }); } }
5.写在最后
源码下载地址:serialportdemo
欢迎同学们吐槽评论,如果你觉得本篇博客对你有用,那么就留个言或者顶一下吧(^-^)
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。