有關Java串口通訊簡介,嵌入式系統或感測器網路的許多應用和測試都需要透過PC機與嵌入式設備或感測器節點進行通訊。其中,最常用的介面就是RS-232串列埠和並口(鑑於USB介面的複雜性以及不需要很大的資料傳輸量,USB介面用在這裡還是顯得過於奢侈,況且目前除了SUN有一個支援USB的包之外,我還沒有看到其他直接支援USB的Java類別庫)。
SUN的CommAPI分別提供了對常用的RS232序列埠和IEEE1284並行埠通訊的支援。 RS-232-C(又稱EIA RS-232-C,以下簡稱RS232)是在1970年由美國電子工業協會(EIA)聯合貝爾系統、調變解調器廠商及電腦終端生產廠商共同製定的用於串列通訊的標準。 RS232是一個全雙工的通訊協議,它可以同時進行資料接收和發送的工作。
1 常見的Java串口包
目前,常見的Java串口包有SUN在1998年發布的串口通訊API:comm2.0.jar(Windows下)、comm3.0.jar(Linux/Solaris);IBM的串口通訊API以及一個開源的實作。鑑於在Windows下SUN的API比較常用以及IBM的實現和SUN的在API層面都是一樣的,那個開源的實現又不像兩家大廠的產品那樣讓人放心,這裡就只介紹SUN的串口通信API在Windows平台下的使用。
按照其使用說明(Readme.html)的說法,要想使用串口包進行串口通信,除了設置好環境變量之外,還要將win32com.dll複製到bin目錄下;將comm.jar複製到lib ;把javax.comm.properties也同樣拷貝到lib 目錄下。然而在真正運行使用串口包的時候,僅作這些是不夠的。
因為通常運行「java MyApp」的時候,是由JRE下的虛擬機器啟動MyApp的。而我們只複製上述檔案到JDK對應目錄下,所以應用程式將會提示找不到串列埠。解決這個問題的方法很簡單,我們只要將上面提到的檔案放到JRE對應的目錄下就可以了。
值得注意的是,在網路應用程式中使用串口API的時候,還會遇到其他更複雜問題。有興趣的話,可以查看CSDN社群中「關於網頁上Applet用javacomm20讀取客戶端串口的問題」的貼文。
2 串列口API概覽
2.1 javax.comm.CommPort
這是用來描述一個被底層系統支援的連接埠的抽象類別。它包含一些高層的IO控制方法,這些方法對於所有不同的通訊連接埠來說是通用的。 SerialPort 和ParallelPort都是它的子類,前者用來控制串列埠而後者用來控這並口,二者對於各自底層的實體埠都有不同的控制方法。這裡我們只關心 SerialPort。
2.2 javax.comm.CommPortIdentifier
這個類別主要用於對串列埠進行管理和設置,是對串口進行存取控制的核心類別。主要包括以下方法
確定是否有可用的通訊埠
為IO操作開啟通訊埠
決定埠的所有權
處理埠所有權的爭用
管理埠所有權變更引發的事件(Event)
2.3
2.3 javax.comm.SerialPort這個類別用來描述一個RS-232串列通訊埠的底層接口,它定義了串口通訊所需的最小功能集。透過它,使用者可以直接對串口進行讀取、寫入及設定工作。 2.4 串口API實例大段的文字怎麼也不如一個小例子來的清晰,下面我們就一起看一下串口包自帶的例子---SerialDemo中的一小段程式碼來加深對串口API核心類的使用方法的認識。 2.4.1 列舉出本機所有可用串列埠void listPortChoices() { CommPortIdentifier portId; Enumeration en = CommPortIdentifier.getPortIdentifiers(); // iterate through the ports. while (en.hasMoreElements()) { portId = (CommPortIdentifier) en.nextElement(); if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) { System.out.println(portId.getName()); } } portChoice.select(parameters.getPortName()); }以上程式碼可以列舉出目前系統所有可用的串列埠名稱,我的機器上輸出的結果是COM1和COM3。 2.4.2 串列埠參數的配置串口一般有以下參數可以在該串列埠開啟先前配置進行配置:包括波特率,輸入/輸出流控制,資料位數,停止位和齊偶校驗。
SerialPort sPort; try { sPort.setSerialPortParams(BaudRate,Databits,Stopbits,Parity); //设置输入/输出控制流 sPort.setFlowControlMode(FlowControlIn | FlowControlOut); } catch (UnsupportedCommOperationException e) {}2.4.3 串口的讀寫對串口讀寫之前需要先打開一個串口:
CommPortIdentifier portId = CommPortIdentifier.getPortIdentifier(PortName); try { SerialPort sPort = (SerialPort) portId.open("串口所有者名称", 超时等待时间); } catch (PortInUseException e) {//如果端口被占用就抛出这个异常 throw new SerialConnectionException(e.getMessage()); } //用于对串口写数据 OutputStream os = new BufferedOutputStream(sPort.getOutputStream()); os.write(int data); //用于从串口读数据 InputStream is = new BufferedInputStream(sPort.getInputStream()); int receivedData = is.read();讀出來的是int型,你可以把它轉換成需要的其他類型。 這裡要注意的是,由於Java語言沒有無符號類型,即所有的類型都是帶符號的,在由byte到int的時候應該尤其註意。因為如果byte的最高位是1,則轉成int型別時會用1來佔位。這樣,原本是10000000的byte類型的數變成int型就成了1111111110000000,這是很嚴重的問題,應該要注意避免。 3 串口通信的通用模式及其問題🎜🎜終於嘮叨完我最討厭的基礎知識了,下面開始我們本次的重點--串口應用的研究。由於向串列埠寫資料很簡單,所以這裡我們只關注從串列口讀取資料的情況。 🎜
通常,串口通訊應用程式有兩種模式,一種是實現SerialPortEventListener接口,監聽各種串口事件並作相應處理;另一種就是建立一個獨立的接收線程專門負責資料的接收。由於這兩種方法在某些情況下存在著很嚴重的問題(至於什麼問題這裡先賣個關子J),所以我的實作是採用第三種方法來解決這個問題。
更多簡單介紹Java的串口通訊相關文章請關注PHP中文網!