版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
MSComm控件在中文Windows下的通信問題與處理方法
摘要VB5.0/6.0的MSComm通信控件提供了一系列標(biāo)準(zhǔn)通信命令的接口,它允許建立串口連接,但在實(shí)際通信軟件設(shè)計(jì)過程中,MSComm控件并非像想像中那樣完美和容易控制,特別是在中文Windows下通信時(shí)更會(huì)出現(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)字符數(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ū)動(dòng)程序(COMM.DRV)調(diào)用API函數(shù)發(fā)送和接收數(shù)據(jù)。當(dāng)用通信控件或聲明調(diào)用API函數(shù)時(shí),它們由COMM.DRV解釋并傳遞給設(shè)備驅(qū)動(dòng)程序。作為一個(gè)VB程序員,要編寫通信程序,只需知道通信控件提供給Windows通信API函數(shù)的接口即可,換句話說,只需設(shè)定和監(jiān)視通信控件的屬性和事件即可。2.利用MSComm控件進(jìn)行數(shù)據(jù)的接收和發(fā)送搞清楚以上基本屬性和事件后就可以開始編寫通信程序了:在VB5.0/6.0中新建一個(gè)工程文件,添加MicrosoftCommcontrol5.0組件,在窗體Form1中加入Command命令按鈕并取名為cmdTest,MSComm控件取名為MSComm1,寫入以下代碼:PrivateSubcmdTest_Click()MSComm1.CommPort=1'設(shè)定Com1口IfMSComm1.PortOpen=FalseThen
MSComm1.Settings="9600,N,8,1"
'9600波特率,無校驗(yàn),8位數(shù)據(jù)位,1位停止位
MSComm1.PortOpen=True
'打開串口EndIfMSComm1.OutBufferCount=0
'清空發(fā)送緩沖區(qū)MSComm1.InBufferCount=0
'清空接收緩沖區(qū)'發(fā)送字符數(shù)據(jù),注意必須用回車符(vbCr)結(jié)束MSComm1.Output="Thisisagoodbook!"&vbCr'撥打電話號(hào)碼或發(fā)送AT命令MSComm1.Output="ATDT0294563622"&vbCr'發(fā)送字符數(shù)組數(shù)據(jù),注意ByteArray必須事先定義賦值DimByteArrayasbyte()
'定義動(dòng)態(tài)數(shù)組
ReDimByteArray(1)'重定義數(shù)組大小
ByteArray(0)=0
ByteArray(1)=1
MSComm1.Output=ByteArray'發(fā)送字符數(shù)組數(shù)據(jù)EndSubPrivateSubMSComm1_OnComm()SelectCaseMSComm1.CommEvent
CasecomEvReceive'接收字符數(shù)據(jù)DimBufferAsVariantMSComm1.InputLen=0'當(dāng)InputMode屬性值為0(文本模式)時(shí),變量中含String型數(shù)據(jù)。'當(dāng)InputMode屬性值為1(二進(jìn)制模式)時(shí),變量中含Byte型數(shù)組數(shù)據(jù)。MSComm1.InputMode=comInputModeBinaryBuffer=MSComm1.Input
'接收二進(jìn)制數(shù)據(jù)MSComm1.InputMode=comInputModeTextBuffer=MSComm1.Input
CaseelseEndSelectEndSub3.中文Windows下的通信問題與解決方法3.1接收的數(shù)據(jù)少于發(fā)送的數(shù)據(jù)如果通過MSComm控件一次性傳送較多的二進(jìn)制數(shù)據(jù),那么,很可能收到的數(shù)據(jù)不足。例如在設(shè)置為2400bps傳輸率的情況下,一次性可以傳輸2048個(gè)字符數(shù)據(jù),那么在大多數(shù)情況下一次只能收到1200個(gè)字符左右,這是因?yàn)樾掳娴腗SComm32.OCX中存在一個(gè)影響傳輸二進(jìn)制數(shù)據(jù)的Bug。32位WindowsAPI函數(shù)使用了幾個(gè)用COMMTIMEOUTS結(jié)構(gòu)表示的限時(shí)變量,WriteTotalTimeOutConstant即是其中的一個(gè),它被Windows內(nèi)部設(shè)定為5000(即5秒),這個(gè)常量決定了在通信驅(qū)動(dòng)程序停止傳輸之前花費(fèi)在發(fā)送緩沖區(qū)中數(shù)據(jù)的時(shí)間的長短。5秒鐘意味著通信速度為1200bps情況下僅能發(fā)送600個(gè)字符,2400bps情況下僅能發(fā)送1200個(gè)左右的字符。事實(shí)上,在一個(gè)緩沖區(qū)內(nèi)一次性發(fā)送更多的數(shù)據(jù)是非??赡艿摹B5.0/6.0版本的MSComm控件有一個(gè)新增的重要的屬性稱為CommID,CommID指的是當(dāng)串口被打開時(shí),被API所調(diào)用的串口句柄(或標(biāo)志),這也意味著能利用API接口函數(shù)去修改這個(gè)常量。每次串口關(guān)閉后,Windows會(huì)自動(dòng)將之恢復(fù)為5000,所以,每次打開串口后需要重新設(shè)定。以下是API聲明代碼:TypeCOMMTIMEOUTSReadIntervalTimeoutAsLongReadTotalTimeoutMultiplierAsLong
ReadTotalTimeoutConstantAsLong
WriteTotalTimeoutMultiplierAsLong
WriteTotalTimeoutConstantAsLongEndTypeDeclareFunctionSetCommTimeoutsLib"Kernel32"(ByValhFileAsLong,_lpCommTimeoutsAsCOMMTIMEOUTS)AsLongDeclareFunctionGetCommTimeoutsLib"Kernel32"(ByValhFileAsLong,_lpCommTimeoutsAsCOMMTIMEOUTS)AsLongDimtimeoutsAsCOMMTIMEOUTSDimRetAsLongIfComm1.PortOpen=FalseThen
Comm1.PortOpen=TrueEndIf'打開串口后重新設(shè)定串口句柄Ret=GetCommTimeouts(Comm1.CommID,timeouts)'Setsomedefaulttimeoutstimeouts.ReadIntervalTimeout=1timeouts.ReadTotalTimeoutMultiplier=1timeouts.ReadTotalTimeoutConstant=1timeouts.WriteTotalTimeoutMultiplier=1timeouts.WriteTotalTimeoutConstant=(Comm1.OutBufferSize\Val(Comm1.Settings))*10000+1000Ret=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ā)送到通信端口即可。但在中文Windows下卻行不通,假設(shè)在中文Windows下運(yùn)行以下程序:DimiasIntegerFori=0To255
MSComm1.Output=chr(i)Nexti希望在接收端得到預(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)生了此類錯(cuò)誤。那么,如何發(fā)送大于128的數(shù)據(jù)呢?答案是使用字節(jié)數(shù)組,將以上程序改為:DimMyData(255)AsByteFori=0To255
MyData(i)=iNextiMSComm1.Output=MyDataDo
DoEventsLoopUntilMSComm1.OutBufferCount=0'接收過程PrivateSubMSComm1_OnComm()
SelectCaseMSComm1.CommEventCasecomEvReceive
DimBufferAsVariant
MSComm1.InputMode=comInputModeBinary
MSComm1.InputLen=0
Buffer=MSComm1.Input
Fori=LBound(Buffer)ToUBound(Buffer)Text1.Text=Buffer(i);NextiCaseElseEndSelectEndSub3.3如何發(fā)送中文字符串VB5.0/6.0中可以直接把中文字符等同于英文字符發(fā)送,如:MSComm1.output="現(xiàn)在發(fā)送中文數(shù)據(jù)!",但這種方法發(fā)送的中文數(shù)據(jù)不能太長,發(fā)送緩沖區(qū)和接收緩沖區(qū)的大小需設(shè)定為中文字符的兩倍以上,而且發(fā)送與接收系統(tǒng)所處的操作系統(tǒng)版本最好要一致,否則會(huì)出現(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é)分開,而VB5.0/6.0中并沒有提供此類函數(shù),以下是求整數(shù)高、低字節(jié)的函數(shù)。PublicFunctionHiByte(aAsInteger)
DimbAsInteger
b=aAnd&HFF00
b=b/256
Ifb<0Thenb=b+256
HiByte=bEndFunction
PublicFunctionLowByte(aAsInteger)
DimbAsInteger
b=aAnd&HFF
LowByte=bEndFunction3.4如何在通信過程中進(jìn)行延時(shí)在某些通信過程中,常常需要在發(fā)送完一組數(shù)據(jù)后進(jìn)行一段延時(shí),以等待對(duì)方處理上組數(shù)據(jù),以下是延時(shí)函數(shù)代碼。PublicSubDelay(PauseTimeAsSingle)
DimStartStart=Timer
'設(shè)定開始時(shí)間DoWhileTimer<Sta
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025-2030年中國虛擬現(xiàn)實(shí)VR行業(yè)營銷創(chuàng)新戰(zhàn)略制定與實(shí)施研究報(bào)告
- 2025-2030年中國指紋識(shí)別芯片行業(yè)資本規(guī)劃與股權(quán)融資戰(zhàn)略制定與實(shí)施研究報(bào)告
- 2025-2030年中國玩具行業(yè)資本規(guī)劃與股權(quán)融資戰(zhàn)略制定與實(shí)施研究報(bào)告
- 2025-2030年中國酒店行業(yè)開拓第二增長曲線戰(zhàn)略制定與實(shí)施研究報(bào)告
- 2024年汽車智能座艙投融資研究白皮書
- 織物強(qiáng)力標(biāo)準(zhǔn)
- 關(guān)于“臥室裝飾燈”的調(diào)研問卷
- 福建省2024屆高三下學(xué)期6月模擬英語試題
- 收購某供水特許經(jīng)營項(xiàng)目SPV公司股權(quán)項(xiàng)目可行性研究報(bào)告
- 甲流防控知識(shí)培訓(xùn)課件
- 心肺復(fù)蘇術(shù)課件2024新版
- 壓瘡診療與護(hù)理規(guī)范
- 錦鯉中國風(fēng)鯉魚吉祥好運(yùn)通用大氣PPT模板
- 燃?xì)鈽I(yè)務(wù)代辦授權(quán)書模板
- 侵襲性肺部真菌感染的診斷標(biāo)準(zhǔn)以及治療基本原則
- 與齒輪相關(guān)的英語詞匯總結(jié)
- 單層鋼結(jié)構(gòu)工業(yè)廠房縱向定位軸線的定位
- 粉體工程第六章粉碎過程及設(shè)備
- 洪水計(jì)算(推理公式法)
- ap系列火焰光度計(jì)說明書
- GMW系列往復(fù)式給料機(jī)說明書
評(píng)論
0/150
提交評(píng)論