在這幾天做的項目中要用到Java的串口通信,所以就自己網上找資源學習了一下,我覺得下面寫的教程是一份很細節的東西,希望有需要的並且在這個串口通信方面不瞭解的小夥伴們可以耐心的看完這篇文章,製作不易。希望給你最大的幫助。
目錄
在一臺電腦上我們需要做哪些準備工作來實現Java的串口通信?
串口通信的原理
- 串口通信指串口按位(bit)發送和接收字節。儘管比按字節(byte)的並行通信慢,但是串口可以在使用一根線發送數據的同時用另一根線接收數據。
- 串口是計算機上一種非常通用的設備通信協議(不要與通用串行總線Universal SerialBus或者USB混淆)
- 典型地,串口用於ASCII碼字符的傳輸。通信使用3根線完成:(1)地線,(2)發送,(3)接收。由於串口通信是異步的,端口能夠在一根線上發送數據同時在另一根線上接收數據。其他線用於握手,但是不是必須的。串口通信最重要的參數是比特率、數據位、停止位和奇偶校驗。對於兩個進行通信的端口,這些參數必須匹配
- RS-232(ANSI/EIA-232標準)是IBM-PC及其兼容機上的串行連接標準、RS-422(EIA RS-422-AStandard)是Apple的Macintosh計算機的串口連接標準。RS-485(EIA-485標準)是RS-422的改進。
在一臺電腦上我們需要做哪些準備工作來實現Java的串口通信?
由於筆記本或臺式機上基本上都沒有成對的串口提供給我們調試使用,我們就需要下載虛擬串口軟件來實現串口調試。【當然你要是軟硬通吃的,有硬件的設備在旁邊的話,那你就忽略這一步的操作】
- 下載虛擬串口軟件:點擊這裏下載虛擬串口(提取碼:nsig)(這裏提供的軟件還是比較好用)。下載安裝完成後先不要急着運行,把壓縮包中的vspdctl.dll文件複製到安裝目錄下替換原有文件即可成功激活。
- 打開軟件添加虛擬串口,一般都是成對添加的(添加COM3、COM4)後如圖所示(根據自己的需求添加串口):
- 添加完成後到設備管理器中查看,發現多了兩個虛擬串口如圖:這樣的話就說明虛擬接口創建成功了,就可以進入下一步操作了。
- 下載串口調試軟件:點擊這裏下載最新版串口調試軟件(提取碼:wh8i),這軟件還是比較好用的。直接解壓點擊打開就ok了。
- 可以直接先打開兩個調試窗口,分別用來表示COM3和COM4串口。兩個串口的參數一定要設置的一樣纔可以正常的收發數據。(若調試可以正常收發數據後,可以關掉一個調試器,而用java程序代替)如圖:
Java代碼的編寫和調試
這一部分將是我們的重點,要與串口通信首先要在項目添加RXTXcomm.jar包(放在項目中的lib目錄下,並添加到build Path中)(win64位下載地址:https://pan.baidu.com/s/1f6aNfcVNSEmAovTcGlfjNw(提取碼:iec1));另外,還需要將解壓後的rxtxParallel.dll和rxtxSerial.dll兩個文件放在%JAVA_HOME%/jre/bin目錄下,這樣該包才能被正常的加載和調用。【在解壓以後的包中有install.txt文檔裏面有需要放到的路徑介紹(Copy RXTXcomm.jar ---> <JAVA_HOME>\jre\lib\ext ;Copy rxtxSerial.dll ---><JAVA_HOME>\jre\bin;Copy rxtxParallel.dll ---> <JAVA_HOME>\jre\bin)】
注:安裝到%JAVA_HOME%/jre/bin時--需要安裝的是tomacat下的jdk文件中,記住一定要是tomcat運行調用的jdk下,包括開發環境時,也是tomcat的jdk下(因爲有時開發配置時開發jdk與tomcat運行jdk不是同一個jdk,這裏指tomcat運行jdk,在eclipse的window-preferences下的servers中jdk)
如果不是tomacat下的jdk會報錯:java.lang.UnsatisfiedLinkError: no rxtxSerial in java.library.path thrown while loading gnu.io.RXTXCommDriver
解決方法就是把上面的幾個文件導入到正確的路徑下。
Java連接傳輸數據的代碼塊:
package Chuankou;
import java.io.*;
import java.util.*;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import gnu.io.*;
public class ContinueckRead extends Thread implements SerialPortEventListener { // SerialPortEventListener
// 監聽器,我的理解是獨立開闢一個線程監聽串口數據
static CommPortIdentifier portId; // 串口通信管理類
static Enumeration<?> portList; // 有效連接上的端口的枚舉
InputStream inputStream; // 從串口來的輸入流
static OutputStream outputStream;// 向串口輸出的流
static SerialPort serialPort; // 串口的引用
// 堵塞隊列用來存放讀到的數據
private BlockingQueue<String> msgQueue = new LinkedBlockingQueue<String>();
@Override
/**
* SerialPort EventListene 的方法,持續監聽端口上是否有數據流
*/
public void serialEvent(SerialPortEvent event) {//
switch (event.getEventType()) {
case SerialPortEvent.BI:
case SerialPortEvent.OE:
case SerialPortEvent.FE:
case SerialPortEvent.PE:
case SerialPortEvent.CD:
case SerialPortEvent.CTS:
case SerialPortEvent.DSR:
case SerialPortEvent.RI:
case SerialPortEvent.OUTPUT_BUFFER_EMPTY:
break;
case SerialPortEvent.DATA_AVAILABLE:// 當有可用數據時讀取數據
byte[] readBuffer = new byte[20];
try {
int numBytes = -1;
while (inputStream.available() > 0) {
numBytes = inputStream.read(readBuffer);
if (numBytes > 0) {
msgQueue.add(new Date() + "真實收到的數據爲:-----"
+ new String(readBuffer));
readBuffer = new byte[20];// 重新構造緩衝對象,否則有可能會影響接下來接收的數據
} else {
msgQueue.add("額------沒有讀到數據");
}
}
} catch (IOException e) {
}
break;
}
}
/**
*
* 通過程序打開COM4串口,設置監聽器以及相關的參數
*
* @return 返回1 表示端口打開成功,返回 0表示端口打開失敗
*/
public int startComPort() {
// 通過串口通信管理類獲得當前連接上的串口列表
portList = CommPortIdentifier.getPortIdentifiers();
while (portList.hasMoreElements()) {
// 獲取相應串口對象
portId = (CommPortIdentifier) portList.nextElement();
System.out.println("設備類型:--->" + portId.getPortType());
System.out.println("設備名稱:---->" + portId.getName());
// 判斷端口類型是否爲串口
if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
// 判斷如果COM4串口存在,就打開該串口
if (portId.getName().equals("COM4:USB-SERIAL")) {
try {
// 打開串口名字爲COM_4(名字任意),延遲爲2毫秒
serialPort = (SerialPort) portId.open("COM_4", 2000);
} catch (PortInUseException e) {
e.printStackTrace();
return 0;
}
// 設置當前串口的輸入輸出流
try {
inputStream = serialPort.getInputStream();
outputStream = serialPort.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
return 0;
}
// 給當前串口添加一個監聽器
try {
serialPort.addEventListener(this);
} catch (TooManyListenersException e) {
e.printStackTrace();
return 0;
}
// 設置監聽器生效,即:當有數據時通知
serialPort.notifyOnDataAvailable(true);
// 設置串口的一些讀寫參數
try {
// 比特率、數據位、停止位、奇偶校驗位
serialPort.setSerialPortParams(9600,
SerialPort.DATABITS_8, SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE);
} catch (UnsupportedCommOperationException e) {
e.printStackTrace();
return 0;
}
return 1;
}
}
}
return 0;
}
@Override
public void run() {
// TODO Auto-generated method stub
try {
System.out.println("--------------任務處理線程運行了--------------");
while (true) {
// 如果堵塞隊列中存在數據就將其輸出
if (msgQueue.size() > 0) {
System.out.println(msgQueue.take());
}
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) {
ContinueckRead cRead = new ContinueckRead();
int i = cRead.startComPort();
if (i == 1) {
// 啓動線程來處理收到的數據
cRead.start();
try {
String st = "哈哈----你好";
System.out.println("發出字節數:" + st.getBytes("gbk").length);
outputStream.write(st.getBytes("gbk"), 0,
st.getBytes("gbk").length);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else {
return;
}
}
}
Java程序與串口通信的結果:
程序和XCOM 的聯合調試:
到此關於Java和串口通信的內容全部結束,希望對你有所幫助。
No pains No results