zoukankan      html  css  js  c++  java
  • Java 串口编程 简单飞扬

    Javax.comm简介
        Javax.comm是Sun公司提供的,用于开发平台独立的通讯应用程序的扩展API。(ps:这里javax的x很准确地表明了它是一个扩展包,而不是核心包(core package),但由于历史原因,javax下的并不都是扩展包,比如swing包已经是Java核心架构的一部分了,不过为了与Java1.1编码兼容,仍使用javax.swing。)javax.comm可以访问RS232接口(串口)及有限制地访问IEEE-1284(并口)。

    下载
        http://mdubuc.freeshell.org/Jolt/javacomm20-win32.zip和(完整的2.0版本,还有 examples)。

    安装
        这里的所谓安装就是把三个重要的文件放到指定的目录下。In summary it says:
         comm.jar                     should go in the ..\jre\lib\ext folder
         javax.comm.properties  should go in the ..\jre\lib folder

         win32comm.dll              should go in c:\windows folder (I put it in c:\WINNT folder in my case.)


    API
    在javax.comm下有13个类和接口,分别是

    4个接口
    CommDriver 可负载设备(the loadable device)驱动程序接口的一部分
    CommPortOwnershipListener 传递各种通讯端口的所有权事件
    ParallelPortEventListener 传递并行端口事件
    SerialPortEventListener 传递串行端口事件

    6个类
    CommPort 通讯端口
    CommPortIdentifier通讯端口管理
    ParallelPort 并行通讯端口
    ParallelPortEvent 并行端口事件
    SerialPort RS-232串行通讯端口
    SerialPortEvent 串行端口事件

    3个异常类
    NoSuchPortException 当驱动程序不能找到指定端口时抛出
    PortInUseException 当碰到指定端口正在使用中时抛出
    UnsupportedCommOperationException 驱动程序不允许指定操作时抛出

    实例
        同API一起下载的还有一个examples文件,里面有6个程序。首先看最简单的读、写程序。

    读串口的例程
    import java.io.*;
    import java.util.*;
    import javax.comm.*;

    public class SimpleRead implements Runnable, SerialPortEventListener {

        static CommPortIdentifier portId;
        static Enumeration portList;//枚举类

        InputStream inputStream;
        SerialPort serialPort;
        Thread readThread;

        public static void main(String[] args) {

            portList = CommPortIdentifier.getPortIdentifiers();/*不带参数的getPortIdentifiers方法获得一个枚举对象,该对象又包含了系统中管理每个端口的CommPortIdentifier对象。注意这里的端口不仅仅是指串口,也包括并口。这个方法还可以带参数。getPortIdentifiers(CommPort)获得与已经被应用程序打开的端口相对应的CommPortIdentifier对象。 getPortIdentifier(String portName)获取指定端口名(比如“COM1”)的CommPortIdentifier对象。*/

            while (portList.hasMoreElements()) {
                portId = (CommPortIdentifier) portList.nextElement();
                if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL)/*getPortType方法返回端口类型*/ {
                    // if (portId.getName().equals("COM1"))/* 找Windows下的第一个串口*/ {
                    if (portId.getName().equals("/dev/term/a"))/*找Unix-like系统下的第一个串口*/ {
                        SimpleRead reader = new SimpleRead();
                    }
                }
            }
        }

        public SimpleRead() {
            try {
                serialPort = (SerialPort) portId.open("SimpleReadApp", 2000);/* open方法打开通讯端口,获得一个CommPort对象。它使程序独占端口。如果端口正被其他应用程序占用,将使用 CommPortOwnershipListener事件机制,传递一个PORT_OWNERSHIP_REQUESTED事件。每个端口都关联一个 InputStream 何一个OutputStream。如果端口是用open方法打开的,那么任何的getInputStream都将返回相同的数据流对象,除非有close 被调用。有两个参数,第一个为应用程序名;第二个参数是在端口打开时阻塞等待的毫秒数。*/
            } catch (PortInUseException e) {}
            try {
                inputStream = serialPort.getInputStream();/*获取端口的输入流对象*/
            } catch (IOException e) {}
        try {
                serialPort.addEventListener(this);/*注册一个SerialPortEventListener事件来监听串口事件*/
        } catch (TooManyListenersException e) {}

            serialPort.notifyOnDataAvailable(true);/*数据可用*/

            try {
                serialPort.setSerialPortParams(9600,
                    SerialPort.DATABITS_8,
                    SerialPort.STOPBITS_1,
                    SerialPort.PARITY_NONE);/*设置串口初始化参数,依次是波特率,数据位,停止位和校验*/
            } catch (UnsupportedCommOperationException e) {}

            readThread = new Thread(this);
            readThread.start();
        }

        public void run() {
            try {
                Thread.sleep(20000);
            } catch (InterruptedException e) {}
        }

    //串口事件
        public void serialEvent(SerialPortEvent event) {

            switch(event.getEventType()) {
            case SerialPortEvent.BI:/*Break interrupt,通讯中断*/
            case SerialPortEvent.OE:/*Overrun error,溢位错误*/
            case SerialPortEvent.FE:/*Framing error,传帧错误*/
            case SerialPortEvent.PE:/*Parity error,校验错误*/
            case SerialPortEvent.CD:/*Carrier detect,载波检测*/
            case SerialPortEvent.CTS:/*Clear to send,清除发送*/
            case SerialPortEvent.DSR:/*Data set ready,数据设备就绪*/
            case SerialPortEvent.RI:/*Ring indicator,响铃指示*/
            case SerialPortEvent.OUTPUT_BUFFER_EMPTY:/*Output buffer is empty,输出缓冲区清空*/
                break;

            case SerialPortEvent.DATA_AVAILABLE:/*Data available at the serial port,端口有可用数据。读到缓冲数组,输出到终端*/
                byte[] readBuffer = new byte[20];

                try {
                    while (inputStream.available() > 0) {
                        int numBytes = inputStream.read(readBuffer);
                    }
                    System.out.print(new String(readBuffer));
                } catch (IOException e) {}
                break;
            }
        }
    }
    (PS:不推荐Thread的这种用法,详见《Core Java VolumeII》)

    写串口的例程
        把字符串"Hello, world!\n"写到系统的第一个串口

    import java.io.*;
    import java.util.*;
    import javax.comm.*;

    public class SimpleWrite {
        static Enumeration portList;
        static CommPortIdentifier portId;
        static String messageString = "Hello, world!\n";
        static SerialPort serialPort;
        static OutputStream outputStream;

        public static void main(String[] args) {
            portList = CommPortIdentifier.getPortIdentifiers();

            while (portList.hasMoreElements()) {
                portId = (CommPortIdentifier) portList.nextElement();
                if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
                    // if (portId.getName().equals("COM1")) {
                    if (portId.getName().equals("/dev/term/a")) {
                        try {
                            serialPort = (SerialPort)
                                portId.open("SimpleWriteApp", 2000);
                        } catch (PortInUseException e) {}
                        try {
                            outputStream = serialPort.getOutputStream();
                        } catch (IOException e) {}
                        try {
                            serialPort.setSerialPortParams(9600,
                                SerialPort.DATABITS_8,
                                SerialPort.STOPBITS_1,
                                SerialPort.PARITY_NONE);
                        } catch (UnsupportedCommOperationException e) {}
                        try {
                            outputStream.write(messageString.getBytes());
                        } catch (IOException e) {}
                    }
                }
            }
        }
    }

        上面两个例程都经过了简化,在打开端口,并且传输结束后没有关闭数据流和串口。在例程中我们看到CommPortIdentifier提供了打开通讯端口的方法open,但却没有相应关闭端口的方法,关闭端口需要调用javax.comm.CommPort类的close()。CommPort是这个包中的一个高级抽象,它定义了端口可作的各种事情:获取I/O数据流对象,控制缓冲区大小,调整输入的处理

  • 相关阅读:
    redis集群规范
    mongodb的基本使用
    redis进阶
    redis基本使用
    selenium的基本使用
    C++入门
    C语言入门
    MATLAB中矩阵reshape的顺序规律
    Tensorflow:ImportError: DLL load failed: 找不到指定的模块 Failed to load the native TensorFlow runtime
    差分定位和精密定位
  • 原文地址:https://www.cnblogs.com/jiandanfy/p/1419373.html
Copyright © 2011-2022 走看看