vb開發通訊軟體 (轉)

worldblog發表於2007-12-04
vb開發通訊軟體 (轉)[@more@]vb開發通訊

一、PC通訊機制
常用的PC序列通訊程式大多利用INT14H中斷,以查詢I/O方式完成非同步序列通訊。

提供中斷方式的序列通訊驅動程式COMM.DRV。通訊程式無需直接對串列埠進行操作,而是透過驅動程式這一介面進行間接操作。

Windows中,序列通訊採用“事件通知”方式,支援資料按塊傳送。進行通訊時,Windows開闢一個定義的輸入輸出緩衝區,每接收一個字元就產生一個低階中斷,序列驅動程式立即取得控制權,並將字元放入輸入資料緩衝區,然後將控制權返還正在執行的應用程式。如果輸入資料緩衝區滿了,驅動程式用當前定義的流控制機制通知傳送方停止傳送資料。傳送資料也採用類似的處理方式,應用程式將需要傳送的資料放入輸出資料緩衝區,串列埠每傳送一個字元就產生一個低階硬體中斷。

二、PC序列口通訊的硬體

序列通訊資料鏈中,一端稱為DTE,即資料終端裝置;調變解調器一端稱為DCE,即資料通訊裝置。PC序列通訊的硬體連線方式分為零Modem連線和Modem連線。

零Modem連線即直接用調變解調器電纜將兩臺裝置連線起來,Modem連線則透過DCE(Modem)將兩臺PC連線起來。

零Modem連線用於距離15m內兩臺DTE或DCE裝置之間的連線。而Modem連線則透過電話網或專線用於長距離的通訊。

TXD和RXD訊號線用於計算機和Modem間傳輸資料資訊;RTS從計算機端傳送訊號到Modem,表示希望把資料傳給Modem,若Modem能接收這個資料,它將傳送CTS訊號給計算機;DTR從計算機端傳送訊號到Modem,表示計算機已作好通訊準備,Modem將DTR訊號作為初始化自己的訊號,然後給計算機回送資料設定就緒訊號DSR;當本地Modem接收到遠地Modem的呼叫,則傳送RING訊號給計算機;Modem應答呼叫後,傳送資料載波檢測DCD訊號到計算機,表示已建立連線。

Modem的工作狀態分為命令狀態和線上狀態。處於命令狀態時,Modem對串列埠傳送的資訊進行解釋,可透過PC串列埠向Modem傳送AT命令對其進行初始化、設定和操作。

例如,初始化命令為:“ATQOV1WOSOΚ1&C1&D2&YO&WO”,其含義為:

QO:返回結果碼;

V1:以字元形式顯示結果碼;

WO:不返回協商程式結果碼;

SOΚ1:振鈴一次,即應答;

&C1:追蹤資料載波訊號CD;

&D2當DTR從開到關時,Modem掛機進入命令狀態;

&YO:Modem上電時重新調出使用者方案;

&WO:將以上設定存為動態設定使用者方案0;

一旦本地Modem與遠地Modem建立連線,Modem即處於線上狀態,可進行資料傳輸。此時,Modem不響應AT命令,直接傳送所收到的資料。

三、Modem連線遠端通訊軟體的編制

通訊過程中大部分的工作由序列通訊驅動軟體承擔。

本文軟體的執行環境為AST+4/66d,Hayes公司的ACCURA144+FAX144Modem,Windows3.2,VB3.0專業版。VB3.0專業版中提供了一個MMM.VBX通訊。它使使用者能很方便地透過對控制元件屬性的設定、檢測,訪問序列通訊驅動程式的大多數特性,而不必考慮其實現細節。該控制元件為“事件驅動”,只響應“OnComm”事件,該事件可對已發生的事件或錯誤進行處理,與CommEvent屬性緊密相關。

通訊軟體、通訊驅動軟體和Modem之間的通訊關係

以下程式實現了通訊的基本過程。包括初始化串列埠和Modem,上位機撥號呼叫下位機,下位機應答並開始定時傳輸資料,掛機停止傳輸等功能。

VB3.0編制的通訊軟體清單如下:

上位機控制元件清單:

控制元件名稱 屬性

Form1Form1Caption ″上位機通訊″

MsComm comm1

Commanutton1CallCaption ″撥號″

CommandButton2hangCaption ″掛機″

CommandButton3ExitCaption ″退出″

下位機控制元件清單

控制元件名稱 屬性

Form1Form1Caption ″下位機通訊″

MsComm comm1

CommandButton1hangCaption ″掛機″

CommandButton2ExitCaption ″退出″

Timer1Timer1Interval 3000

Text(i)Text(i)

1.串列埠初始化、設定程式

在程式初始化時,先對串列埠初始化。因為使用RTS/CTS握手訊號的硬體裝置只有RTS訊號置為高才能接收資料,所以需將MSCOMM通訊控制元件的RTSenable屬性設為TRUE。由於Modem在處於命令狀態時,透過串列埠傳送的命令以及命令結果均會回顯在輸入緩衝區中,因此在進入線上狀態前,禁止產生EV-RECEIVE事件,避免資料誤處理。

由於Windows是多工系統,在進行資料收發迴圈處理時,應DOEVENTS事件,將控制權交還系統,允許Windows其他任務。但應注意,在處理OnComm事件時小心使用DOEVENTS,避免系統又產生OnComm事件,造成巢狀,出現堆疊錯誤。

Sub Form-Load()

comm1.CommportΚ1′COM1口通訊

comm1.SettingsΚ″9600,N,8,1″′波特率9600,無校驗,8位資料位1位停止位

comm1.OutBufferSizeΚOUTPACK′設定輸出緩衝區大小

comm1.InBufferSizeΚINPACK′設定輸入緩衝區大小

comm1.InputLenΚ1′每次從輸入緩衝區中取一個字元

comm1.RTSenableΚ-1′RTS訊號為高

comm1.RthresholdΚ0′不產生MSCOMM-EV-RECEIVE事件

comm1.PortOpenΚ-1′開啟串列埠

cdΚcomm1.CDHolding′取載波檢測訊號線原始狀態

comm1.outputΚ″ATQOV1WOSOΚ1&C1&D2&YOWO″′初始化Modem

Do DoEventsLUntilcomm1.OutBufferCountΚ0

End Sub

2.上位機撥號呼叫下位機

SubCallcom-Click()

Comm1.OutPutΚ″ATDT″&Phonnum$&chr$(13)′向Modem發撥號命令

Do DoEventsLoopUntilcomm1.OutBufferCountΚ0

End Sub

3.下位機Modem應答,連通後開始定時傳輸資料

下位機檢測CD,判斷是否連通:

Sub Comm1-OnComm()

Casecomm1.CommEvent

Case5 ′MSCOMM-EV-CD

Timer1.EnabledΚ-1′啟動定時器

End Select

End Sub

VB傳送定長字串,資料接收處理相對簡單。但在傳送實時資料時,若將資料轉換成定長字串,這樣會大大降低傳輸。在接收端,通知程式從輸入緩衝區中取字元有兩種方法:一是用輪詢方法迴圈判斷InBufferCount是否為0;另外就是利用Rthreshold屬性觸發“OnComm”事件及“CommEvent”屬性中EV-RECEIVE事件。當Rthreshold的值不為0時,允許產生EV-RECEIVE事件。該屬性設定和返回在通訊控制元件設定CommEvent特性為接收和產生OnComm事件之前要接收的字元數。VB傳送變長字串時,接收端的Rthreshold值要作相應的改變,以確保接收資料及時準確。

下位機定時傳送字串“strin3$ΚFormat$(Len(strin1$),″0000″)&chr$(8)&strin2$”。strin1$為當前字串,strin2$為上一字串。上位機根據接收strin3$中Len(strin1$),相應改變RthresholdΚLen(strin1$)+4。這樣,透過提前傳送字串長度,改變Rthreshold值可實現傳送變長資料。

Windows序列通訊驅動程式的事件驅動特性仍有不穩定的缺陷。如InputLenΚ0時,有可能取出不完整的資料。為保證可靠,採取降低處理速率的方法,保證下位機傳送的資料流完整地進入輸入緩衝區。設InputLenΚ1,即每次從緩衝區中取一個字元。也可採用輪詢方法,定時檢測輸入緩衝區。下位機定時傳送資料:

Sub Timer1-Timer()

If comm1.CDHoldingΙΛcdThen

str1$-text1(i).Text

strin2$Κstrin1$′上一字串

strin1$Κstr1$′當前字串

strin3$ΚFormat$(Len(strin1$),″0000″)&chr$(8)&strin2$

′傳送當前字串長度,以及上一字串內容

m1.OutPutΚstrin3$

Do DoEventsLoopUntilcomm1.OutBufferCountΚ0

Else

Timer1.EnabledΚ0

End If

End Sub

上位機檢測CD狀態,判斷是否連通、並接收處理資料。

Sub Comm1-OnComm()

Select Case comm1.CommEvent

Case5 ′MSCOMM-EV-CD檢測CD狀態,判斷是否連通

comm1.InBufferCountΚ0′清輸入緩衝區

comm1.RThresholdΚ4′當輸入緩衝區中有五個字元,

Case2′MSCOMM-EV-RECEIVE產生EV-RECEIVE事件,接收處理資料

Do DoEvents

Ifcomm1.InBufferCountThen′迴圈從緩衝區中取資料

str1$Κstr1$+comm1.Input

Else

Exit Do

End If

Loop

len2Κ1en1′當前字串長度

len1ΚVa1(Left$(str1$,5))′即將傳送的字串長度

comm1.RThresholdΚlen1+4

strin$ΚRight$(str1$,len2)′資料處理

……

End Select

str1$Κ″″

End Sub

4.根據設定的AT命令“&D2”,當置DTR訊號為低時,Modem掛機進入命令狀態。也可透過串列埠輸出““+++ATH”+chr$(13)”字串掛機。

Sub Hang-click()

If comm1.CDHoldingΙΛcdThen′檢測CD,判斷是否掛機

comm1.DTRenableΚ0

comm1.DTRenableΚ-1′置DTR訊號為高,為下一次通訊準備

End If

End Sub

5.退出程式時,一定要關閉串列埠

Sub Exitcomm()

comm1.PortOpenΚfalse

End

End Sub

四、Windows通訊機制和VB3.0通訊控制元件潛在缺陷

在通訊軟體編制過程中,我們發現Windows下通訊機制採用的“事件驅動”在實際執行中不穩定。如在傳輸過程中,誤碼和資料丟失的情況時有發生;若串列埠波特率過高,會產生無法通訊或在通訊過程中隨機掛機的情況。這主要是由於Windows本身通訊機制和通訊線路介質及質量的影響。為保證資料傳輸穩定可靠,可採用通訊如XModem-CRC或YModem。在MSCOMM.VBX通訊控制元件中,Rthreshold屬性值大小與輸入緩衝區InBufferSize大小有關,當Rthreshold值較接近InBufferSize值時,有可能不產生EV-RECEIVE事件,為保證產生該事件,可將InBufferSize值取得較大


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-988312/,如需轉載,請註明出處,否則將追究法律責任。

相關文章