從串口讀數據
從串口COM11發送的數據最終將到達與其連通的串口COM21,如果COM21處于可用狀態,則到達的數據將被緩存,等待程序的讀取。從串口讀入數據有多種模式,本文將介紹“輪詢模式”和事件監聽模式。
“輪詢模式”是指程序(線程)每隔固定的時間就對串口進行一次掃描,如果掃描發現串口中有可用數據,則進行讀取。Com21PollingListener類使用“事件監聽模式”讀取串口COM21接收到的數據:
Com21PollingListener.java
package com.serialPort.listener;
import java.io.IOException;
import java.io.InputStream;
import javax.comm.CommPortIdentifier;
import javax.comm.NoSuchPortException;
import javax.comm.PortInUseException;
import javax.comm.SerialPort;
/**
* Com21PollingListener類使用“輪訓”的方法監聽串口COM21,
* 并通過COM21的輸入流對象來獲取該端口接收到的數據(在本文中數據來自串口COM11)。
*/
public class Com21PollingListener {
public static void main(String[] args){
//1.定義變量
CommPortIdentifier com21 = null;//未打卡的端口
SerialPort serialCom21 = null;//打開的端口
InputStream inputStream = null;//端口輸入流
try{
//2.獲取并打開串口COM21
com21 = CommPortIdentifier.getPortIdentifier(“COM21”);
serialCom21 = (SerialPort) com21.open(“Com21Listener”, 1000);
//3.獲取串口的輸入流對象
inputStream = serialCom21.getInputStream();
//4.從串口讀入數據
//定義用于緩存讀入數據的數組
byte[] cache = new byte[1024];
//記錄已經到達串口COM21且未被讀取的數據的字節(Byte)數。
int availableBytes = 0;
//無限循環,每隔20毫秒對串口COM21進行一次掃描,檢查是否有數據到達
while(true){
//獲取串口COM21收到的可用字節數
availableBytes = inputStream.available();
//如果可用字節數大于零則開始循環并獲取數據
while(availableBytes 》 0){
//從串口的輸入流對象中讀入數據并將數據存放到緩存數組中
inputStream.read(cache);
//將獲取到的數據進行轉碼并輸出
for(int j = 0;j 《 cache.length && j 《 availableBytes; j++){
//因為COM11口發送的是使用byte數組表示的字符串,
//所以在此將接收到的每個字節的數據都強制裝換為char對象即可,
//這是一個簡單的編碼轉換,讀者可以根據需要進行更加復雜的編碼轉換。
System.out.print((char)cache[j]);
}
System.out.println();
//更新循環條件
availableBytes = inputStream.available();
}
//讓線程睡眠20毫秒
Thread.sleep(20);
}
}catch(InterruptedException e){
e.printStackTrace();
}catch (NoSuchPortException e) {
//找不到串口的情況下拋出該異常
e.printStackTrace();
} catch (PortInUseException e) {
//如果因為端口被占用而導致打開失敗,則拋出該異常
e.printStackTrace();
} catch (IOException e) {
//如果獲取輸出流失敗,則拋出該異常
e.printStackTrace();
}
}
}
“事件監聽模式”是為串口注冊一個事件監聽類,當有數據到達串口的時候就會觸發事件,在事件的響應方法中讀取串口接收到的數據。Com21EventListener類使用“事件監聽模式”讀取串口COM21接收到的數據:
Com21EventListener.java
package com.serialPort.listener;
import java.io.IOException;
import java.io.InputStream;
import java.util.TooManyListenersException;
import javax.comm.CommPortIdentifier;
import javax.comm.NoSuchPortException;
import javax.comm.PortInUseException;
import javax.comm.SerialPort;
import javax.comm.SerialPortEvent;
import javax.comm.SerialPortEventListener;
/**
* Com21EventListener類使用“事件監聽模式”監聽串口COM21,
* 并通過COM21的輸入流對象來獲取該端口接收到的數據(在本文中數據來自串口COM11)。
* 使用“事件監聽模式”監聽串口,必須字定義一個事件監聽類,該類實現SerialPortEventListener
* 接口并重寫serialEvent方法,在serialEvent方法中編寫監聽邏輯。
*/
public class Com21EventListener implements SerialPortEventListener {
//1.定義變量
CommPortIdentifier com21 = null;//未打卡的端口
SerialPort serialCom21 = null;//打開的端口
InputStream inputStream = null;//輸入流
//2.構造函數:
//實現初始化動作:獲取串口COM21、打開串口、獲取串口輸入流對象、為串口添加事件監聽對象
public Com21EventListener(){
try {
//獲取串口、打開窗串口、獲取串口的輸入流。
com21 = CommPortIdentifier.getPortIdentifier(“COM21”);
serialCom21 = (SerialPort) com21.open(“Com21EventListener”, 1000);
inputStream = serialCom21.getInputStream();
//向串口添加事件監聽對象。
serialCom21.addEventListener(this);
//設置當端口有可用數據時觸發事件,此設置必不可少。
serialCom21.notifyOnDataAvailable(true);
} catch (NoSuchPortException e) {
e.printStackTrace();
} catch (PortInUseException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (TooManyListenersException e) {
e.printStackTrace();
}
}
//重寫繼承的監聽器方法
@Override
public void serialEvent(SerialPortEvent event) {
//定義用于緩存讀入數據的數組
byte[] cache = new byte[1024];
//記錄已經到達串口COM21且未被讀取的數據的字節(Byte)數。
int availableBytes = 0;
//如果是數據可用的時間發送,則進行數據的讀寫
if(event.getEventType() == SerialPortEvent.DATA_AVAILABLE){
try {
availableBytes = inputStream.available();
while(availableBytes 》 0){
inputStream.read(cache);
for(int i = 0; i 《 cache.length && i 《 availableBytes; i++){
//解碼并輸出數據
System.out.print((char)cache[i]);
}
availableBytes = inputStream.available();
}
System.out.println();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//在main方法中創建類的實例
public static void main(String[] args) {
new Com21EventListener();
}
}
讀寫程序的聯合運行
串口能接收到數據的前提是該串口處于打開(可用)狀態,如果串口處于關閉狀態,那么發送到該串口的數據就會丟失。所以在實驗的過程中,如果使用銅線連接同一個串口的引腳2和引腳3,一定要注意的是千萬不能在向串口發送完數據之后關閉該串口,然后再次打開串口去讀取數據,一定要讓串口始終處于打開狀態直到程序運行結束。
評論
查看更多