???????????????由于這幾天要通過(guò)java調(diào)用通過(guò)串口或并口連接的硬件資源,所以我就要用到和底層的硬件進(jìn)行通訊。通過(guò)RS-232的通訊協(xié)議,了解電腦和外設(shè)是怎樣進(jìn)行通訊的。在應(yīng)用中我們也可以通過(guò)JNI來(lái)實(shí)現(xiàn)(詳情請(qǐng)見(jiàn)http://www.aygfsteel.com/hgq0011/archive/2005/09/21/13637.html),這樣的話,就必須知道更多的知識(shí)。由于java已經(jīng)提供我們一個(gè)javacomm20-win32通用的API我們還是實(shí)行 “拿來(lái)主義”吧。我就把整個(gè)應(yīng)用的過(guò)程詳細(xì)的說(shuō)一下,希望給需要的人一點(diǎn)幫助。?
????????????我們經(jīng)過(guò)串口和外設(shè)通訊,下面我就以串口為例進(jìn)行解說(shuō)。?
????????????1)我們要準(zhǔn)備相應(yīng)的設(shè)備。
??????????????????電腦,外設(shè),通過(guò)數(shù)據(jù)線把他們連接起來(lái)。?
????????????2)檢驗(yàn)外設(shè)到底是用的那個(gè)COM口和電腦通訊的。
??????????????????也就是說(shuō),他們有沒(méi)有真確的連接上。我們可以通過(guò)下載串口通訊口測(cè)試軟件,我用的是"SuperCommTool.exe"的綠色軟件,進(jìn)行測(cè)試的。這軟件很適應(yīng),如果選中的某個(gè)COM已經(jīng)被使用了,它會(huì)給你一個(gè)相應(yīng)的提示(端口以被占用)。如果你不知道到底是使用的那個(gè)端口,那么你可以通過(guò)superCommTool軟件一個(gè)一個(gè)的試,如果正常的話,那么你可以看到有數(shù)據(jù)顯示在數(shù)據(jù)接收窗口。也許,有些主板的串口壞了,那么你就要買(mǎi)一個(gè)轉(zhuǎn)接卡,通過(guò)PCI插口轉(zhuǎn)接。?
????????????3)察看外設(shè)使用說(shuō)明書(shū)知道外設(shè)的相關(guān)參數(shù)。
???????????????比如,波特率,數(shù)據(jù)位,停止位,校驗(yàn)位,等等。只有正確參數(shù),才能顯示正確的數(shù)據(jù)。當(dāng)然,你可以在通訊測(cè)試軟件上調(diào)試這些參數(shù)的。比如:波特率 = 2400,數(shù)據(jù)位 = 8,停止位 = 2 ,校驗(yàn)位 = 1。?
????????????4)準(zhǔn)備開(kāi)發(fā)環(huán)境。
????????????最基本的JDK了,你可以使用自己鐘愛(ài)的IDE,幫助你開(kāi)發(fā)。IDE可能自帶了JDK,那么 你要把相應(yīng)的javaComm20-win32放到運(yùn)行時(shí)使用的JDK中。 下載JAVAcomm20-win32。
??????????5)了解javaComm20-win32。
????????????你必須把win32com.dll復(fù)制到j(luò)ava.home/bin下;把javax.comm.properties 復(fù)制到j(luò)ava.home/lib下;把comm.jar添加到你classPath下。前面兩個(gè)都是非常重要的。?
?????????????下面說(shuō)明用到的幾個(gè)類(lèi):?
??????????????????javax.comm.CommPortIdentifier?
?????????????????????通訊端口管理器,CommPortIdentifier是控制訪問(wèn)到通訊端口的中 心類(lèi)。
?????????????????????它包括的方法有:?
???????????????????????????a. 通過(guò)驅(qū)動(dòng)決定通訊端口是可用的。?
???????????????????????????b. 打開(kāi)通訊端口為了I/O操作。?
???????????????????????????c. 決定端口的擁有者。?
???????????????????????????d. 解析端口擁有者的爭(zhēng)奪。?
???????????????????????????e. 管理事件顯示在端口擁有者的中的狀態(tài)改變。?
?????????????????????一個(gè)應(yīng)用程序首先使用CommPortIdentifier中的方法,通過(guò)相關(guān)的驅(qū)動(dòng)去獲取那些通訊端口是可用的 并且選擇一個(gè)端口便于開(kāi)始。然后它使用方法在其它類(lèi)中想CommPort,ParallelPort和SerialPort通過(guò) 這個(gè)端口進(jìn)行通訊。?
??????????????????javax.comm.SerialPort?
?????????????????????一個(gè)RS-232串口通訊端口。SerialPort 描述底層的接口到一個(gè)串口通訊端口 變得有效的通過(guò)底層的系統(tǒng)。SerialPort定義最小的必需的功能便于串口通訊端口。?
??????????????????javax.comm.SerialPortEventListener?
?????????????????????串行端口事件傳播。?
??????????????????javax.comm.CommDriver?
?????????6)代碼的編寫(xiě)。?
???????????????a. 獲取SerialPort sPort對(duì)象的兩種方法。
???????????????????1)
???????????????????????????
System.loadLibrary("win32com");?
??????????????????????????????javax.comm.CommDriver?driver?=?null;?
??????????????????????????????String?driverName?=?"com.sun.comm.Win32Driver";?
????????????????????????????? SerialPort?sPort?=?(SerialPort)?driver.getCommPort("COM4",?CommPortIdentifier.PORT_SERIAL);?

??????????????????2)
??????????????????????????????javax.comm.CommDriver?driver?=?null;?
??????????????????????????????String?driverName?=?"com.sun.comm.Win32Driver";?
????????????????????????????? SerialPort?sPort?=?(SerialPort)?driver.getCommPort("COM4",?CommPortIdentifier.PORT_SERIAL);?


?????????????????????????? SerialPort?sPort?=?(SerialPort)portId.open("shipment",1000);
?????????????以上兩種方法都可以。不過(guò)一般都會(huì)采用第二種。方法說(shuō)明我們獲取了對(duì)串行端口(COM4),可以和它進(jìn)行通訊了。?
??????????????b. 設(shè)置串行端口通訊參數(shù)。

???????????????c. 獲取輸入(出)流。?
??????????????????

?????????????? OutputStream?os?=?sPort.getOutputStream();//發(fā)送命令到外設(shè)

??????????????????
?1
//Set?notifyOnDataAvailable?to?true?to?allow?event?driven?input.
?2
????????????sPort.notifyOnDataAvailable(true);
?3
?4
?????????????//?Set?notifyOnBreakInterrup?to?allow?event?driven?break?handling.
?5
????????????sPort.notifyOnBreakInterrupt(true);
?6
?7
?????????????//?Set?receive?timeout?to?allow?breaking?out?of?polling?loop?during??input?handling.
?8
????????????sPort.enableReceiveTimeout(30);
?9
????????????StringBuffer?linkWgt?=?new?StringBuffer();//存放獲取的數(shù)據(jù)
10
????????????sPort.addEventListener(?
11
????????????????new?SerialPortEventListener(){
12
????????????????????public?void?serialEvent(SerialPortEvent?e){
13
????????????????????????int?newData?=?0;
14
????????????????????????//?Determine?type?of?event.
15
????????????????????????switch?(e.getEventType())?{
16
????????????????????????//?Read?data?until?-1?is?returned.?If?\r?is?received?substitute
17
????????????????????????????//?\n?for?correct?newline?handling.
18
????????????????????????????case?SerialPortEvent.DATA_AVAILABLE:
19
????????????????????????????????while?(newData?!=?-1)?{
20
????????????????????????????????????try?{
21
????????????????????????????????????????newData?=?is.read();
22
????????????????????????????????????????if?(newData?==?-1)?{
23
????????????????????????????????????????????break;
24
????????????????????????????????????????}
25
????????????????????????????????????????if?('\r'?==?(char)newData)?{
26
????????????????????????????????????????}?else?{
27
????????????????????????????????????????????linkWgt.append((char)newData);
28
????????????????????????????????????????}
29
????????????????????????????????????}?catch?(IOException?ex)?{
30
????????????????????????????????????????System.err.println(ex);
31
????????????????????????????????????????return;
32
????????????????????????????????????}
33
????????????????????????????????}
34
35
????????????????????????????//?Append?received?data?to?messageAreaIn.
36
????????????????????????????
37
?????????????????????????????try{
38
????????????????????????????????System.out.println("linkWgt?---------|||||??????????"+Double.valueOf(linkWgt.toString()));
39
????????????????????????????????
40
?????????????????????????????}catch(Exception?ew){
41
?????????????????????????????????ew.printStackTrace();
42
?????????????????????????????}finally{
43
?????????????????????????????????try{
44
????????????????????????????????????//用完了,記得關(guān)閉端口。
45
?????????????????????????????????????is.close();
46
????????????????????????????????????sPort.close();
47
?????????????????????????????????}catch(Exception?c){
48
?????????????????????????????????????c.printStackTrace();
49
?????????????????????????????????}
50
?????????????????????????????}
51
????????????????????????????break;
52
????????????????????????????//?If?break?event?append?BREAK?RECEIVED?message.
53
????????????????????????????case?SerialPortEvent.BI:
54
????????????????????????????????System.out.println("\n---?BREAK?RECEIVED?---\n");
55
????????????????????????}
56
????????????????????}
57
58
????????????????}
59
????????????);

?2

?3

?4

?5

?6

?7

?8

?9

10

11


12


13

14

15


16

17

18

19


20


21

22


23

24

25


26


27

28

29


30

31

32

33

34

35

36

37


38

39

40


41

42


43


44

45

46

47


48

49

50

51

52

53

54

55

56

57

58

59

??????????7)常見(jiàn)的異常
????????????????a. javax.comm.NoSuchPortException 這個(gè)說(shuō)明你的javax.comm.properties沒(méi)有放到正確的位置。
?如果有什么不正確的地方,歡迎批評(píng)指正,謝謝!