关于串口通信的学习记录

声明:本文代码摘抄至网上源码,本笔录只为记录学习和后面回顾

工具:myeclipse, Virtual Serial Port Driver 6.9,友善串口调试工具。

言语:java

依赖包:rxtxccom.jar

基于rxtx的串口通信接口代码编写:

获得本机可用的串口列表:

    通过CommPortIdentifier对象的到系统的串口列表。源码如下

 1  public static final ArrayList<String> findPort() {
 2         // 获得当前所有可用串口
 3         Enumeration<CommPortIdentifier> portList = CommPortIdentifier
 4                 .getPortIdentifiers();
 5         ArrayList<String> portNameList = new ArrayList<String>();
 6         // 将可用串口名添加到List并返回该List
 7         while (portList.hasMoreElements()) {
 8             String portName = portList.nextElement().getName();
 9             portNameList.add(portName);
10         }
11         return portNameList;
12  }

 设置参数开启串口:源码如下

 1 public static final SerialPort openPort(String portName, int baudrate,
 2             int dataBits,int stopBits,int parity){
 3         try {
 4             // 通过端口名识别端口
 5             CommPortIdentifier portIdentifier = CommPortIdentifier
 6                     .getPortIdentifier(portName);
 7             // 打开端口,设置端口名与timeout(打开操作的超时时间)
 8             CommPort commPort = portIdentifier.open(portName, 2000);
 9             // 判断是不是串口
10             if (commPort instanceof SerialPort) {
11                 SerialPort serialPort = (SerialPort) commPort;
12                 try {
13                     // 设置串口的波特率等参数
14                     serialPort.setSerialPortParams(baudrate,
15                             SerialPort.DATABITS_8, SerialPort.STOPBITS_1,
16                             SerialPort.PARITY_NONE);
17                 } catch (UnsupportedCommOperationException e) {
18                     e.printStackTrace();
19                 }
20                 return serialPort;
21             } else {
22                 // 不是串口
23                 System.out.println("不是串口");
24             }
25         } catch (NoSuchPortException e1) {
26             e1.printStackTrace();
27         } catch (PortInUseException e2) {
28             e2.printStackTrace();
29         }
30         return null;
31 }

 开启了一个serialPort后加载一个监听,我写了个SerialListener实现SerialPortEventListener,重写接口里面的serialEvent(SerialPortEvent serialPortEvent)方法。源码如下

public void serialEvent(SerialPortEvent serialPortEvent) {
        // TODO Auto-generated method stub
        switch (serialPortEvent.getEventType()) {
            case SerialPortEvent.BI: // 10 通讯中断
            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: break;// 2 输出缓冲区已清空
            case SerialPortEvent.DATA_AVAILABLE: // 1 串口存在可用数据
                byte[] readBuffer = new byte[20];
                try {
                    int numBytes = -1;
                    while (inputStream.available() > 0) {
                        numBytes = inputStream.read(readBuffer);

                        if (numBytes > 0) {
                            msgQueue.add(new Date() + "真实收到的数据为:-----"
                                    + new String(readBuffer));
                            readBuffer = new byte[20];// 重新构造缓冲对象,否则有可能会影响接下来接收的数据
                        } else {
                            msgQueue.add("额------没有读到数据");
                        }
                    }
                } catch (IOException e) {
                }
                break;
}

      此监听器实时监听串口中的事件,当串口存在数据就会间数据会将数据存入

BlockingQueue<String> msgQueue中。再建一个线程实时监控缓存区msgQueue中是否有数据,如果有就将其输出或提取。源码如下:

public void run() {
        // TODO Auto-generated method stub
         try {
                System.out.println("--------------任务处理线程运行了--------------");
                while (true) {
                    // 如果堵塞队列中存在数据就将其输出
                    if (msgQueue.size() > 0) {
                        System.out.println(msgQueue.take());
                    }
                }
         } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
         }
    }

    msgQueue设为私有参数,需要提取数据时可以通过get获取。

传送数据

public static void sendToPort(SerialPort serialPort, byte[] order){
        OutputStream out = null;
        try {
            out = serialPort.getOutputStream();
            out.write(order);
            out.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (out != null) {
                    out.close();
                    out = null;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
}

通过串口得到outputstream,向其写入数据就好了。

关闭串口

public static void closePort(SerialPort serialPort) {
        if (serialPort != null) {
            serialPort.close();
            serialPort = null;
        }
}

测试环境搭建:

先安装了Virtual Serial Port Driver 6.9软件构建成对的串口(电脑没有成对的串口)。在安装友善串口调试工具,打开两个调试窗口,分别选一对串口中的一个,并设置相同配置。测试发送和接收。

如果测试数据可以收发,就将一个调试串口关了,换位java窗口收发消息。

具体代码为调用上面接口的小程序。

posted @ 2017-08-15 21:09  共祝愿  阅读(387)  评论(0编辑  收藏  举报