版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
MSComm控件在中文Windows下的通信問題與處理方法
摘要VB5.0/6.0的MSComm通信控件提供了一系列標準通信命令的接口,它允許建立串口連接,但在實際通信軟件設計過程中,MSComm控件并非像想像中那樣完美和容易控制,特別是在中文Windows下通信時更會出現(xiàn)問題。本文就MSComm控件在實際應用中可能出現(xiàn)的問題以及編程技巧進行探討。關鍵詞MsComm控件串口通信
處理1.MSComm控件的基礎理論一般說來,計算機都有一個或多個串行端口,它們依次為Com1、Com2、...。這些串口還提供了外部設備與PC進行數(shù)據(jù)傳輸和通信的通道,這些串口在CPU和外設之間充當解釋器的角色。當字符數(shù)據(jù)從CPU發(fā)送給外設時,這些字符數(shù)據(jù)將被轉換成串行比特流數(shù)據(jù);當接收數(shù)據(jù)時,比特流數(shù)據(jù)被轉換為字符數(shù)據(jù)傳遞給CPU。再進一步說,在操作系統(tǒng)方面,Windows用通信驅動程序(COMM.DRV)調用API函數(shù)發(fā)送和接收數(shù)據(jù)。當用通信控件或聲明調用API函數(shù)時,它們由COMM.DRV解釋并傳遞給設備驅動程序。作為一個VB程序員,要編寫通信程序,只需知道通信控件提供給Windows通信API函數(shù)的接口即可,換句話說,只需設定和監(jiān)視通信控件的屬性和事件即可。2.利用MSComm控件進行數(shù)據(jù)的接收和發(fā)送搞清楚以上基本屬性和事件后就可以開始編寫通信程序了:在VB5.0/6.0中新建一個工程文件,添加MicrosoftCommcontrol5.0組件,在窗體Form1中加入Command命令按鈕并取名為cmdTest,MSComm控件取名為MSComm1,寫入以下代碼:PrivateSubcmdTest_Click()MSComm1.CommPort=1'設定Com1口IfMSComm1.PortOpen=FalseThen
MSComm1.Settings="9600,N,8,1"
'9600波特率,無校驗,8位數(shù)據(jù)位,1位停止位
MSComm1.PortOpen=True
'打開串口EndIfMSComm1.OutBufferCount=0
'清空發(fā)送緩沖區(qū)MSComm1.InBufferCount=0
'清空接收緩沖區(qū)'發(fā)送字符數(shù)據(jù),注意必須用回車符(vbCr)結束MSComm1.Output="Thisisagoodbook!"&vbCr'撥打電話號碼或發(fā)送AT命令MSComm1.Output="ATDT0294563622"&vbCr'發(fā)送字符數(shù)組數(shù)據(jù),注意ByteArray必須事先定義賦值DimByteArrayasbyte()
'定義動態(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'當InputMode屬性值為0(文本模式)時,變量中含String型數(shù)據(jù)。'當InputMode屬性值為1(二進制模式)時,變量中含Byte型數(shù)組數(shù)據(jù)。MSComm1.InputMode=comInputModeBinaryBuffer=MSComm1.Input
'接收二進制數(shù)據(jù)MSComm1.InputMode=comInputModeTextBuffer=MSComm1.Input
CaseelseEndSelectEndSub3.中文Windows下的通信問題與解決方法3.1接收的數(shù)據(jù)少于發(fā)送的數(shù)據(jù)如果通過MSComm控件一次性傳送較多的二進制數(shù)據(jù),那么,很可能收到的數(shù)據(jù)不足。例如在設置為2400bps傳輸率的情況下,一次性可以傳輸2048個字符數(shù)據(jù),那么在大多數(shù)情況下一次只能收到1200個字符左右,這是因為新版的MSComm32.OCX中存在一個影響傳輸二進制數(shù)據(jù)的Bug。32位WindowsAPI函數(shù)使用了幾個用COMMTIMEOUTS結構表示的限時變量,WriteTotalTimeOutConstant即是其中的一個,它被Windows內部設定為5000(即5秒),這個常量決定了在通信驅動程序停止傳輸之前花費在發(fā)送緩沖區(qū)中數(shù)據(jù)的時間的長短。5秒鐘意味著通信速度為1200bps情況下僅能發(fā)送600個字符,2400bps情況下僅能發(fā)送1200個左右的字符。事實上,在一個緩沖區(qū)內一次性發(fā)送更多的數(shù)據(jù)是非??赡艿?。VB5.0/6.0版本的MSComm控件有一個新增的重要的屬性稱為CommID,CommID指的是當串口被打開時,被API所調用的串口句柄(或標志),這也意味著能利用API接口函數(shù)去修改這個常量。每次串口關閉后,Windows會自動將之恢復為5000,所以,每次打開串口后需要重新設定。以下是API聲明代碼:TypeCOMMTIMEOUTSReadIntervalTimeoutAsLongReadTotalTimeoutMultiplierAsLong
ReadTotalTimeoutConstantAsLong
WriteTotalTimeoutMultiplierAsLong
WriteTotalTimeoutConstantAsLongEndTypeDeclareFunctionSetCommTimeoutsLib"Kernel32"(ByValhFileAsLong,_lpCommTimeoutsAsCOMMTIMEOUTS)AsLongDeclareFunctionGetCommTimeoutsLib"Kernel32"(ByValhFileAsLong,_lpCommTimeoutsAsCOMMTIMEOUTS)AsLongDimtimeoutsAsCOMMTIMEOUTSDimRetAsLongIfComm1.PortOpen=FalseThen
Comm1.PortOpen=TrueEndIf'打開串口后重新設定串口句柄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ù)在通信程序中,以單字符方式逐個發(fā)送數(shù)據(jù)時,每一個數(shù)據(jù)范圍為0-255(即十六進制的00-FF)。在單字符版本的英文Windows或DOS版的BASIC程序中,只需要將相應的數(shù)據(jù)轉換成相應的字符發(fā)送到通信端口即可。但在中文Windows下卻行不通,假設在中文Windows下運行以下程序:DimiasIntegerFori=0To255
MSComm1.Output=chr(i)Nexti希望在接收端得到預期的0-255之間的數(shù)據(jù),結果卻是:前129個數(shù)據(jù)接收正確,為0-128,后面127個數(shù)據(jù)為126個0和一個255。造成這種結果的原因在于中文Windows使用的是雙字節(jié)字符集(DBCS)系統(tǒng)。DBCS系統(tǒng)使用0-128之間的數(shù)字表示ASCII字符,大于128的數(shù)字僅作為前導字符,它只是顯示是一個非拉丁語系的字符,而并不代表實際意義。上述程序在調用CHR()函數(shù)時用到了DBCS字符集,因此產(chǎn)生了此類錯誤。那么,如何發(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ū)的大小需設定為中文字符的兩倍以上,而且發(fā)送與接收系統(tǒng)所處的操作系統(tǒng)版本最好要一致,否則會出現(xiàn)接收或發(fā)送緩沖區(qū)溢出之類的錯誤。這種方法可用于一般要求不太高的場合。除了上述方法外,還可以采用間接方式發(fā)送中文字符串。在發(fā)送端將漢字或字符轉換為機器內碼或區(qū)位碼數(shù)據(jù)數(shù)組,然后將轉換后的數(shù)據(jù)發(fā)送到串口,在接收端接收到數(shù)據(jù)后,按照相反的順序將得到的數(shù)據(jù)轉換為相應的漢字或字符。在轉換過程中,要用到位運算,如取得漢字的內碼后需要將高字節(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如何在通信過程中進行延時在某些通信過程中,常常需要在發(fā)送完一組數(shù)據(jù)后進行一段延時,以等待對方處理上組數(shù)據(jù),以下是延時函數(shù)代碼。PublicSubDelay(PauseTimeAsSingle)
DimStartStart=Timer
'設定開始時間DoWhileTimer<Sta
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 生物性職業(yè)暴露防護與健康監(jiān)護方案
- 生物制劑臨床試驗中脫落病例管理規(guī)范
- 深度解析(2026)《GBT 20014.25-2010良好農(nóng)業(yè)規(guī)范 第25部分:花卉和觀賞植物控制點與符合性規(guī)范》(2026年)深度解析
- 程序員資格認證考試含答案
- 深度解析(2026)《GBT 19386.1-2003紡織機械與附件 紗線和中間產(chǎn)品的卷裝 第1部分術語》
- 沃爾瑪行政助理面試題及答案
- 數(shù)字市場開發(fā)專員職業(yè)資格認證考試大綱含答案
- 深度解析(2026)《GBT 19290.1-2003發(fā)展中的電子設備構體機械結構模數(shù)序列 第1部分總規(guī)范》
- 尾氣處理裝置項目可行性分析報告范文(總投資19000萬元)
- 獨居老人照護:遠程決策參與的溝通策略
- 眩暈的中醫(yī)治療
- 2026共青團中央所屬單位高校畢業(yè)生招聘66人參考筆試試題及答案解析
- 2026屆吉林省九校高三11月聯(lián)考化學試題及答案
- 2025福建寧德霞浦縣福寧水務有限公司招聘33人考試筆試模擬試題及答案解析
- 2025年全國反洗錢知識競賽試題庫及答案(共95題)
- 大量不保留灌腸
- 遼寧省名校聯(lián)盟2025-2026學年高三上學期12月月考物理試題+答案
- 江西省地方課課件
- (2025年)護士資格《基礎護理學》考試練習試題附答案
- 小學英語一般將來時精美講課教案
- 水下仿生撲翼推進系統(tǒng)設計
評論
0/150
提交評論