1.准备工作

       在进行串口连接通讯前,必须保证你当前操作电脑上有可用且闲置的串口。因为一般的电脑上只有一个或者两个串口,如COM1或COM2,但大多数情况下,这些串口可能会被其他的程序或者应用所占用,所以此时我们可以借助工具,在我们的电脑上建立虚拟串口。
       先下载一个叫Virtual Serial Port的软件,通过这个软件可以创建新的虚拟串口,如下图所示:
通过图中的添加串口即可进行新虚拟串口的创建,并且一般都是成对创建。
 
有了虚拟串口之后,为了方便测试新建串口是否可用,我们可以再下载一款串口测试软件,我用的是一个串口调试助手,如下图:
通过测试,发现我所添加的虚拟串口COM3和COM4是可以用的,那么接下来,我们就可以关闭其中一个,通过我们的JAVA程序来进行与该虚拟串口的信息交互了。
 

2.JAVA程序的操作

在进行程序编写之前,我们需要下载几个文件,才能使我们的程序进行串口通讯的操作。
     首先需要下载如下图中的三个文件:
并将RXTXcomm.jar这个包通过集成工具的构建路径添加到我们的项目之中;其次将 rxtxParallel.dll 和 rxtxSerial.dll 这两个文件放到我们的JDK安装目录中的bin文件夹中。
     这两个文件必须添加到指定位置,否则后面程序在运行时将会报错找不到文件。(需要注意:这几个文件按操作系统分32位和64位,各位需要根据自己电脑的系统下载对应的版本,不然也会报错).
 
接下来可以开始我们的代码编写了,为了方便使用,我们肯定是需要有一个SerialPort串口工具类,如下:
  1.  
    package com.cams.CaMSMobileService.SerialPort;
  2.  
     
  3.  
    import gnu.io.CommPort;
  4.  
    import gnu.io.CommPortIdentifier;
  5.  
    import gnu.io.NoSuchPortException;
  6.  
    import gnu.io.PortInUseException;
  7.  
    import gnu.io.SerialPort;
  8.  
    import gnu.io.SerialPortEventListener;
  9.  
    import gnu.io.UnsupportedCommOperationException;
  10.  
     
  11.  
    import java.io.IOException;
  12.  
    import java.io.InputStream;
  13.  
    import java.io.OutputStream;
  14.  
    import java.util.ArrayList;
  15.  
    import java.util.Enumeration;
  16.  
    import java.util.TooManyListenersException;
  17.  
     
  18.  
    import com.cams.CaMSMobileService.SerialPort.exception.NoSuchPort;
  19.  
    import com.cams.CaMSMobileService.SerialPort.exception.NotASerialPort;
  20.  
    import com.cams.CaMSMobileService.SerialPort.exception.PortInUse;
  21.  
    import com.cams.CaMSMobileService.SerialPort.exception.ReadDataFromSerialPortFailure;
  22.  
    import com.cams.CaMSMobileService.SerialPort.exception.SendDataToSerialPortFailure;
  23.  
    import com.cams.CaMSMobileService.SerialPort.exception.SerialPortInputStreamCloseFailure;
  24.  
    import com.cams.CaMSMobileService.SerialPort.exception.SerialPortOutputStreamCloseFailure;
  25.  
    import com.cams.CaMSMobileService.SerialPort.exception.SerialPortParameterFailure;
  26.  
    import com.cams.CaMSMobileService.SerialPort.exception.TooManyListeners;
  27.  
     
  28.  
    public class SerialPortManager {
  29.  
     
  30.  
    /**
  31.  
    * 查找所有可用端口
  32.  
    *
  33.  
    * @return 可用端口名称列表
  34.  
    */
  35.  
    @SuppressWarnings("unchecked")
  36.  
    public static final ArrayList<String> findPort() {
  37.  
    // 获得当前所有可用串口
  38.  
    Enumeration<CommPortIdentifier> portList = CommPortIdentifier
  39.  
    .getPortIdentifiers();
  40.  
    ArrayList<String> portNameList = new ArrayList<String>();
  41.  
    // 将可用串口名添加到List并返回该List
  42.  
    while (portList.hasMoreElements()) {
  43.  
    String portName = portList.nextElement().getName();
  44.  
    portNameList.add(portName);
  45.  
    }
  46.  
    return portNameList;
  47.  
    }
  48.  
     
  49.  
    /**
  50.  
    * 打开串口
  51.  
    *
  52.  
    * @param portName
  53.  
    * 端口名称
  54.  
    * @param baudrate
  55.  
    * 波特率
  56.  
    * @return 串口对象
  57.  
    * @throws SerialPortParameterFailure
  58.  
    * 设置串口参数失败
  59.  
    * @throws NotASerialPort
  60.  
    * 端口指向设备不是串口类型
  61.  
    * @throws NoSuchPort
  62.  
    * 没有该端口对应的串口设备
  63.  
    * @throws PortInUse
  64.  
    * 端口已被占用
  65.  
    */
  66.  
    public static final SerialPort openPort(String portName, int baudrate)
  67.  
    throws SerialPortParameterFailure, NotASerialPort, NoSuchPort,
  68.  
    PortInUse {
  69.  
    try {
  70.  
    // 通过端口名识别端口
  71.  
    CommPortIdentifier portIdentifier = CommPortIdentifier
  72.  
    .getPortIdentifier(portName);
  73.  
    // 打开端口,设置端口名与timeout(打开操作的超时时间)
  74.  
    CommPort commPort = portIdentifier.open(portName, 2000);
  75.  
    // 判断是不是串口
  76.  
    if (commPort instanceof SerialPort) {
  77.  
    SerialPort serialPort = (SerialPort) commPort;
  78.  
     
  79.  
    try {
  80.  
    // 设置串口的波特率等参数
  81.  
    serialPort.setSerialPortParams(baudrate,
  82.  
    SerialPort.DATABITS_8, SerialPort.STOPBITS_1,
  83.  
    SerialPort.PARITY_NONE);
  84.  
    } catch (UnsupportedCommOperationException e) {
  85.  
    throw new SerialPortParameterFailure();
  86.  
    }
  87.  
    return serialPort;
  88.  
    } else {
  89.  
    // 不是串口
  90.  
    throw new NotASerialPort();
  91.  
    }
  92.  
    } catch (NoSuchPortException e1) {
  93.  
    throw new NoSuchPort();
  94.  
    } catch (PortInUseException e2) {
  95.  
    throw new PortInUse();
  96.  
    }
  97.  
    }
  98.  
     
  99.  
    /**
  100.  
    * 关闭串口
  101.  
    *
  102.  
    * @param serialport
  103.  
    * 待关闭的串口对象
  104.  
    */
  105.  
    public static void closePort(SerialPort serialPort) {
  106.  
    if (serialPort != null) {
  107.  
    serialPort.close();
  108.  
    serialPort = null;
  109.  
    }
  110.  
    }
  111.  
     
  112.  
    /**
  113.  
    * 向串口发送数据
  114.  
    *
  115.  
    * @param serialPort
  116.  
    * 串口对象
  117.  
    * @param order
  118.  
    * 待发送数据
  119.  
    * @throws SendDataToSerialPortFailure
  120.  
    * 向串口发送数据失败
  121.  
    * @throws SerialPortOutputStreamCloseFailure
  122.  
    * 关闭串口对象的输出流出错
  123.  
    */
  124.  
    public static void sendToPort(SerialPort serialPort, byte[] order)
  125.  
    throws SendDataToSerialPortFailure,
  126.  
    SerialPortOutputStreamCloseFailure {
  127.  
    OutputStream out = null;
  128.  
    try {
  129.  
    out = serialPort.getOutputStream();
  130.  
    out.write(order);
  131.  
    out.flush();
  132.  
    } catch (IOException e) {
  133.  
    throw new SendDataToSerialPortFailure();
  134.  
    } finally {
  135.  
    try {
  136.  
    if (out != null) {
  137.  
    out.close();
  138.  
    out = null;
  139.  
    }
  140.  
    } catch (IOException e) {
  141.  
    throw new SerialPortOutputStreamCloseFailure();
  142.  
    }
  143.  
    }
  144.  
    }
  145.  
     
  146.  
    /**
  147.  
    * 从串口读取数据
  148.  
    *
  149.  
    * @param serialPort
  150.  
    * 当前已建立连接的SerialPort对象
  151.  
    * @return 读取到的数据
  152.  
    * @throws ReadDataFromSerialPortFailure
  153.  
    * 从串口读取数据时出错
  154.  
    * @throws SerialPortInputStreamCloseFailure
  155.  
    * 关闭串口对象输入流出错
  156.  
    */
  157.  
    public static byte[] readFromPort(SerialPort serialPort)
  158.  
    throws ReadDataFromSerialPortFailure,
  159.  
    SerialPortInputStreamCloseFailure {
  160.  
    InputStream in = null;
  161.  
    byte[] bytes = null;
  162.  
    try {
  163.  
    in = serialPort.getInputStream();
  164.  
    // 获取buffer里的数据长度
  165.  
    int bufflenth = in.available();
  166.  
    while (bufflenth != 0) {
  167.  
    // 初始化byte数组为buffer中数据的长度
  168.  
    bytes = new byte[bufflenth];
  169.  
    in.read(bytes);
  170.  
    bufflenth = in.available();
  171.  
    }
  172.  
    } catch (IOException e) {
  173.  
    throw new ReadDataFromSerialPortFailure();
  174.  
    } finally {
  175.  
    try {
  176.  
    if (in != null) {
  177.  
    in.close();
  178.  
    in = null;
  179.  
    }
  180.  
    } catch (IOException e) {
  181.  
    throw new SerialPortInputStreamCloseFailure();
  182.  
    }
  183.  
    }
  184.  
    return bytes;
  185.  
    }
  186.  
     
  187.  
    /**
  188.  
    * 添加监听器
  189.  
    *
  190.  
    * @param port
  191.  
    * 串口对象
  192.  
    * @param listener
  193.  
    * 串口监听器
  194.  
    * @throws TooManyListeners
  195.  
    * 监听类对象过多
  196.  
    */
  197.  
    public static void addListener(SerialPort port,
  198.  
    SerialPortEventListener listener) throws TooManyListeners {
  199.  
    try {
  200.  
    // 给串口添加监听器
  201.  
    port.addEventListener(listener);
  202.  
    // 设置当有数据到达时唤醒监听接收线程
  203.  
    port.notifyOnDataAvailable(true);
  204.  
    // 设置当通信中断时唤醒中断线程
  205.  
    port.notifyOnBreakInterrupt(true);
  206.  
    } catch (TooManyListenersException e) {
  207.  
    throw new TooManyListeners();
  208.  
    }
  209.  
    }
  210.  
    }
有了工具类之后,接下来我们就可以开始测试串口通讯了,如下:
 
到这里串口通讯测试的也差不多了。可能自己做的项目中需要自己做两个串口,一个client端和一个server端。为了使串口操作变的可视化,大家也可以使用JFrame来进行操作窗口模拟,这里就不做多的介绍了。

使用Java进行串口SerialPort通讯的更多相关文章

  1. java实现串口通讯

    一. 准备工作 1. 点击此下载java串口通讯相关工具 2. 将RXTXcomm.jar放到  %JAVA_HOME%\jre\lib\ext\  目录下,工程中引入该jar包 3. 将rxtxSe ...

  2. java读写串口数据

    本博文参考自https://www.cnblogs.com/Dreamer-1/p/5523046.html 最近接触到了串口及其读写,在此记录java进行串口读写的过程. 1.导入串口支持包 需要下 ...

  3. Java实现串口通信的小样例

    用Java实现串口通信(windows系统下),须要用到sun提供的串口包 javacomm20-win32.zip.当中要用到三个文件,配置例如以下: 1.comm.jar放置到 JAVA_HOME ...

  4. 用Java通过串口发送手机短信

    用Java通过串口发短信其实很简单,因为有现成的类库供我们使用.有底层的类库,也有封装好一点的类库,下面我介绍一下在 Win32 平台下发送短信的方法. 如果你想用更底层的类库开发功能更强大的应用程序 ...

  5. 自制单片机之十七……PC与单片机RS-232串口的通讯和控制

    这次我们来试着一步步的去掌握PC与单片机通过RS-232进行通讯和控制. 先说说我硬件的情况.我用的PC是个二手的IBM240小本本,十寸屏,赛扬400,机子很老了.但也有它的优点:1.串口,并口,P ...

  6. Java编写串口程序

    用Java编写串口程序一般都会用到这个 http://fizzed.com/oss/rxtx-for-java 根据电脑的情况下载 解压以后有安装文档 For a JDK installation: ...

  7. java读取串口-mfz-rxtx-2.2-20081207-win-x86

    1.下载jar包 RXTXcomm.jar 2.实现代码 package main; import java.awt.*; import java.awt.event.*; import java.i ...

  8. gRPC java 客户端,服务器端通讯使用json格式

    使用 protobuf 作为通讯内容序列化的简单例子请看:http://www.cnblogs.com/ghj1976/p/5458176.html . 本文是使用 json 做为内容序列化的简单例子 ...

  9. c# 串口SerialPort

    创建SerialPortFun类 using System; using System.Collections.Generic; using System.Linq; using System.Tex ...

随机推荐

  1. decimal模块

    简介 decimal意思为十进制,这个模块提供了十进制浮点运算支持. 常用方法 1.可以传递给Decimal整型或者字符串参数,但不能是浮点数据,因为浮点数据本身就不准确. 2.要从浮点数据转换为De ...

  2. Number of Airplanes in the Sky

    Given an interval list which are flying and landing time of the flight. How many airplanes are on th ...

  3. 学习mysql replication gitd

  4. linux backtrace()详细使用说明,分析Segmentation fault【转】

    转自:http://velep.com/archives/1032.html 在此之前,开发eCos应用程序时,经常碰到程序挂掉后,串口打印输出一大串让人看不懂的数据.今天才明白,原来这些数据是程序挂 ...

  5. springmvc上下文与springcontext上下文的关系

    内容摘自:springmvc与spring上下文的关系 原理区别 一直不清楚springmvc-servlet.xml配置与spring.xml两个配置文件出现的上下文关系.今天找到一上面的文章,倒是 ...

  6. java 内部类 工厂方法

    用内部类实现工厂模式 :优先使用类而不是接口,如果你的设计中需要某个接口,你必须了解它,否则不到迫不得已,不要将其放到你的类中 //: innerclasses/Factories.java impo ...

  7. java 多重继承

    接口不仅仅只是一种更纯粹形式的抽象类,它的目标比这更高,因为接口是根本没有任何具体实现的--也就是说,没有任何与接口相关的存储,因此也就无法阻止多个接口的组合, 在导出类中,不强制要求必须有一个抽象的 ...

  8. EFCore CodeFirst 适配数据库

    EF6中可以直接根据代码模型生成数据库Database.SetInitializer即可 在EFCore中如何实现呢? 这项功能放在了DatabaseFacade对象中,传入数据库上下文对象实例化到一 ...

  9. 一步一步学习IdentityServer3 (3)

    在上一篇中配置一个基础的idrserver服务端 这篇文章将对服务端做一些变化,这里我先贴一下上一章中的代码 证书: static class Certificate { public static ...

  10. 只想写一个真正能用的django mock

    调参数的过程,百转千回. 还好,搞得差不多了. 确实,方便写测试用例, 也是一个开发水平高低的衡量~~~:( 为了测试这个mock,不得不改下代码~~ 还要不断的将Model里允许Null的参数写完, ...