要編寫一個程式,控制串口通訊,java裡面有...

來源:互聯網
上載者:User
 瞭解串列通訊
串列通訊協議有很多種,像RS232,RS485,RS422,甚至現今流行的USB等都是串列
通訊協議。而串列通訊技術的應用無處不在。可能大家見的最多就是電腦的串口與Mode
m的通訊。記得在PC機剛開始在中國流行起來時(大約是在90年代前五年),那時甚至有
人用一條串列線進行兩台電腦之間的資料共用。除了這些,手機,PDA,USB滑鼠、鍵盤
等等都是以串列通訊的方式與電腦串連。而筆者工作性質的關係,所接觸到的就更多了
,像多串口卡,各種種類的具有串口通訊介面的檢測與測量儀器,串口通訊的網路裝置
等。
雖然串列通訊有很多種,但筆者所知的在整個電子通訊產品方面,以RS232的通訊方
式最為多見。雖然USB介面的電子產品也是層出不窮,但瞭解一下Java在串列通訊方面的
技術還有有必要的,說不定有哪位讀者還想用此技術寫一個PDA與電腦之間資料共用的程
序呢。
本文主要以RS232為主來講解JAVA的串列通訊技術。
RS232通訊基礎
RS-232-C(又稱 EIA RS-232-C,以下簡稱RS232)是在1970年由美國電子工業協會(E
IA)聯合貝爾系統、數據機廠家及電腦終端生產廠家共同制定的用於串列通訊的
標準。RS232是一個全雙工系統的通訊協議,它可以同時進行資料接收和發送的工作。RS232
的連接埠通常有兩種:9針(DB9)和25針(DB25)。
DB9和DB25的常用針腳定義
 9針串口(DB9)
25針串口(DB25)

針號
功能說明
縮寫 針號
功能說明
縮寫
1
資料偵測載波
DCD 8
資料偵測載波
DCD
2
接收資料 RXD 3
接收資料 RXD
3
發送資料
TXD 2
發送資料
TXD
4
資料終端準備
DTR 20
資料終端準備
DTR
5
訊號地
GND 7
訊號地
GND
6
資料裝置準備好
DSR 6
資料準備好
DSR
7
請求發送 RTS 4
請求發送
RTS
8
清除發送
CTS 5
清除發送
CTS
9
響鈴指示
RI 22
響鈴指示
RI
常見的邊線方式
常見的通訊方式是三線式,這種方式是將兩個RS232裝置的發送端(TXD)和接收端(RXD)及
接地端(GND)互相串連,也是許多讀者所知道的串連方式:


(9針)
2(RXD) ------- 3(TXD
3(TXD) ------- 2(TXD)
5(GND) ------- 5(GND)
(25針)
2(RXD) ------- 3(TXD
3(TXD) ------- 2(RXD)
7(GND) ------- 7(GND)
這種方式分別將兩端的RS232介面的2--3,3---2,5(7)---5(7)針腳串連起來。其中2
是資料接收線(RXD),3是資料發送線(TXD),5(7)是接地(RND)。如果有一台式PC,和一
部NoteBook電腦,就可以用這種方式連線了。用三線式可以將大多數的RS232裝置串連起
來。但如果你認死了2--3,3--2,5(7)--5(7)對接這個理,會發現在連某些RS232裝置時並
不奏效。這是因為有些裝置在電路內部已將2和3線調換過來了,你只要2,3,5(7)針一一
對應就行了。
小技巧:如何辨別TXD和RXD連接埠。
    搞電子的人手邊應該常備一個電錶,用來測測電壓,電阻什麼的會很有用。你
只要分別測一下RS232連接埠的2--5或3--5針腳之間的電壓,通常TXD針腳與GND之間會有3
~15V左右的負電壓,表示它是TXD針腳。
安裝Java Communications API
Sun的J2SE中並沒有直接提供以上提到的任何一種串列通訊協議的開發包,而是以獨
立的jar包形式發布在java.sun.com網站上(從這裡下載)----即comm.jar,稱之為Javat
m Communications API,它是J2SE的標準擴充。comm.jar並不是最近才有,早在1998年
時,sun就已經發布了這個開發包。comm.jar分別提供了對常用的RS232序列埠和IEEE
1284並行連接埠通訊的支援。目前sun發布的comm.jar只有Windows和Solaris平台兩個版本
,如果你需要Linux平台下的,可以在 http://www.geeksville.com/~kevinh/linuxcomm
.html找到。
在使用comm.jar之前,必須知道如何安裝它。這也是困擾許多初學java RS232通訊
者的一個難題。如果我們電腦上安裝了JDK, 它將同時為我們安裝一份JRE(Java Runtim
e Entironment),通常我們運行程式時都是以JRE來啟動並執行。所以以下的安裝適用於JRE
。如果你是用JDK來運行程式的,請將相應的<JRE_HOME>改成<JDK_HOME>。
下載了comm.jar開發包後,與之一起的還有兩個重要的檔案,win32com.dll和java
x.comm.properties。 comm.jar提供了通訊用的java API,而win32com.dll提供了供co
mm.jar調用的本地驅動介面。而javax.comm.properties是這個驅動的類設定檔。首先
將comm.jar複製到<JRE_HOME>libext目錄。再將win21com.dll複製到你的RS232應用程
序啟動並執行目錄,即user.dir。然後將javax.comm.properties複製到<JRE_HOME>lib目錄

通訊前的準備
如果你手頭上沒有現成的提供了標準RS232串口的裝置,你可以將自己的電腦類比成
兩台不同的串口裝置。通常電腦主機後面的面板提供了兩個9針的串口,請將這兩個串口
的2,3,5腳按前面介紹的方法串連。電子市場都有現成的串連頭賣,請不要買那種封裝的
嚴嚴實實的接頭,而要買用螺絲封裝可以拆開的串連頭,這樣可以方便自己根據需要連
接各個針腳。
Comm API基礎
我無意於在此詳細描述Comm API每個類和介面的用法,但我會介紹Comm API的類結
構和幾個重要的API用法。
所有的comm API位於javax.comm包下面。從Comm API的javadoc來看,它介紹給我們
的只有區區以下13個類或介面:
javax.comm.CommDriver
javax.comm.CommPort
javax.comm.ParallelPort
javax.comm.SerialPort
javax.comm.CommPortIdentifier
javax.comm.CommPortOwnershipListener
javax.comm.ParallelPortEvent
javax.comm.SerialPortEvent
javax.comm.ParallelPortEventListener (extends java.util.EventListener)
javax.comm.SerialPortEventListener (extends java.util.EventListener)
javax.comm.NoSuchPortException
javax.comm.PortInUseException
javax.comm.UnsupportedCommOperationException
下面講解一下幾個主要類或介面。
1.枚舉出系統所有的RS232連接埠
在開始使用RS232連接埠通訊之前,我們想知道系統有哪些連接埠是可用的,以下代碼列
出系統中所有可用的RS232連接埠:
Enumeration en = CommPortIdentifier.getPortIdentifiers();
CommPortIdentifier portId;
while (en.hasMoreElements())
{
portId = (CommPortIdentifier) en.nextElement();
/*如果連接埠類型是串口,則列印出其連接埠資訊*/
if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL)
{
System.out.println(portId.getName());
}
}
在我的電腦上以上程式輸出以下結果:
COM1
COM2
CommPortIdentifier類的getPortIdentifiers方法可以找到系統所有的串口,每個
串口對應一個CommPortIdentifier類的執行個體。
2.開啟連接埠
如果你使用連接埠,必須先開啟它。
try{
CommPort serialPort = portId.open("My App", 60);
/* 從連接埠中讀取資料*/
InputStream input = serialPort.getInputStream();
input.read(...);
/* 往連接埠中寫資料*/
OutputStream output = serialPort.getOutputStream();
output.write(...)
...
}catch(PortInUseException ex)
{ ... }
通過CommPortIdentifier的open方法可以返回一個CommPort對象。open方法有兩個
參數,第一個是String,通常設定為你的應用程式的名字。第二個參數是時間,即開啟
連接埠逾時的毫秒數。當連接埠被另外的應用程式佔用時,將拋出PortInUseException異常

在這裡CommPortIdentifier類和CommPort類有什麼區別呢。其實它們兩者是一一對
應的關係。CommPortIdentifier主要負責連接埠的初始化和開啟,以及管理它們的佔有權
。而CommPort則是跟實際的輸入和輸出功能有關的。通過CommPort的getInputStream()
可以取得連接埠的輸入資料流,它是java.io.InputStream介面的一個執行個體。我們可以用標準的
InputStream的操作介面來讀取流中的資料,就像通過FileInputSteam讀取檔案的內容一
樣。相應的,CommPort的getOutputStream可以獲得連接埠的輸出資料流,這樣就可以往串口輸
出資料了。
3. 關閉連接埠
使用完的連接埠,必須記得將其關閉,這樣可以讓其它的程式有機會使用它,不然其
它程式使用該連接埠時可能會拋出連接埠正在使用中的錯誤。很奇怪的是,CommPortIdenti
fier類只提供了開啟連接埠的方法,而要關閉連接埠,則要調用CommPort類的close()方法。
通訊方式
CommPort的輸入資料流的讀取方式與檔案的輸入資料流有些不一樣,那就是你可能永遠不知
這個InputStream何時結束,除非對方的OutputStream向你發送了一個特定資料表示發送
結束,你收到這個特定字元後,再行關閉你的InputStream。而comm.jar提供了兩種靈活
的方式讓你讀取資料。
1. 輪詢方式(Polling)
舉個例子,你同GF相約一起出門去看電影,但你的GF好打扮,這一打扮可能就是半
小時甚至一小時以上。這時你就耐不住了,每兩分鐘就催問一次“好了沒。”,如此這
樣,直到你的GF說OK了才算完。這個就叫輪詢(Polling)。
在程式中,輪詢通常設計成一個封閉的迴圈,當滿足某個條件時即結束迴圈。剛才
那個例子中,你的GF說“OK了。”,這個就是結束你輪詢的條件。在單線程的程式中,
當迴圈一直執行某項任務而又無法預知它何時結束時,此時你的程式看起來可能就像死
機一樣。在VB程式中,這個問題可以用在迴圈結構中插入一個doEvent語句來解決。而J
ava中,最好的方式是使用線程,就像以下代碼片斷一樣。
public TestPort extend Thread
{
...
InputStream input = serialPort.getInputStream();
StringBuffer buf = new StringBuffer();
boolean stopped = false;
...
public void run()
{
try {
while( !stopped )
int ch = input.read();
if ( ch=="q" || ch=="Q" )
{
/* 結束讀取,關閉連接埠...*/
stopped = true;
...
}
else
{
buf.append((char)ch);
...
}
}catch (InterruptedException e) { }
}
}
2. 監聽方式(listening)
Comm API支援標準的Java Bean型的事件模型。也就是說,你可以使用類似AddXXXLi
stener這樣的方法為一個串口註冊自己的監聽器,以監聽方式進行資料讀取。
如要對連接埠監聽,你必須先取得CommPortIdentifier類的一個執行個體,
CommPort serialPort = portId.open("My App", 60);


從而取得SerialPort,再調用它的addEventListener方法為它添加監聽器,
serialPort.addEventListener(new MyPortListener());
SerialPort的監聽器必須繼承於SerialPortEventListener介面。當有任何SerialP
ort的事件發生時,將自動調用監聽器中的serialEvent方法。Serial Event有以下幾種
類型:
BI - 通訊中斷.
CD - 偵測載波.
CTS - 清除發送.
DATA_AVAILABLE - 有資料到達.
DSR - 資料裝置準備好.
FE - 幀錯誤.
OE - 溢位錯誤.
OUTPUT_BUFFER_EMPTY - 輸出緩衝區已清空.
PE - 同位錯.
RI -  響鈴指示.
下面是一個監聽器的樣本,
public void MyPortListener implements SerialPortEventListener
{
public void serialEvent(SerialPortEvent evt)
{
switch (evt.getEventType())
{
case SerialPortEvent.CTS :
System.out.println("CTS event occured.");
break;
case SerialPortEvent.CD :
System.out.println("CD event occured.");
break;
case SerialPortEvent.BI :
System.out.println("BI event occured.");
break;
case SerialPortEvent.DSR :
System.out.println("DSR event occured.");
break;
case SerialPortEvent.FE :
System.out.println("FE event occured.");
break;
case SerialPortEvent.OE :
System.out.println("OE event occured.");
break;
case SerialPortEvent.PE :
System.out.println("PE event occured.");
break;
case SerialPortEvent.RI :
System.out.println("RI event occured.");
break;
case SerialPortEvent.OUTPUT_BUFFER_EMPTY :
System.out.println("OUTPUT_BUFFER_EMPTY event occured.");
break;
case SerialPortEvent.DATA_AVAILABLE :
System.out.println("DATA_AVAILABLE event occured.");
int ch;
StringBuffer buf = new StringBuffer();
InputStream input = serialPort.getInputStream
try {
while ( (ch=input.read()) > 0) {
buf.append((char)ch);
}
System.out.print(buf);
} catch (IOException e) {}
break;
}
}
這個監聽器只是簡單列印每個發生的事件名稱。而對於大多數應用程式來說,通常
關心是DATA_AVAILABLE事件,當資料從外部裝置傳送到連接埠上來時將觸發此事件。此時
就可以使用前面提到過的方法,serialPort.getInputStream()來從InputStream中讀取
資料了。
完整的程式
為節省篇幅,本文只提供了一些代碼片斷來協助讀者來理解Comm API的用法。你可
以從Comm API的開發包中取得完整的可啟動並執行示範程式。請先下載了comm API的開發包
,解壓之後有一個名為Sample的目錄,裡面有幾個示範程式,分別是:
1) BlackBox: A Serial Port BlackBox application.
2) ParallelBlackBox: A Parallel Port BlackBox application
3) SerialDemo: A simpler SerialPort sample application
4) Simple: A very simple comm application
5) NullDriver: A template for driver writers. Can be used as the starting po
int
to write a driver for the Comm API.
6) porting: A template CommPortIdentifier java file for people interested
in porting the Comm API to a new platform.
其中,第1),3),4)是關於rs232通訊的示範程式。而其它的,2)是並行連接埠的示範程式。
5)和6)是開發自己的連接埠驅動程式的模板程式,有興趣的讀者可以自行研究。
 
 
【 在 rj
(rj)
的大作中提到: 】: 看看前幾天我發的 "人氣這麼低,發個javax.comm大家學習一下"
:
:
: Java(tm) communications API用於平台無關的通訊應用程式,如語音信箱,傳真,和電
: 子卡。
: 目錄結構如下:
: .interface javax.comm.CommDriver
: .class javax.comm.CommPort
: class javax.comm.ParallelPort
: class javax.comm.SerialPort
: .................(以下省略)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.