隨著Windows在國內的普及,特別是Windows95的推出,越來越多的微機使用者轉向了Windows作業系統。不過Windows應用軟體的開發對於一般工程技術領域的技術人員來說並非易事,不但Windows的訊息迴圈機制不易理解,而且要開發一個功能強、介面美觀的應用軟體,其編程和調試的工作量是非常大的。許多並非搞軟體出身的工程技術人員對Windows編程望而生畏。然而使用微軟的VisualBasic來開發這些方面的Windows應用軟體就十分方便,一般工程技術人員易於掌握,設計軟體介面非常方便,編程工作量相對較小,只需進行主要應用功能的編程和少量介面控制的編程。本文介紹了筆者使用VB在串列通訊編程方面的一些收穫,由於在報刊雜誌上對Windows下串列通訊編程的介紹多為用MicrosoftC++或BorlandC++,故筆者願意就VB在該方面的應用與大家探討。對於採用了RS-232介面進行串列通訊的電腦測控系統軟體的開發,具有一定的參考價值。
在該系統中使用了80C31單片機作為下位機採集慣性敏感組件的測量資料,經過一定的預先處理後通過RS-232串列口將資料傳送給上位PC機。在PC機上Windows環境下運行檢測軟體,接受串列口傳來的資料,進行資料處理、顯示、存檔等。資料處理結果以表格形式列印輸出。
在VB3.0中,有許多專業廠商提供使用者定製的控制項(Customcontrol),這些控制項以.VBX為尾碼,其中MSCOMM.VBX即是用於串列通訊的控制項。對於VB3.0,啟動後該控制項就包含於控制項工具箱(toolbox)內,否則可以通過File|AddFile將該控制項加入控制項工具箱。然後就可以利用該控制項進行串列通訊的程式設計。
下面舉一個簡單的例子,說明了如何進行串列通訊的程式設計,該程式在Windows95環境下,使用VB3.0已經實現:
1.先建立一個專案檔,其控制項如下表所示:
2.代碼如下:
SubForm_Load()
comm1.CommPort=1‘使用串列口1
'傳輸速率9600,偶校正,8個資料位元,1個停止位。
comm1.Settings=“9600,E,8,1”
當使用Comm1.Input時,每次從接收緩衝區取一個位元組。
comm1.InputLen=1
timer1.interval=20‘定時器的中斷間隔為20ms,用於更新顯示時間。
EndSub
SubcmdComm_Click()
Dimechoch%‘命令變數
Staticmaxf01&,maxf02&,minf01&,minf02&‘最大值,最小值
OnErrorResumeNext‘簡單的錯誤處理
maxf01&=maxf02&=0‘初始設定變數
minf01&=32767
minf02&=32767
label2.Caption=comm1.Settings‘顯示串列口的設定。
Ifcmdcomm.Caption=“通訊”Then‘若當前命令按扭的提示為“通訊”則開始發送和
cmdcomm.Caption=“停止”‘接受資料,並將命令按扭提示改為“停止”,以
cmdexit.Enabled=False‘允許停止通訊。使退出命令在通訊中失效。
IfNotcomm1.PortOpenThen‘若串列口沒有開啟,則開啟串列口
comm1.PortOpen=True
EndIf
Ifcomm1.PortOpenThen
Ifecho.Text<>“”Then‘若命令輸入框不空,則將其轉換為十六進位數值
echoch%=Val(“&H”+echo.Text)
Else
echoch%=&HF0‘否則確省命令為F0H
EndIf
comm1.Output=Chr(echoch%)‘向串列口寫入一位元組命令,由WINDOWS自
EndIf‘動將命令發出
label3.Caption=Hex(echoch%)‘顯示剛發出的命令
DoWhilecomm1.PortOpen
Ifcomm1.InBufferCount>0Then‘若comm1.InBufferCount>0表示接受緩衝
ch$=comm1.Input‘區有資料,並讀出一個字元,
IfAsc(ch$)=echoch%Then‘若與發出的命令相同,則退出當前迴圈
ExitDo‘進入下一迴圈
EndIf
Else
comm1.Output=Chr(echoch%)‘否則繼續向下位機發命令,通知下位機
EndIf‘送資料
dummy=DoEvents()‘讓系統處理其他訊息
Loop
‘下位機接受到正確的命令,並回傳命令正確時,進入下面迴圈
i=1
DoWhilecomm1.PortOpen
Ifcomm1.InBufferCount>5Then
ch$=comm1.Input
DoWhileAsc(ch$)<>echoch%‘以命令位元組同步測試資料
ch$=comm1.Input
Loop
ch1$=comm1.Input‘從WINDOWS串列資料接受緩衝區讀測試資料
ch2$=comm1.Input
ch3$=comm1.Input
ch4$=comm1.Input
newf01&=CLng(CLng(Asc(ch2$))*16*16+Asc(ch1$))‘合并為一個整數
newf02&=CLng(CLng(Asc(ch4$))*16*16+Asc(ch3$))
ifnewf01&>maxf01&Then‘判斷最大值,最小值
maxf01&=newf01&
EndIf
Ifnewf01&<minf01&Then
minf01&=newf01&
EndIf
Ifnewf02&>maxf02&Then
maxf02&=newf02&
EndIf
Ifnewf02&<minf02&Then
minf02&=newf02&
EndIf
labf01.Caption=Str(newf01&)‘顯示資料
labf02.Caption=Str(newf02&)
labmaxf01.Caption=Str(maxf01&)
labminf01.Caption=Str(minf01&)
labmaxf02.Caption=Str(maxf02&)
labminf02.Caption=Str(minf02&)
Else
comm1.Output=Chr(echoch%)
EndIf
dummy=DoEvents()
Loop
Else‘在通訊過程中,按下cmdCOMM按鈕則停止通訊,發出停止測試
cmdcomm.Caption=“通訊”‘命令,關閉串列口,使退出按鈕有效。
comm1.Output=Chr(&H5F)
comm1.PortOpen=False
cmdexit.Enabled=True
EndIf
EndSub
SubcmdExit_Click()
Ifcomm1.PortOpenThen‘確認關閉串列口
comm1.PortOpen=False
EndIf
End‘終止整個程式
EndSub
SubTimer1_Timer()‘更新顯示時間
Iflabtime.Caption<>Time&Then
labtime.Caption=Time$
EndIf
EndSub
3.程式說明:
a.上述程式的通訊協定為:傳輸速率9600,偶校正,8個資料位元,1個停止位。由上位機發送開始測試命令,下位機接收到命令後每隔500ms向上位機發送檢測到的資料。每次發送5個位元組,第一個位元組為下位機接受到的命令,第二三位元組為16Byte的值,第四五位元組為16Byte的值。上位機迴圈接受並處理和顯示資料;
b.由於在控制軟體中,串列通訊發送和接受的資料多為十六進位,故在命令輸入時為十六進位數,在程式中通過echoch%=Val(“&H”+echo.Text)將輸入的echo.Text轉換為十六進位數,並賦給變數echoch%。而在通過串列口發送時comm1.Output要求接受字元型變數,故通過語句comm1.Output=Chr(echoch%)實現;
c.接受資料時,每次要判斷第一個位元組是否為發出的命令,只有是後面4個位元組才為正確的資料,否則查看下一位元組。通過設定COMM1.InputLen=1來實現每次從接受緩衝區內讀取一個位元組;
d.當退出程式時,一定要關閉串列口,通過comm1.PortOpen=False完成;
e.如果需要上位機定時查詢下位機,可以將串列通訊在定時器Timer1-Timer事件中進行;
f.要實現完善的功能,必須進一步改善程式,甚至要用到WindowsAPI、OLE等,上述程式只是一個簡單的例子;
上面介紹了筆者在使用VB開發Windows環境下測控軟體的一點收穫,筆者使用上述原理開發了一個介面友好、功能全面、使用方便的衛星控制系統慣性敏感組件檢測軟體,實際使用效果良好,提高了工作效率,甚至實現了測試和資料處理的自動化。