当前位置: 移动技术网 > IT编程>开发语言>Java > 使用Java实现串口通信

使用Java实现串口通信

2019年07月22日  | 移动技术网IT编程  | 我要评论

本文实例为大家分享了java实现串口通信的具体代码,供大家参考,具体内容如下

1.介绍

使用java实现的串口通信程序,支持十六进制数据的发送与接收。
源码:

效果图如下:

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.写在最后

源码下载地址:

欢迎同学们吐槽评论,如果你觉得本篇博客对你有用,那么就留个言或者顶一下吧(^-^)

感谢:基于java编写串口通信工具

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网