首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 串口通訊實戰:Java Communications API 與 RS-232 完整指南

     編輯:Java 相關知識

前言:串口通訊無處不在

從早期的 Modem、滑鼠/鍵盤,到現代的 USB、工業儀器、醫療設備、網路設備,串列通訊(RS-232/485/422、USB)始終是硬體互聯的基石。Java 標準庫未內建串口支援,需引入 Java Communications API (comm.jar)。本文涵蓋 RS-232 基礎、API 安裝、核心類別、輪詢與事件驅動兩種讀取模式,並提供完整可運行程式碼。

RS-232 硬體基礎速查

  • 全雙工:可同時收發。
  • 常見接腳(DB9): 2=RXD(接收)、3=TXD(發送)、5=GND(地線)。
  • 三線制接法: 交叉連接 TXD↔RXD、GND↔GND。
  • 判別 TXD/RXD 小技巧: 萬用表測量針腳對 GND 電壓,TXD 通常呈 -3V ~ -15V 負電壓。

Java Communications API 安裝三步驟

  1. comm.jar → $JAVA_HOME/jre/lib/ext/
  2. win32com.dll → 應用程式工作目錄(user.dir)或 $JAVA_HOME/jre/bin/
  3. javax.comm.properties → $JAVA_HOME/jre/lib/

Linux 平台請參考 RXTX 專案。

核心 API 架構(javax.comm 套件)

類別/介面職責
CommPortIdentifier列舉、開啟、管理埠佔用權
CommPort父介面,提供 getInputStream()/getOutputStream()
SerialPort串口專用,設定鮑率、資料位、停止位、校驗位、流控
SerialPortEventListener事件驅動模式的監聽器介面

實作範例:列舉可用串口

Enumeration<CommPortIdentifier> ports = CommPortIdentifier.getPortIdentifiers();
while (ports.hasMoreElements()) {
    CommPortIdentifier pid = ports.nextElement();
    if (pid.getPortType() == CommPortIdentifier.PORT_SERIAL) {
        System.out.println("可用串口: " + pid.getName()); // 例: COM1, COM2
    }
}

開啟埠與 I/O 基礎操作

CommPortIdentifier pid = CommPortIdentifier.getPortIdentifier("COM1");
SerialPort port = (SerialPort) pid.open("MyApp", 2000); // 2 秒逾時
port.setSerialPortParams(9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);

InputStream in = port.getInputStream();
OutputStream out = port.getOutputStream();
// 讀寫邏輯...
port.close(); // 釋放埠

兩種資料讀取模式

1. 輪詢模式 - 適合簡單、單執行緒場景

public class PollingReader extends Thread {
    private InputStream in;
    private volatile boolean stop = false;
    public void run() {
        StringBuffer buf = new StringBuffer();
        try {
            while (!stop) {
                int ch = in.read();
                if (ch == 'Q' || ch == 'q') { stop = true; break; }
                buf.append((char) ch);
            }
        } catch (IOException ignored) {}
    }
}

2. 事件驅動模式 - 專業、非阻塞、高併發首選

public class EventReader implements SerialPortEventListener {
    private SerialPort port;
    public EventReader(SerialPort port) {
        this.port = port;
        port.addEventListener(this);
        port.notifyOnDataAvailable(true);
    }
    public void serialEvent(SerialPortEvent e) {
        if (e.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
            try (InputStream in = port.getInputStream()) {
                int ch; StringBuffer buf = new StringBuffer();
                while ((ch = in.read()) > 0) buf.append((char) ch);
                System.out.println("收到: " + buf);
            } catch (IOException ex) { ex.printStackTrace(); }
        }
        // 其他事件: CTS, DSR, BI, OE, PE, FE, RI, OUTPUT_BUFFER_EMPTY 等
    }
}

常見坑點與最佳實踐

  • 務必 close() 釋放埠,否則後續開啟會拋 PortInUseException。
  • 輸入流無 EOF,需自訂結束符或協定長度。
  • 生產環境建議使用成熟庫 jSerialComm 或 RXTX 替代舊版 comm.jar。
  • 多執行緒存取 SerialPort 時需自行同步。

結語

Java Communications API 雖歷史悠久,但其事件驅動模型與標準串流介面設計經典,掌握後可輕鬆整合各類串口設備。現代專案建議改用積極維護的 jSerialComm,API 相似且跨平台支援更佳。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved