




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、MSComm控件在中文Windows下的通信問題與處理方法摘 要VB 5.0/6.0的MSComm通信控件提供了一系列標(biāo)準(zhǔn)通信命令的接口,它允許建立串口連接,但在實(shí)際通信軟件設(shè)計(jì)過程中,MSComm控件并非像想像中那樣完美和容易控制,特別是在中文Windows下通信時(shí)更會出現(xiàn)問題。本文就MSComm控件在實(shí)際應(yīng)用中可能出現(xiàn)的問題以及編程技巧進(jìn)行探討。關(guān)鍵詞 MsComm控件 串口通信 處理1.MSComm控件的基礎(chǔ)理論一般說來,計(jì)算機(jī)都有一個(gè)或多個(gè)串行端口,它們依次為Com1、Com2、.。這些串口還提供了外部設(shè)備與PC進(jìn)行數(shù)據(jù)傳輸和通信的通道,這些串口在CPU和外設(shè)之間充當(dāng)解釋器的角色。當(dāng)字
2、符數(shù)據(jù)從CPU發(fā)送給外設(shè)時(shí),這些字符數(shù)據(jù)將被轉(zhuǎn)換成串行比特流數(shù)據(jù);當(dāng)接收數(shù)據(jù)時(shí),比特流數(shù)據(jù)被轉(zhuǎn)換為字符數(shù)據(jù)傳遞給CPU。再進(jìn)一步說,在操作系統(tǒng)方面,Windows用通信驅(qū)動程序(COMM.DRV)調(diào)用API函數(shù)發(fā)送和接收數(shù)據(jù)。當(dāng)用通信控件或聲明調(diào)用API函數(shù)時(shí),它們由COMM.DRV解釋并傳遞給設(shè)備驅(qū)動程序。作為一個(gè)VB程序員,要編寫通信程序,只需知道通信控件提供給Windows通信API函數(shù)的接口即可,換句話說,只需設(shè)定和監(jiān)視通信控件的屬性和事件即可。2.利用MSComm控件進(jìn)行數(shù)據(jù)的接收和發(fā)送搞清楚以上基本屬性和事件后就可以開始編寫通信程序了:在VB 5.0/6.0中新建一個(gè)工程文件,添加
3、Microsoft Comm control 5.0組件,在窗體Form1中加入Command命令按鈕并取名為cmdTest,MSComm控件取名為MSComm1,寫入以下代碼:Private Sub cmdTest_Click() MSComm1.CommPort = 1 '設(shè)定Com1口 If MSComm1.PortOpen = False Then MSComm1.Settings = "9600,N,8,1" '9600波特率,無校驗(yàn),8位數(shù)據(jù)位,1位停止位 MSComm1.PortOpen = True '打開串口 End If MSCo
4、mm1.OutBufferCount = 0 '清空發(fā)送緩沖區(qū) MSComm1.InBufferCount = 0 '清空接收緩沖區(qū) '發(fā)送字符數(shù)據(jù),注意必須用回車符(vbCr)結(jié)束 MSComm1.Output="This is a good book!" & vbCr '撥打電話號碼或發(fā)送AT命令 MSComm1.Output="ATDT 0294563622" & vbCr '發(fā)送字符數(shù)組數(shù)據(jù),注意ByteArray必須事先定義賦值 Dim ByteArray as byte(
5、) '定義動態(tài)數(shù)組 ReDim ByteArray(1) '重定義數(shù)組大小 ByteArray(0)=0 ByteArray(1)=1 MSComm1.Output = ByteArray '發(fā)送字符數(shù)組數(shù)據(jù) End Sub Private Sub MSComm1_OnComm() Select Case MSComm1.CommEvent Case comEvReceive '接收字符數(shù)據(jù) Dim Buffer As Variant MSComm1.InputLen = 0 '當(dāng)InputMode 屬性值為0(文本模式)時(shí),變量中含String型數(shù)據(jù)。
6、'當(dāng)InputMode屬性值為1(二進(jìn)制模式)時(shí),變量中含Byte型數(shù)組數(shù)據(jù)。 MSComm1.InputMode=comInputModeBinary Buffer=MSComm1.Input '接收二進(jìn)制數(shù)據(jù) MSComm1.InputMode=comInputModeText Buffer = MSComm1.Input Case else End Select End Sub 3.中文Windows下的通信問題與解決方法 3.1 接收的數(shù)據(jù)少于發(fā)送的數(shù)據(jù) 如果通過MSComm控件一次性傳送較多的二進(jìn)制數(shù)據(jù),那么,很可能收到的數(shù)據(jù)不足。例如在設(shè)置為2400bps傳輸率的情
7、況下,一次性可以傳輸2048個(gè)字符數(shù)據(jù),那么在大多數(shù)情況下一次只能收到1200個(gè)字符左右,這是因?yàn)樾掳娴腗SComm32.OCX中存在一個(gè)影響傳輸二進(jìn)制數(shù)據(jù)的Bug。 32位Windows API函數(shù)使用了幾個(gè)用COMMTIMEOUTS結(jié)構(gòu)表示的限時(shí)變量,WriteTotalTimeOutConstant即是其中的一個(gè),它被Windows內(nèi)部設(shè)定為5000(即5秒),這個(gè)常量決定了在通信驅(qū)動程序停止傳輸之前花費(fèi)在發(fā)送緩沖區(qū)中數(shù)據(jù)的時(shí)間的長短。5秒鐘意味著通信速度為1200bps情況下僅能發(fā)送600個(gè)字符,2400bps情況下僅能發(fā)送1200個(gè)左右的字符。事實(shí)上,在一個(gè)緩沖區(qū)內(nèi)一次性發(fā)送更多的數(shù)
8、據(jù)是非??赡艿?。VB 5.0/6.0版本的MSComm控件有一個(gè)新增的重要的屬性稱為CommID,CommID指的是當(dāng)串口被打開時(shí),被API所調(diào)用的串口句柄(或標(biāo)志),這也意味著能利用API接口函數(shù)去修改這個(gè)常量。每次串口關(guān)閉后,Windows會自動將之恢復(fù)為5000,所以,每次打開串口后需要重新設(shè)定。以下是API聲明代碼: Type COMMTIMEOUTS ReadIntervalTimeout As LongReadTotalTimeoutMultiplier As Long ReadTotalTimeoutConstant As Long WriteTotalTimeoutMultip
9、lier As Long WriteTotalTimeoutConstant As Long End Type Declare Function SetCommTimeouts Lib "Kernel32" (ByVal h Long , _lpCommTimeouts As COMMTIMEOUTS) As Long Declare Function GetCommTimeouts Lib "Kernel32" (ByVal h Long , _lpCommTimeouts As COMMTIMEOUTS) As Long Dim timeouts A
10、s COMMTIMEOUTS Dim Ret As Long If Comm1.PortOpen = False Then Comm1.PortOpen = True End If '打開串口后重新設(shè)定串口句柄 Ret=GetCommTimeouts(Comm1.CommID,timeouts) 'Set some default timeouts timeouts.ReadIntervalTimeout = 1 timeouts.ReadTotalTimeoutMultiplier = 1 timeouts.ReadTotalTimeoutConstant = 1 timeo
11、uts.WriteTotalTimeoutMultiplier = 1 timeouts.WriteTotalTimeoutConstant=(Comm1.OutBufferSize Val(Comm1.Settings)*10000+1000 Ret=SetCommTimeouts(Comm1.CommID,timeouts) 3.2 如何發(fā)送大于128的字符數(shù)據(jù) 在通信程序中,以單字符方式逐個(gè)發(fā)送數(shù)據(jù)時(shí),每一個(gè)數(shù)據(jù)范圍為0-255(即十六進(jìn)制的00-FF)。在單字符版本的英文Windows或DOS版的BASIC程序中,只需要將相應(yīng)的數(shù)據(jù)轉(zhuǎn)換成相應(yīng)的字符發(fā)送到通信端口即可。但在中文Windo
12、ws下卻行不通,假設(shè)在中文Windows下運(yùn)行以下程序: Dim i as Integer For i = 0 To 255 MSComm1.Output = chr(i) Next i希望在接收端得到預(yù)期的0-255之間的數(shù)據(jù),結(jié)果卻是:前129個(gè)數(shù)據(jù)接收正確,為0-128,后面127個(gè)數(shù)據(jù)為126個(gè)0和一個(gè)255。造成這種結(jié)果的原因在于中文Windows使用的是雙字節(jié)字符集(DBCS)系統(tǒng)。DBCS系統(tǒng)使用0-128之間的數(shù)字表示ASCII字符,大于128的數(shù)字僅作為前導(dǎo)字符,它只是顯示是一個(gè)非拉丁語系的字符,而并不代表實(shí)際意義。上述程序在調(diào)用CHR()函數(shù)時(shí)用到了DBCS字符集,因此產(chǎn)生
13、了此類錯(cuò)誤。那么,如何發(fā)送大于128的數(shù)據(jù)呢?答案是使用字節(jié)數(shù)組,將以上程序改為: Dim MyData(255) As Byte For i = 0 To 255 MyData(i) = i Next i MSComm1.Output = MyData Do DoEvents Loop Until MSComm1.OutBufferCount = 0 '接收過程 Private Sub MSComm1_OnComm() Select Case MSComm1.CommEvent Case comEvReceive Dim Buffer As Variant MSComm1.Input
14、Mode = comInputModeBinary MSComm1.InputLen = 0 Buffer = MSComm1.Input For i=LBound(Buffer) To UBound(Buffer) Text1.Text= Buffer(i); Next i Case ElseEnd Select End Sub3.3 如何發(fā)送中文字符串VB 5.0/6.0中可以直接把中文字符等同于英文字符發(fā)送,如:MSComm1.output="現(xiàn)在發(fā)送中文數(shù)據(jù)!",但這種方法發(fā)送的中文數(shù)據(jù)不能太長,發(fā)送緩沖區(qū)和接收緩沖區(qū)的大小需設(shè)定為中文字符的兩倍以上,而且發(fā)送與接收
15、系統(tǒng)所處的操作系統(tǒng)版本最好要一致,否則會出現(xiàn)接收或發(fā)送緩沖區(qū)溢出之類的錯(cuò)誤。這種方法可用于一般要求不太高的場合。除了上述方法外,還可以采用間接方式發(fā)送中文字符串。在發(fā)送端將漢字或字符轉(zhuǎn)換為機(jī)器內(nèi)碼或區(qū)位碼數(shù)據(jù)數(shù)組,然后將轉(zhuǎn)換后的數(shù)據(jù)發(fā)送到串口,在接收端接收到數(shù)據(jù)后,按照相反的順序?qū)⒌玫降臄?shù)據(jù)轉(zhuǎn)換為相應(yīng)的漢字或字符。在轉(zhuǎn)換過程中,要用到位運(yùn)算,如取得漢字的內(nèi)碼后需要將高字節(jié)和低字節(jié)分開,而VB 5.0/6.0中并沒有提供此類函數(shù),以下是求整數(shù)高、低字節(jié)的函數(shù)。 Public Function HiByte(a As Integer) Dim b As Integer b = a And &
16、;amp;HFF00 b = b / 256 If b < 0 Then b = b + 256 HiByte = b End Function Public Function LowByte(a As Integer) Dim b As Integer b = a And &HFF LowByte = b End Function 3.4如何在通信過程中進(jìn)行延時(shí) 在某些通信過程中,常常需要在發(fā)送完一組數(shù)據(jù)后進(jìn)行一段延時(shí),以等待對方處理上組數(shù)據(jù),以下是延時(shí)函數(shù)代碼。 Public Sub Delay(PauseTime As Single) Dim Start Start = Timer '設(shè)定開始時(shí)間 Do While Timer < Start + PauseTime DoEvents Loop End Sub 4.結(jié)束語隨著計(jì)算機(jī)應(yīng)用領(lǐng)域的不斷擴(kuò)展,計(jì)算機(jī)之間的遠(yuǎn)程通信用得也越來越廣泛。作為RAD開發(fā)工具代表的Visual Basic同樣提供了一系列標(biāo)準(zhǔn)通信命令的接口,它允
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 政策工具的多樣性與選擇研究試題及答案
- 西方政治與社會政策的調(diào)整策略試題及答案
- 2025年飲料行業(yè)新型甜味劑在低糖咖啡飲料中的應(yīng)用與法規(guī)合規(guī)性研究報(bào)告
- 提升軟件設(shè)計(jì)師考試成績的試題及答案
- 信息系統(tǒng)項(xiàng)目管理的績效評價(jià)體系探討試題及答案
- 2025年軟件設(shè)計(jì)行業(yè)挑戰(zhàn)及應(yīng)對策略與試題答案
- 西方公共政策與社會福利試題及答案
- 設(shè)計(jì)模式在軟件設(shè)計(jì)師考試中的試題及答案
- 液壓傳動系統(tǒng)試題及答案回顧
- 項(xiàng)目成功評估與指標(biāo)試題及答案
- 2025年吉林省時(shí)事政治考試試卷帶解析及答案(必背)
- 2024年江蘇省武進(jìn)市事業(yè)單位公開招聘醫(yī)療衛(wèi)生崗考前沖刺模擬帶答案
- 2025屆陜西省高三新高考全真模擬政治試題(原卷版+解析版)
- 南京2025年南京市市場監(jiān)督管理局所屬事業(yè)單位招聘編外筆試歷年參考題庫附帶答案詳解
- 2025貴州中考:政治必考知識點(diǎn)
- 心率變異性與情緒狀態(tài)的相關(guān)性-洞察闡釋
- 新質(zhì)生產(chǎn)力下產(chǎn)教協(xié)同下的智能會計(jì)人才培養(yǎng)模式研究
- 2025-2030中國再生纖維行業(yè)市場發(fā)展現(xiàn)狀及競爭策略與投資前景研究報(bào)告
- 2025屆湖北省示范中學(xué)高考沖刺押題(最后一卷)英語試卷含答案
- 智能機(jī)器人技術(shù)下的智慧校園建設(shè)
- 華電煤業(yè)集團(tuán)有限公司招標(biāo)管理辦法
評論
0/150
提交評論