Java 串口數據收發

環境


開發環境: win7 64、java 8、RXTXcomm(mfz-rxtx-2.2)、IntelliJ IDEA 2019.1.1 x64

方法一、
  • 解壓 mfz-rxtx-2.2
  • RXTXcomm.jar 拷貝至 %JAVA_HOME%\jre\lib\ext
  • rxtxSerial.dllrxtxParallel.dll拷貝至 %JAVA_HOME%\jre\bin
  • 在IDEA新建工程後,選擇菜單 File -> Project Structure(ctrl+alt+shift+s) -> Modules -> Dependencies ,如下圖,點擊最右側加號,彈出小菜單,點擊第一個選項,再選擇需要添加的jar 包就可以了。
    在這裏插入圖片描述
方法二(推薦)、

新建 Gradle 工程,修改工程中 build.gradle 文件如下:

plugins {
    id 'java'
}

group 'Demo'
version '1.0-SNAPSHOT'

sourceCompatibility = 1.8

repositories {
    mavenLocal()
    mavenCentral()
}

dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.12'
    implementation 'org.bidib.jbidib.org.qbang.rxtx:rxtxcomm:2.2'
}

只要配置好build.gradle 文件,Gradle就會自動下載依賴包,而不需要手動添加了。

程序代碼

import gnu.io.*;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.TooManyListenersException;

public class SerialComm {

    public static void main(String[] args) throws IOException {
        //獲得系統端口列表
        getSystemPort();
        //開啓端口
        final SerialPort serialPort = openSerialPort("COM5", 115200);
        //啓動一個線程,每2s 向串口發送數據,發送1000次 hello
        new Thread(new Runnable() {
            @Override
            public void run() {
                int i = 1;
                while (i<1000) {
                    if (serialPort != null) {
                        String s = "hello \n";
                        byte[] bytes = s.getBytes();
                        SerialComm.sendData(serialPort, bytes);
                    }
                    i++;
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
        //設置串口的listener
        SerialComm.setListenerToSerialPort(serialPort, new SerialPortEventListener() {
            @Override
            public void serialEvent(SerialPortEvent serialPortEvent) {
                if (serialPortEvent.getEventType() == SerialPortEvent.DATA_AVAILABLE) { //數據通知
                    byte[] bytes = SerialComm.readData(serialPort);
                    System.out.println("收到的數據長度: " + bytes.length);
                    System.out.println("收到的數據:" + new String(bytes));
                }
            }
        });
        //closeSerialPort(serialPort);
    }


    /**
     * 獲得系統可用端口的列表
     * @return 可用的端口名稱列表
     */
    @SuppressWarnings("unchecked")
    public static List<String> getSystemPort() {
        List<String> systemPorts = new ArrayList<>();
        //獲得系統可用的端口
        Enumeration<CommPortIdentifier> portList = CommPortIdentifier.getPortIdentifiers();
        while (portList.hasMoreElements()) {
            String portName = portList.nextElement().getName();
            systemPorts.add(portName);
        }
        System.out.println("系統可用端口列表: " + systemPorts);
        return systemPorts;
    }

    /**
     * 開啓串口
     * @param serialPortName 串口名稱
     * @param baudRete  波特率
     * @return 串口對象
     */
    public static SerialPort openSerialPort(String serialPortName, int baudRete) {
        try {
            // 通過端口名稱得到端口
            CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(serialPortName);
            // 打開端口  自定義名字,打開超時時間
            CommPort commPort = portIdentifier.open(serialPortName, 2222);
            // 判斷是不是串口
            if (commPort instanceof SerialPort) {
                SerialPort serialPort = (SerialPort) commPort;
                //設置串口參數(波特率,數據位8, 停止位1, 校驗位無)
                serialPort.setSerialPortParams(baudRete, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
                System.out.println("串口開啓成功,串口名稱: " + serialPortName);
                return serialPort;
            } else {
                //是其他類型端口
                throw new NoSuchPortException();
            }
        } catch (NoSuchPortException | PortInUseException | UnsupportedCommOperationException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 關閉串口
     * @param serialPort 要關閉的串口對象
     */
    public static void closeSerialPort(SerialPort serialPort) {
        if(serialPort != null) {
            serialPort.close();
            System.out.println("關閉串口:" + serialPort.getName());
            serialPort = null;
        }
    }

    /**
     * 向串口發送數據
     * @param serialPort 串口對象
     * @param data 發送的數據
     */
    public static void sendData(SerialPort serialPort, byte[] data) {
        OutputStream os = null;
        try {
            os = serialPort.getOutputStream(); //獲取串口的輸出流
            os.write(data);
            os.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (os != null) {
                    os.close();
                    os = null;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 從串口讀取數據
     * @param serialPort 要讀取的串口
     * @return 讀取的數據
     */
    public static byte[] readData(SerialPort serialPort) {
        InputStream is = null;
        byte[] bytes = null;
        try {
            is = serialPort.getInputStream(); //獲得串口的輸入流
            int bufflenth = is.available(); //獲取數據長度
            while (bufflenth != 0) {
                bytes = new byte[bufflenth];
                int read = is.read(bytes);
                bufflenth = is.available();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (is != null) {
                    is.close();
                    is = null;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return bytes;
    }

    public static void setListenerToSerialPort(SerialPort serialPort, SerialPortEventListener listener) {
        try {
            //給串口添加事件監聽
            serialPort.addEventListener(listener);
        } catch (TooManyListenersException e) {
            e.printStackTrace();
        }
        serialPort.notifyOnDataAvailable(true);//串口有數據監聽
        serialPort.notifyOnBreakInterrupt(true);//中斷事件監聽
    }
}

源碼

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章