了解串行通訊 串行通訊協議有很多種
像RS
RS
RS
甚至現今流行的USB等都是串行通訊協議
而串行通訊技術的應用無處不在
可能大家見的最多就是電腦的串口與Modem的通訊
記得在PC機剛開始在中國流行起來時(大約是在
年代前五年)
那時甚至有人用一條串行線進行兩台電腦之間的數據共享
除了這些
手機
PDA
USB鼠標
鍵盤等等都是以串行通訊的方式與電腦連接
而筆者工作性質的關系
所接觸到的就更多了
像多串口卡
各種種類的具有串口通訊接口的檢測與測量儀器
串口通訊的網絡設備等
雖然串行通訊有很多種
但筆者所知的在整個電子通訊產品方面
以RS
的通訊方式最為多見
雖然USB接口的電子產品也是層出不窮
但了解一下Java在串行通訊方面的技術還有有必要的
說不定有哪位讀者還想用此技術寫一個PDA與電腦之間數據共享的程序呢
本文主要以RS
為主來講解JAVA的串行通訊技術
RS通訊基礎 RS
C(又稱 EIA RS
C
以下簡稱RS
)是在
年由美國電子工業協會(EIA)聯合貝爾系統
調制解調器廠家及計算機終端生產廠家共同制定的用於串行通訊的標准
RS
是一個全雙工的通訊協議
它可以同時進行數據接收和發送的工作
RS
的端口通常有兩種
針(DB
)和
針(DB
)
DB
和DB
的常用針腳定義
常見的邊線方式
常見的通訊方式是三線式
這種方式是將兩個RS
設備的發送端(TXD)和接收端(RXD)及接地端(GND)互相連接
也是許多讀者所知道的連接方式
(
針)
(RXD)
(TXD
(TXD)
(TXD)
(GND)
(GND)
(
針)
(RXD)
(TXD
(TXD)
(RXD)
(GND)
(GND)
這種方式分別將兩端的RS
接口的
(
)
(
)針腳連接起來
其中
是數據接收線(RXD)
是數據發送線(TXD)
(
)是接地(RND)
如果有一台式PC
和一部NoteBook電腦
就可以用這種方式連線了
用三線式可以將大多數的RS
設備連接起來
但如果你認死了
(
)
(
)對接這個理
會發現在連某些RS
設備時並不奏效
這是因為有些設備在電路內部已將
和
線調換過來了
你只要
(
)針一一對應就行了
安裝Java Communications API Sun的J
SE中並沒有直接提供以上提到的任何一種串行通訊協議的開發包
而是以獨立的jar包形式發布在網站上(從這裡下載)
即comm
jar
稱之為Javatm Communications API
它是J
SE的標准擴展
comm
jar並不是最近才有
早在
年時
sun就已經發布了這個開發包
comm
jar分別提供了對常用的RS
串行端口和IEEE
並行端口通訊的支持
目前sun發布的comm
jar只有Windows和Solaris平台兩個版本
如果你需要Linux平台下的
可以在找到
在使用comm
jar之前
必須知道如何安裝它
這也是困擾許多初學java RS
通訊者的一個難題
如果我們電腦上安裝了JDK
它將同時為我們安裝一份JRE(Java Runtime Entironment)
通常我們運行程序時都是以JRE來運行的
所以以下的安裝適用於JRE
如果你是用JDK來運行程序的
請將相應的<JRE_HOME>改成<JDK_HOME>
下載了comm
jar開發包後
與之一起的還有兩個重要的文件
win
com
dll和m
properties
comm
jar提供了通訊用的java API
而win
com
dll提供了供comm
jar調用的本地驅動接口
而m
properties是這個驅動的類配置文件
首先將comm
jar復制到<JRE_HOME>\lib\ext目錄
再將win
com
dll復制到你的RS
應用程序運行的目錄
即user
dir
然後將m
properties復制到<JRE_HOME>\lib目錄
通訊前的准備 如果你手頭上沒有現成的提供了標准RS
串口的設備
你可以將自己的電腦模擬成兩台不同的串口設備
通常電腦主機後面的面板提供了兩個
針的串口
請將這兩個串口的
腳按前面介紹的方法連接
電子市場都有現成的連接頭賣
請不要買那種封裝的嚴嚴實實的接頭
而要買用螺絲封裝可以拆開的連接頭
這樣可以方便自己根據需要連接各個針腳
Comm API基礎 我無意於在此詳細描述Comm API每個類和接口的用法
但我會介紹Comm API的類結構和幾個重要的API用法
所有的comm API位於m包下面
從Comm API的javadoc來看
它介紹給我們的只有區區以下
個類或接口
m
CommDriver
m
CommPort
m
ParallelPort
m
SerialPort
m
CommPortIdentifier
m
CommPortOwnershipListener
m
ParallelPortEvent
m
SerialPortEvent
m
ParallelPortEventListener (extends java
util
EventListener)
m
SerialPortEventListener (extends java
util
EventListener)
m
NoSuchPortException
m
PortInUseException
m
UnsupportedCommOperationException
下面講解一下幾個主要類或接口
枚舉出系統所有的RS
端口
在開始使用RS
端口通訊之前
我們想知道系統有哪些端口是可用的
以下代碼列出系統中所有可用的RS
端口:
Enumeration en = CommPortIdentifier
getPortIdentifiers();
CommPortIdentifier portId;
while (en
hasMoreElements())
{
portId = (CommPortIdentifier) en
nextElement();
/*如果端口類型是串口
則打印出其端口信息*/
if (portId
getPortType() == CommPortIdentifier
PORT_SERIAL)
{
System
out
println(portId
getName());
}
}
在我的電腦上以上程序輸出以下結果
COM
COM
CommPortIdentifier類的getPortIdentifiers方法可以找到系統所有的串口
每個串口對應一個CommPortIdentifier類的實例
打開端口
如果你使用端口
必須先打開它
try{
CommPort serialPort = portId
open(
My App
);
/* 從端口中讀取數據*/
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可以獲得端口的輸出流
這樣就可以往串口輸出數據了
關閉端口
使用完的端口
必須記得將其關閉
這樣可以讓其它的程序有機會使用它
不然其它程序使用該端口時可能會拋出端口正在使用中的錯誤
很奇怪的是
CommPortIdentifier類只提供了開啟端口的方法
而要關閉端口
則要調用CommPort類的close()方法
通訊方式 CommPort的輸入流的讀取方式與文件的輸入流有些不一樣
那就是你可能永遠不知這個InputStream何時結束
除非對方的OutputStream向你發送了一個特定數據表示發送結束
你收到這個特定字符後
再行關閉你的InputStream
而comm
jar提供了兩種靈活的方式讓你讀取數據
輪詢方式(Polling)
舉個例子
你同GF相約一起出門去看電影
但你的GF好打扮
這一打扮可能就是半小時甚至一小時以上
這時你就耐不住了
每兩分鐘就催問一次
好了沒?
如此這樣
直到你的GF說OK了才算完
這個就叫輪詢(Polling)
在程序中
輪詢通常設計成一個封閉的循環
當滿足某個條件時即結束循環
剛才那個例子中
你的GF說
OK了!
這個就是結束你輪詢的條件
在單線程的程序中
當循環一直執行某項任務而又無法預知它何時結束時
此時你的程序看起來可能就像死機一樣
在VB程序中
這個問題可以用在循環結構中插入一個doEvent語句來解決
而Java中
最好的方式是使用線程
就像以下代碼片斷一樣
public TestPort extend Thread
{
InputStream input = serialPort
getInputStream();
StringBuffer buf = new StringBuffer();
boolean stopped = false;
From:http://tw.wingwit.com/Article/program/Java/Javascript/201311/25440.html