找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 8112|回復(fù): 0
打印 上一主題 下一主題
收起左側(cè)

excel vba 獲取rs232數(shù)據(jù)

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:104835 發(fā)表于 2016-2-4 03:52 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
本文介紹VB6.0利用MSComm通信控件,開(kāi)發(fā)微機(jī)通過(guò)串口對(duì)工業(yè)儀表進(jìn)行實(shí)時(shí)數(shù)據(jù)采集的編程技術(shù)。給出的程序代碼具有通用性,并有詳細(xì)的注釋,可以直接或稍加改動(dòng)后用于其他數(shù)據(jù)采集或?qū)崟r(shí)控制程序中。

----一臺(tái)工業(yè)專用實(shí)時(shí)檢測(cè)儀表,接高精度位移傳感器,用于測(cè)量微小形變或微量位移,儀表測(cè)量精度為0.01毫米,測(cè)量范圍最大值為50毫米。該儀表帶有一個(gè)9針的RS-232C 串口,能與微機(jī)進(jìn)行串口數(shù)據(jù)通信,實(shí)時(shí)傳送檢測(cè)數(shù)據(jù),通過(guò)微機(jī)軟件處理可實(shí)現(xiàn)工業(yè)實(shí)時(shí)監(jiān)控。

----該儀表的串口數(shù)據(jù)通信協(xié)議是:數(shù)據(jù)傳輸速率為 9600bps,1位開(kāi)始位,8位數(shù)據(jù)位,1位停止位,無(wú)奇偶校驗(yàn)位。儀表每秒發(fā)送50幀檢測(cè)數(shù)據(jù),每幀數(shù)據(jù)由4個(gè)字節(jié)組成。第一個(gè)字節(jié)定義為二進(jìn)制常數(shù)0F0H,是每幀數(shù)據(jù)開(kāi)始的標(biāo)志字節(jié);后面連續(xù)2個(gè)字節(jié)為數(shù)據(jù)字節(jié),采用壓縮的BCD碼編碼方式,高位在前,低位在后,即一個(gè)字節(jié)表示兩位十進(jìn)制數(shù),則兩個(gè)字節(jié)表示四位十進(jìn)制數(shù),小數(shù)點(diǎn)采用固定形式,定義在兩字節(jié)中間;第四個(gè)字節(jié)為符號(hào)字節(jié),該字節(jié)第八位為1,即:
1xxxxxxx


----則為負(fù)數(shù);第八位為0,即:
0xxxxxxx


----則為正數(shù)。

----例如:0F0H 26H 87H 80H 0F0H 34H 62H 00H 表示 -26.87 34.62。

----通信傳輸速率為9600bps,則最快速度1.04ms發(fā)送一個(gè)字節(jié),儀表每秒發(fā)送50幀數(shù)據(jù),每幀數(shù)據(jù)有4個(gè)字節(jié),即每秒發(fā)送200個(gè)字節(jié),平均5.0ms 發(fā)送一個(gè)字節(jié),連續(xù)讀取串口數(shù)據(jù)時(shí)要在程序中添加循環(huán)等待程序。

----為了實(shí)現(xiàn)實(shí)時(shí)監(jiān)測(cè)功能,接收數(shù)據(jù)的讀取要盡可能的快速,則設(shè)置MSComm1的屬性如下:
RThreshold = 1
接收緩沖區(qū)收到一個(gè)字節(jié)產(chǎn)生OnComm事件
InputLen = 1 每次讀取一個(gè)字節(jié)

----儀表每秒發(fā)送50幀數(shù)據(jù),微機(jī)收到一幀完整數(shù)據(jù)至少需要20 ms時(shí)間,然后再進(jìn)行數(shù)據(jù)處理。如果微機(jī)在下一幀數(shù)據(jù)接收前即20ms內(nèi)能將數(shù)據(jù)計(jì)算處理完畢,則接收緩沖區(qū)內(nèi)只會(huì)保存有一幀數(shù)據(jù),不會(huì)存有兩幀以上數(shù)據(jù),接收緩沖區(qū)的大小不會(huì)影響實(shí)時(shí)監(jiān)測(cè)效果(接收緩沖區(qū)>4字節(jié)),這時(shí)完全可以實(shí)現(xiàn)實(shí)時(shí)監(jiān)測(cè)或?qū)崟r(shí)控制;如果微機(jī)在20ms內(nèi)不能將數(shù)據(jù)計(jì)算處理完畢,接收緩沖區(qū)設(shè)置得又很大,在數(shù)據(jù)計(jì)算處理完畢前,接收緩沖區(qū)內(nèi)就會(huì)保存有兩幀以上數(shù)據(jù),而且一次工作時(shí)間越長(zhǎng),緩沖區(qū)內(nèi)滯留數(shù)據(jù)幀就越多,數(shù)據(jù)采集和數(shù)據(jù)處理之間產(chǎn)生逐漸增大的額外時(shí)間差,當(dāng)接收緩沖區(qū)充滿后,時(shí)間差不再增大,固定在某一值,部分?jǐn)?shù)據(jù)因不能及時(shí)采集到接收緩沖區(qū)中,數(shù)據(jù)產(chǎn)生丟失現(xiàn)象,真實(shí)工作情況就會(huì)和微機(jī)處理結(jié)果產(chǎn)生較大的時(shí)間差,對(duì)實(shí)時(shí)監(jiān)測(cè)和實(shí)時(shí)控制很不利,這種情況下接收緩沖區(qū)的大小就會(huì)影響實(shí)時(shí)監(jiān)測(cè)效果,所以接收緩沖區(qū)設(shè)置不能過(guò)大,以保證數(shù)據(jù)處理的實(shí)時(shí)性。

----設(shè)置接收數(shù)據(jù)模式采用二進(jìn)制形式,即 InputMode=comInputModeBinary,但用Input屬性讀取數(shù)據(jù)時(shí),不能直接賦值給 Byte 類型變量,只能通過(guò)先賦值給一個(gè) Variant 類型變量,返回一個(gè)二進(jìn)制數(shù)據(jù)的數(shù)組,再轉(zhuǎn)換保存到Byte類型數(shù)變量中。

----VB中有Byte類型變量,但沒(méi)有字節(jié)的位處理語(yǔ)句,符號(hào)字節(jié)的位處理要判斷符號(hào)字節(jié)的值是否大于 127,大于127則為負(fù)數(shù);壓縮的BCD碼存入 Byte類型變量,VB系統(tǒng)只按十進(jìn)制數(shù)處理,這要通過(guò)一個(gè)簡(jiǎn)單算法換算,解壓BCD碼才能還原成十進(jìn)制表示數(shù)值。假如a是Byte類型變量,D是Single類型變量,將一個(gè)壓縮的BCD 碼存入a中,則算法是:
D=(a\16)*10 + a-(a\16)*16
則D=a-(a\16)*6

----程序清單:

----在通用聲明中定義程序所用變量:
Dim ab(4) As Byte
‘字節(jié)數(shù)據(jù)類型數(shù)組,用來(lái)存儲(chǔ)接收到的一組字節(jié)數(shù)據(jù)
Dim av As Variant ‘用來(lái)從接收緩沖區(qū)讀取數(shù)據(jù)
Dim i As Integer
Dim j As Integer
Dim w As Integer ‘接收數(shù)據(jù)個(gè)數(shù)計(jì)數(shù)器
Dim b1 As Single
Dim b2 As Single
Dim WW As Single ‘十進(jìn)制檢測(cè)值
Dim MaxW As Single ‘最大值
Dim MinW As Single ‘最小值

----在窗體中添加名為Command1的[開(kāi)始]按鈕和名為 MSComm1的MSComm控件。

---- [開(kāi)始]按鈕的Click事件處理程序主要是對(duì)MSComm1控制的參數(shù)初始化設(shè)置,程序中大部分參數(shù)在設(shè)計(jì)時(shí)可在MSComm1控制的屬性窗口中設(shè)置:
Private Sub Command1_Click()
‘開(kāi)始按鈕
With MSComm1
.CommPort=2 ‘使用COM2
.Setting=“9600,N,8,1" ‘設(shè)置通信口參數(shù)
.InBufferSize=40
‘設(shè)置MSComm1接收緩沖區(qū)為40字節(jié)
.OutBufferSize=2
‘設(shè)置MSComm1發(fā)送緩沖區(qū)為2字節(jié)
.InputMode = comInputModeBinary
‘設(shè)置接收數(shù)據(jù)模式為二進(jìn)制形式
.InputLen = 1
‘設(shè)置Input 一次從接收緩沖讀取字節(jié)數(shù)為1
.SThreshold = 1
‘設(shè)置Output 一次從發(fā)送緩沖讀取字節(jié)數(shù)為1
.InBufferCount = 0 ‘清除接收緩沖區(qū)
.OutBufferCount = 0 ‘清除發(fā)送緩沖區(qū)
MaxW = -99
‘最大值賦初值
MinW = 99 ‘最小值賦初值
w = 0
‘?dāng)?shù)據(jù)個(gè)數(shù)計(jì)數(shù)器清零
.RThreshold = 1
‘設(shè)置接收一個(gè)字節(jié)產(chǎn)生OnComm事件
If .PortOpen = False Then
‘判斷通信口是否打開(kāi)
.PortOpen = True ‘打開(kāi)通信口
If Err Then ‘錯(cuò)誤處理
MsgBox “串口通信無(wú)效"
Exit Sub
End If
End If
End With
End Sub

----為了達(dá)到實(shí)時(shí)數(shù)據(jù)采集目的,實(shí)時(shí)數(shù)據(jù)采集處理程序采用MSComm事件驅(qū)動(dòng)方式。

----MSComm1_OnComm的事件處理程序只處理 comEvReceive事件,首先判斷幀數(shù)據(jù)的開(kāi)始字節(jié),關(guān)閉OnComm接收事件,然后接收數(shù)據(jù)字節(jié),將壓縮BCD進(jìn)行還原轉(zhuǎn)換,再接收符號(hào)字節(jié),判斷數(shù)據(jù)符號(hào),判斷數(shù)據(jù)最大最小值,最后打開(kāi)OnComm接收事件,等待下一次OnComm事件產(chǎn)生:
Private Sub MSComm1_OnComm()
With MSComm1
Select Case .CommEvent
‘判斷MSComm1通信事件
Case comEvReceive
‘收到Rthreshold個(gè)字節(jié)產(chǎn)生的接收事件
av = .Input
‘讀取一個(gè)接收字節(jié)
ab(1) = av(0)
‘轉(zhuǎn)換保存到字節(jié)數(shù)據(jù)類型數(shù)組
If ab(1) = &HF0 Then
‘判斷是否為數(shù)據(jù)開(kāi)始標(biāo)志
RThreshold = 0
‘關(guān)閉OnComm事件接收
Do
DoEvents
Loop Until .InBufferCount >= 3
‘循環(huán)等待MSComm1接收緩沖區(qū)>=3個(gè)字節(jié)
w = w + 1 ‘計(jì)數(shù)器累加計(jì)數(shù)
av = .Input
‘讀取第二個(gè)數(shù)據(jù)字節(jié)(BCD碼高位字節(jié))
ab(2) = av(0)
‘轉(zhuǎn)換保存到字節(jié)數(shù)據(jù)類型數(shù)組
av = .Input
‘讀取第三個(gè)數(shù)據(jù)字節(jié)(BCD碼低位字節(jié))
ab(3) = av(0)
‘轉(zhuǎn)換保存到字節(jié)數(shù)據(jù)類型數(shù)組
av = .Input
‘讀取第四個(gè)數(shù)據(jù)字節(jié)(符號(hào)位字節(jié))
ab(4) = av(0)
‘轉(zhuǎn)換保存到字節(jié)數(shù)據(jù)類型數(shù)組
b1 = ab(2) - 6 * (ab(2)\16)
‘高位字節(jié)壓縮BCD碼轉(zhuǎn)換為實(shí)數(shù)
b2 = ab(3) - 6 * (ab(3)\16)
‘低位字節(jié)壓縮BCD碼轉(zhuǎn)換為實(shí)數(shù)
WW = b1 + b2 / 100
‘?dāng)?shù)值組合,標(biāo)定小數(shù)點(diǎn)
If ab(4) > 127 Then WW=?WW
‘判斷數(shù)據(jù)符號(hào)位
Label1(0) = Format(WW, “0.00")
‘顯示毫米單位數(shù)值,2位小數(shù)
Label1(1) =Format(WW /25.4, “0.000")
‘顯示英寸單位數(shù)值,3位小數(shù)
If WW > MaxW And WW < 51 Then

----‘判斷最大值,儀表在剛開(kāi)始工作時(shí)有干擾,會(huì)傳導(dǎo)一些亂碼,位移傳感器有參數(shù)偏差,最大值一般都略大于50毫米,所以取51為極限最大值,取-51為極限最小值。
MaxW = WW
Label1(2) = Format(MaxW, “0.00")
‘顯示毫米單位最大值,2位小數(shù)
Label1(3) = Format(MaxW/25.4,“0.000")
‘顯示英寸單位最大值,3位小數(shù)
End If
If WW < MinW And WW > -51 Then
‘判斷最小值
MinW = WW
Label1(4) = Format(MinW, “0.00")
‘顯示毫米單位最小值,2位小數(shù)
Label1(5) = Format(MinW/25.4,“0.000")
   ‘顯示英寸單位最小值,3位小數(shù)
End If
.RThreshold = 1
‘打開(kāi)MSComm1事件接收
End If
Case Else
End Select
End With
End Sub

1992年Crescent Software Inc.公司專為VB設(shè)計(jì)了MSCOMM.VBX用戶通信控件,它提供了通過(guò)串口發(fā)送和接收數(shù)據(jù)的串行通信能力,不但包括了全部Windows API中關(guān)于串行通信的16個(gè)函數(shù)所完成的功能,而且開(kāi)拓了更多的使用戶設(shè)計(jì)方便的對(duì)象屬性來(lái)滿足不同用戶不同業(yè)務(wù)的需求。目前國(guó)內(nèi)眾多的VB資料中很少涉及該通信控件的介紹,本文將詳細(xì)介紹MSCOMM.VBX通信控件及編程方法,并結(jié)合工作中的一個(gè)實(shí)例給出基本通信程序。

1 MSCOMM.VBX通信控件描述

MSCOMM.VBX通信控件可直接從VB的ToolBox中加入窗體Form,即可用其進(jìn)行通信。若ToolBox中無(wú)此控件,則用Tools的Custom Controls 將MSCOMM.VBX從Windows的System子目錄中加入VB的ToolBox中。

1.1 通信方式

MSCOMM.VBX有2種不同的方式來(lái)處理和解決各類通信軟件的開(kāi)發(fā)和設(shè)計(jì)問(wèn)題

1、事件驅(qū)動(dòng)。它與C/C++寫(xiě)Windows 軟件時(shí)的窗口回調(diào)函數(shù)類似,是1種功能強(qiáng)大的處理問(wèn)題的方法。在實(shí)際工作中,往往要處理許多通信中的相關(guān)事件,例如:當(dāng)線路數(shù)據(jù)到達(dá)本端或CD線和RTS信號(hào)線狀態(tài)發(fā)生變化時(shí),要求我們使用相應(yīng)的事件來(lái)跟蹤和處理,該控件是使用OnComm事件來(lái)實(shí)現(xiàn)的,它也包括檢測(cè)和處理通信錯(cuò)誤等方面的問(wèn)題,CommEvent 值返回最近的通信事件或錯(cuò)誤的數(shù)字代碼。通信控件詳細(xì)的錯(cuò)誤和事件舉例有:

MSCOMM-ER-BREAK 收到1個(gè)Break Signal

MSCOMM-ER-CDTO CD 信號(hào)超時(shí)

……

MSCOMM-EV-CD CD信號(hào)改變

……

2、查詢方式。由程序設(shè)計(jì)者負(fù)責(zé)讀取CommEvent的值并處理所發(fā)生的錯(cuò)誤或事件。通常簡(jiǎn)單的應(yīng)用程序設(shè)計(jì)可采用這種辦法。

1.2 通信控件的屬性

利用通信控件編制通信程序,關(guān)鍵是準(zhǔn)確理解設(shè)置通信控件的屬性。MSCOMM.VBX提供了27個(gè)關(guān)于通信控件方面的屬性,例如:

CommPort:設(shè)置或返回通信口編號(hào)。

Settings:設(shè)置或返回以字符串形式出現(xiàn)的數(shù)據(jù)通信格式:波特率、校驗(yàn)、數(shù)據(jù)位和停 止位。

PortOpen:設(shè)置或返回通信口狀態(tài)(包括打開(kāi)和關(guān)閉1個(gè)通信口)

……

3、 實(shí)例

本程序應(yīng)用背景為DCC95型靜電除塵器自動(dòng)監(jiān)控系統(tǒng)軟件,解決1個(gè)PC工控機(jī)(主站)與32個(gè)單片機(jī)(子站)之間的通信問(wèn)題。主站與子站之間這總線式網(wǎng)絡(luò)結(jié)構(gòu),采用RS-485通信標(biāo)準(zhǔn),以問(wèn)答方式進(jìn)行數(shù)據(jù)通信。由于32個(gè)子站與主站發(fā)送通信命令(下行命令),主站在接收子站發(fā)回的相應(yīng)回答命令(上行命令)后繼續(xù)發(fā)送下行命令的通信形式。根據(jù)系統(tǒng)功能的要求,主站需發(fā)送2種類型的命令:(1)同期命令,它由定時(shí)器觸發(fā)引起,每隔ls周期發(fā)送1次;(2)非周期性命令,它由操作者按動(dòng)相應(yīng)命令按鈕引起,非周期性發(fā)送。自動(dòng)監(jiān)控系統(tǒng)軟件安裝在主站上,而通信程序作為自動(dòng)監(jiān)控系統(tǒng)軟件的一部分也安裝在主站上。

本文僅列出調(diào)試通信程序時(shí)進(jìn)行試驗(yàn)用的基本演示程序清單。試驗(yàn)時(shí),用1臺(tái)PC機(jī)作為主站,另一臺(tái)PC機(jī)模擬32個(gè)子站的工作,兩臺(tái)PC機(jī)之間采用RS232c串口通信。往主站的通信演示程序窗體(form)中加入1個(gè)通信控件、2個(gè)定時(shí)器控件和1個(gè)命令按鈕控件,通信控件(Mscomm1)用于訪問(wèn)串口,發(fā)送和接收數(shù)據(jù);Periodic定時(shí)器控件(Periodic)用于控制每秒由主站向各子站發(fā)送周期性命令;命令按鈕控件(NonPeriodic-Command)與NonPeriodic定時(shí)器控件(NonPeriodic)用于發(fā)送非周期性命令。數(shù)據(jù)傳送采用事件驅(qū)動(dòng)的通信方式,根據(jù)不同的發(fā)送命令設(shè)置RTreshlod屬性,從而引起OnComm事件以接收數(shù)據(jù)。

2.1 窗體各控件初始化程序

設(shè)置通信串口工作參數(shù),設(shè)置Periodic定時(shí)器的在斷間隔為ls, NonPeriodic定時(shí)器的中斷間隔為0.5s。

Sub Form-Load ()

Mscomm1.CommPort=2 ’選用COM2串行口

Mscomm1.Settings="9600,N8,1" ’波特率9600,無(wú)奇偶校驗(yàn)位,8位數(shù)據(jù)位1位停止位

Mscomm1.InputLen=0 ’Input將讀取接收緩沖區(qū)的全部?jī)?nèi)容

Mscomm1.InBufferSize=1024 ’設(shè)置接收緩沖區(qū)的字節(jié)長(zhǎng)度

Mscomm1.PortOpen=True ’打開(kāi)通信口

Mscomm1.InBufferCount=0 ’清除發(fā)送緩沖區(qū)數(shù)據(jù)

Mscomm1.OutBufferCount=0 ’清除接收緩沖區(qū)數(shù)據(jù)

Periodic.inteval=100 ’設(shè)置ls定時(shí)間隔,使遙測(cè)命令每隔ls發(fā)送1次

NonPeriodic.inteval=500 ’設(shè)置0.5s定時(shí)間隔,查詢命令按鈕是否處于激活狀態(tài)以確定是否發(fā)送周期性命令

Command-Pressed=False ’命令按鈕為未激活狀態(tài)

During- Periodic=False ’周期性命令數(shù)據(jù)傳輸尚未開(kāi)始

During- NonPeriodic=False ’非周期性命令數(shù)據(jù)傳輸尚未開(kāi)始

End Sub

2.2 非周期性命令發(fā)送程序

根據(jù)命令按鈕狀態(tài)及周期性命令數(shù)據(jù)傳輸狀態(tài),在NonPeriodic定時(shí)器的中斷程序中發(fā)送非周期性命令。

Sub NonPeriodic-Command-Click ()

Command-Pressed=True ’命令按鈕激活

End Sub

Sub NonPeriodic-Timer ()

if During- Periodic=True OR Command-Pressed=False

Then Exit Sub ’若周期性命令數(shù)據(jù)傳輸尚未結(jié)束或命令按鈕處于激活狀態(tài),則退出發(fā)送非周期性命令程序。

Command-Pressed=False ’命令按鈕恢復(fù)為未激活狀態(tài)

Call SendData (NONPERIODIC-COMMAND) ’發(fā)送非周期性命令

Mscomm1.RThreshold=R-NONPERIODIC-BYTE’發(fā)送非周期性命令后,設(shè)置Rthreshold屬性,使主站接收所設(shè)定的字節(jié)數(shù)后引發(fā)OnComm事件

End Sub

2.3 Periodic定時(shí)器程序

在Periodic定時(shí)器的中斷程序中發(fā)送周期性命令:

Sub Periodic-Timer ()

if During- NonPeriodic=True Then Exit Sub ’若非周期性命令數(shù)據(jù)傳輸尚未結(jié)束,則退出發(fā)送非周期性命令程序。

During-Periodic=True ’設(shè)置周期性命令數(shù)據(jù)傳輸狀態(tài)為正在進(jìn)行中

Call SendData (PERIODIC-COMMAND) ’發(fā)送周期性命令

Mscomm1.RThreshold=R-PERIODIC-BYTE ’發(fā)送周期性命令后,主站接收R-REMOT- EDATA-BYTE個(gè)字節(jié),可引發(fā)OnComm 事件

End Sub

2.4 OnComm事件程序

根據(jù)RThreshold屬性設(shè)置值,當(dāng)接收緩存區(qū)內(nèi)接收到相應(yīng)字節(jié)的字符時(shí),引發(fā)OnComm事件,在中斷程序中接收數(shù)據(jù)。

Sub Mscomm1-OnComm ()

Select Case Mscomm1.CommEvent ’在此可插入處理各種不同錯(cuò)誤或事件的代碼

Case MSCOMM-EV-RECEIVE

ReceiveString$=Mscomm1.Input

Select Case Mscomm1.RThreshold

Case R-PERIODIC-BYTE ’周期性命令的應(yīng)答數(shù)據(jù)

Call DisposeData(PERIODIC-COMMAND) ’處理接收數(shù)據(jù)

During Periodic=False ’設(shè)置周期性命令數(shù)據(jù)傳輸狀態(tài)為結(jié)束

Case R-NONPERIODIC-BYTE ’非周期性命令的應(yīng)答數(shù)據(jù)

Call DisposeData(NONPERIODIC-COMMAND) ’處理接收數(shù)據(jù)

During-Nonperiodic=False ’設(shè)置非周期性命令數(shù)據(jù)傳輸狀態(tài)為結(jié)束

End Select

End Select

End Sub

------------------------------------------------------------------------

隨著VB版本的不斷升級(jí),VB將成為最快速、易用、強(qiáng)勁的應(yīng)用開(kāi)發(fā)工具,是企業(yè)級(jí)客戶/服務(wù)器應(yīng)用軟件開(kāi)發(fā)的首選工具之一。

VB有一個(gè)例子在Samples\CompTool\Mscomm中。你可以利用這個(gè)例子來(lái)學(xué)習(xí)串口編程。
     打開(kāi)串口先設(shè)置CommPort屬性(端口號(hào)),使用PortOpen=True就可以了。
     串口數(shù)據(jù)保存在MSComm的Input屬性中。你可以使用下面的代碼:
     Dim v As Variant
     v = MSComm1.Input
     For i = 0 To MSComm1.InBufferCount - 1
      Debug.Print v(i)
     Next
  
現(xiàn)有電子秤一臺(tái),使用串口與計(jì)算機(jī)進(jìn)行通訊。編寫(xiě)VB程序來(lái)訪問(wèn)串口,達(dá)到讀取電子秤上顯示的數(shù)據(jù)。該電子秤為BE01型儀表,輸出為RS-232C標(biāo)準(zhǔn)接口,波特率為300-9600、偶校驗(yàn)、7個(gè)數(shù)據(jù)位、2個(gè)停止位。所有字符均發(fā)送11位ASCII碼,一個(gè)起始位。在VB中與串口通訊需要引入控件MSComm串口通訊控件(在Microsoft Comm Control 6.0中)。具體程序如下:控件簡(jiǎn)稱:MSC

Dim Out(12) As Byte '接收var中的值
Dim var As Variant '接收MSC.input中的數(shù)值
Dim nRece As Integer '計(jì)算MSC.inputbuffer的個(gè)數(shù)
Dim i As Integer, j As Integer '隨即變量,計(jì)算循環(huán)

****************************************************************************

Private Sub Form_Load()
 ClearText
 With MSC
  .CommPort = 1 '設(shè)置Com1為通信端口
  .Settings = "9600,E,7,2" '設(shè)置通信端口參數(shù) 9600赫茲、偶校驗(yàn)、7個(gè)數(shù)據(jù)位、1個(gè)停止位.(這里需要進(jìn)一步說(shuō)明的是:.Setting=”BBBB,P,D,S”。
  含義是:B:Baud Rate(波特率);P:Parity(奇偶);D:Data Bit;S:Stop Bit)

  .InBufferSize = 40 '設(shè)置緩沖區(qū)接收數(shù)據(jù)為40字節(jié)
  .InputLen = 1 '設(shè)置Input一次從接收緩沖讀取字節(jié)數(shù)為1
  .RThreshold = 1 '設(shè)置接收一個(gè)字節(jié)就產(chǎn)生OnComm事件

 End With

End Sub

****************************************************************************

Private Sub ClearText()
 Text3.Text = ""
 Text2.Text = "5"
 Text1.Text = ""
End Sub

Private Sub Command1_Click()
 ClearText
 ' nRece = 0 '計(jì)數(shù)器清零
 With MSC
  .InputMode = comInputModeBinary '設(shè)置數(shù)據(jù)接收模式為二進(jìn)制形式
  .InBufferCount = 0 '清除接收緩沖區(qū)
  If Not .PortOpen Then
   .PortOpen = True '打開(kāi)通信端口
  End If
 End With
End Sub

Private Sub MSC_OnComm()
 DelayTime ‘用來(lái)延續(xù)時(shí)間
 ClearText
 With MSC
  Select Case .CommEvent '判斷通信事件
  Case comEvReceive: '收到Rthreshold個(gè)字節(jié)產(chǎn)生的接收事件
   SwichVar 1
   If Out(1) = 2 Then '判斷是否為數(shù)據(jù)的開(kāi)始標(biāo)志
    .RThreshold = 0 '關(guān)閉OnComm事件接收
   End If
   Do
    DoEvents
   Loop Until .InBufferCount >= 3 '循環(huán)等待接收緩沖區(qū)>=3個(gè)字節(jié)
   ' nRece = nRece + 1
   For i = 2 To 12
    SwichVar i
    Text1.Text = Text1.Text & Chr(Out(i))
   Next
   Text1.Text = LTrim(Text1.Text)
   Text2.Text = Text2.Text & CStr(nRece)
   .RThreshold = 1 '打開(kāi)MSComm事件接收
  Case Else
   ' .PortOpen = False
  End Select
 End With

End Sub

****************************************************************************

Private Sub DelayTime()

 Dim bDT As Boolean
 Dim sPrevious As Single, sLast As Single

 bDT = True

 sPrevious = Timer (Timer可以計(jì)算從子夜到現(xiàn)在所經(jīng)過(guò)的秒數(shù),在Microsoft Windows中,Timer函數(shù)可以返回一秒的小數(shù)部分)

 Do While bDT
  If Timer - sPrevious >= 0.3 Then bDT = False
 Loop
 bDT = True

End Sub

(通信傳輸速率為9600bps,則最快速度1.04ms發(fā)送一個(gè)字節(jié),儀表每秒發(fā)送50幀數(shù)據(jù),每幀數(shù)據(jù)有4個(gè)字節(jié),即每秒發(fā)送200個(gè)字節(jié),平均5.0ms 發(fā)送一個(gè)字節(jié),連續(xù)讀取串口數(shù)據(jù)時(shí)要在程序中添加循環(huán)等待程序)

Private Sub SwichVar(ByVal nNum As Integer)

 DelayTime
 var = Null
 var = MSC.Input
 Out(nNum) = var(0)

End Sub

(設(shè)置接收數(shù)據(jù)模式采用二進(jìn)制形式,即 InputMode=comInputModeBinary,但用Input屬性讀取數(shù)據(jù)時(shí),不能直接賦值給 Byte 類型變量,只能通過(guò)先賦值給一個(gè) Variant 類型變量,返回一個(gè)二進(jìn)制數(shù)據(jù)的數(shù)組,再轉(zhuǎn)換保存到Byte類型數(shù)變量中。)

Private Sub Text1_Change()

 Text3.Text = CText(Text1.Text) - CText(Text2.Text)

End Sub

****************************************************************************

Private Function CText(ByVal str As String) As Currency

 If str <> "" Then
  CText = CCur(Val(str))
 Else
  CText = 0
 End If

End Function

 。▋x表每秒發(fā)送50幀數(shù)據(jù),微機(jī)收到一幀完整數(shù)據(jù)至少需要20 ms時(shí)間,然后再進(jìn)行數(shù)據(jù)處理。如果微機(jī)在下一幀數(shù)據(jù)接收前即20ms內(nèi)能將數(shù)據(jù)計(jì)算處理完畢,則接收緩沖區(qū)內(nèi)只會(huì)保存有一幀數(shù)據(jù),不會(huì)存有兩幀以上數(shù)據(jù),接收緩沖區(qū)的大小不會(huì)影響實(shí)時(shí)監(jiān)測(cè)效果(接收緩沖區(qū)>4字節(jié)),這時(shí)完全可以實(shí)現(xiàn)實(shí)時(shí)監(jiān)測(cè)或?qū)崟r(shí)控制;如果微機(jī)在20ms內(nèi)不能將數(shù)據(jù)計(jì)算處理完畢,接收緩沖區(qū)設(shè)置得又很大,在數(shù)據(jù)計(jì)算處理完畢前,接收緩沖區(qū)內(nèi)就會(huì)保存有兩幀以上數(shù)據(jù),而且一次工作時(shí)間越長(zhǎng),緩沖區(qū)內(nèi)滯留數(shù)據(jù)幀就越多,數(shù)據(jù)采集和數(shù)據(jù)處理之間產(chǎn)生逐漸增大的額外時(shí)間差,當(dāng)接收緩沖區(qū)充滿后,時(shí)間差不再增大,固定在某一值,部分?jǐn)?shù)據(jù)因不能及時(shí)采集到接收緩沖區(qū)中,數(shù)據(jù)產(chǎn)生丟失現(xiàn)象,真實(shí)工作情況就會(huì)和微機(jī)處理結(jié)果產(chǎn)生較大的時(shí)間差,對(duì)實(shí)時(shí)監(jiān)測(cè)和實(shí)時(shí)控制很不利,這種情況下接收緩沖區(qū)的大小就會(huì)影響實(shí)時(shí)監(jiān)測(cè)效果,所以接收緩沖區(qū)設(shè)置不能過(guò)大,以保證數(shù)據(jù)處理的實(shí)時(shí)性。) 小結(jié):本文所用的儀表為梅特勒公司出產(chǎn)的BE01型電子秤,其輸出的每個(gè)編碼均為標(biāo)準(zhǔn)的ASCII碼。其他的儀表存在發(fā)射的編碼中含有BCD壓縮碼,而且分為高低位,需要接收后對(duì)其進(jìn)行解碼換算,之后還要將高位和低位數(shù)字進(jìn)行相加,即可以將其BCD碼換算成實(shí)數(shù)。另還存在誤差的可能:判斷最大值,儀表在剛開(kāi)始工作時(shí)有干擾,會(huì)傳導(dǎo)一些亂碼,位移傳感器有參數(shù)偏差,最大值一般都略大于50毫米,所以取51為極限最大值,取-51為極限最小值。暫時(shí)先寫(xiě)這些,當(dāng)然其他的情況可以依此類推!

串口數(shù)據(jù)接收方式
如何處理不定長(zhǎng)數(shù)據(jù)的接收
用字符方式收發(fā)碼值大于127的字符數(shù)據(jù)
串口通訊問(wèn)答2


串口數(shù)據(jù)接收方式

1、 在OnComm 事件中接收數(shù)據(jù):
這種方式能充分MSCOMM控件的特性。OnComm 事件還可以檢查和處理通訊錯(cuò)誤;可以通過(guò)檢查 CommEvent 屬性的值來(lái)查詢事件和錯(cuò)誤;對(duì)于不定長(zhǎng)數(shù)據(jù)以及對(duì)數(shù)據(jù)進(jìn)行處理比較復(fù)雜的情況,此法不是很方便。

Private Sub MSComm_OnComm ()
Select Case MSComm1.CommEvent

' 錯(cuò)誤
Case comEventBreak ' 收到 Break。
Case comEventCDTO ' CD (RLSD) 超時(shí)。
Case comEventCTSTO ' CTS Timeout。
Case comEventDSRTO ' DSR Timeout。
Case comEventFrame ' Framing Error
Case comEventOverrun '數(shù)據(jù)丟失。
Case comEventRxOver'接收緩沖區(qū)溢出。
Case comEventRxParity' Parity 錯(cuò)誤。
Case comEventTxFull '傳輸緩沖區(qū)已滿。
Case comEventDCB '獲取 DCB] 時(shí)意外錯(cuò)誤

' 事件
Case comEvCD ' CD 線狀態(tài)變化。
Case comEvCTS ' CTS 線狀態(tài)變化。
Case comEvDSR ' DSR 線狀態(tài)變化。
Case comEvRing ' Ring Indicator 變化。
Case comEvReceive ' 收到 RThreshold # of chars.
Case comEvSend ' 傳輸緩沖區(qū)有 Sthreshold 個(gè)字符 '
Case comEvEof ' 輸入數(shù)據(jù)流中發(fā)現(xiàn) EOF 字符

End Select
End Sub

2.輪循法采集數(shù)據(jù):
A、定時(shí)器輪循法
對(duì)于數(shù)據(jù)包方式收發(fā)數(shù)據(jù)以及不需即時(shí)響應(yīng)情況,用輪循法更好些。實(shí)際上輪循法最大的好處在于集中處理數(shù)據(jù)而且不太占用CPU。輪循法要注意定時(shí)采集的時(shí)間片段大小;這里用二進(jìn)制收發(fā)模式;使屬性RThreshold、SThreshold為0,屏蔽ONCOMM事件。

InputMode = comInputModeBinary
RThreshold = 0
SThreshold = 0

Private Sub TmrComm_Timer()
'采用輪循法采集數(shù)據(jù)
Dim Rx_buff() As Byte
Dim okstring As String
Dim ReceivedLen As Integer

On Error GoTo ErrorHandler
TmrComm.Enabled = False '關(guān)閉定時(shí)器
If commport.InBufferCount > 0 Then
ReceivedLen = commport.InBufferCount
Rx_buff = commport.Input
okstring = StrConv(tempbyte, vbUnicode)
If ReceivedLen = 6 Then
If Chr(tempbyte(0)) = ":" And tempbyte(3) = &h0a Then
....
End If
If Instr(okstring ,":@END*",vbBinaryCompare) Then
....
End If
End If
TmrComm.Enabled = True '打開(kāi)定時(shí)器
End Sub

B、直接輪循法
此法用于接收少量控制命令字;
' 保存輸入子串的緩沖區(qū)
Dim Instring As String
' 使用 COM1。
MSComm1.CommPort = 1
' 9600 波特,無(wú)奇偶校驗(yàn),8 位數(shù)據(jù),一個(gè)停止位。
MSComm1.Settings = "9600,N,8,1"
' 當(dāng)輸入占用時(shí),
' 告訴控件讀入整個(gè)緩沖區(qū)。
MSComm1.InputLen = 0
' 打開(kāi)端口。
MSComm1.PortOpen = True
' 將 attention 命令送到調(diào)制解調(diào)器。
MSComm1.Output = "ATV1Q0" & Chr$(13)
' 確保
' 調(diào)制解調(diào)器以"OK"響應(yīng)。
' 等待數(shù)據(jù)返回到串行端口。
Do
DoEvents
Buffer$ = Buffer$ & MSComm1.Input
Loop Until InStr(Buffer$, "OK" & vbCRLF)
' 從串行端口讀 "OK" 響應(yīng)。
' 關(guān)閉串行端口。
MSComm1.PortOpen = False



如何處理不定長(zhǎng)數(shù)據(jù)的接收

在處理串口通訊時(shí),經(jīng)常會(huì)遇到不定長(zhǎng)數(shù)據(jù)的接收。由于通訊任務(wù)不同及編程要求的差異所以采用的方法也有所不同。本文就此問(wèn)題進(jìn)行探討。不定長(zhǎng)數(shù)據(jù)從數(shù)據(jù)格式上分,可分為有格式和無(wú)格式。

一、無(wú)格式不定長(zhǎng)數(shù)據(jù)的接收
這種格式在實(shí)際串口通訊中用得不多,一般只用傳送字符串?dāng)?shù)據(jù)。問(wèn)題在于怎么判斷接收結(jié)束。一般用時(shí)間延遲的方法解決。
A、對(duì)于非握手式通訊,可用一個(gè)定時(shí)器定時(shí)輪循接收,并假定每個(gè)輪循接收完成。用ONCOMM事件接收也可,只是不如定時(shí)器定時(shí)輪循接收簡(jiǎn)便。
B、對(duì)于握手方式通訊,可用直接輪循法提高接收的準(zhǔn)確性。下面是實(shí)現(xiàn)此法的函數(shù):

Function sComm(sCommand As String, comReceive As MSComm) As String
Dim nReceiveCount As Integer
If comReceive.PortOpen = False Then
comReceive.PortOpen = True
End If

comReceive.Output = sCommand

Do
nReceiveCount = comReceive.InBufferCount
sleep (2) 'API 函數(shù),掛起當(dāng)前進(jìn)程一段時(shí)間
Loop Until comReceive.InBufferCount = nReceiveCount
If comReceive.PortOpen = True Then
sComm = comReceive.Input
End If
End Function
注:此函數(shù)參照了xth一文。
此法一般是能確保數(shù)據(jù)接收的正確,但由于WINDOWS是多任務(wù)操作系統(tǒng),當(dāng)有耗時(shí)的進(jìn)程運(yùn)行時(shí)會(huì)丟失數(shù)據(jù)。如果系統(tǒng)會(huì)出現(xiàn)這種情況,可增大函數(shù)sleep()的參數(shù)值。

二、不定長(zhǎng)格式數(shù)據(jù)的接收
對(duì)于不定長(zhǎng)數(shù)據(jù)接收最好的方法是制定通訊協(xié)議,比如定義開(kāi)始字符和結(jié)束字符。由于單片機(jī)系統(tǒng)通訊一般不太復(fù)雜,沒(méi)必要去制定一套象通用計(jì)算機(jī)間通訊的協(xié)議,而根據(jù)單片機(jī)系統(tǒng)的大小和性能要求制定通訊協(xié)議。實(shí)際上為便于交流、維護(hù)以及一致性,可制定一套可伸縮的通訊協(xié)議。定義了開(kāi)始字符和結(jié)束字符就容易實(shí)現(xiàn)不定長(zhǎng)格式數(shù)據(jù)通訊,但在實(shí)際通訊編程還是容易出現(xiàn)一些比較隱蔽的通訊錯(cuò)誤。下面就常用方法分別進(jìn)行分析。
A、定時(shí)器輪循法。
假定每個(gè)輪循期數(shù)據(jù)接收完畢,并在每個(gè)輪循期處理數(shù)據(jù),由于有開(kāi)始字符和結(jié)束字符很容易確定接收數(shù)據(jù)的完整性。好象合理設(shè)定輪循時(shí)間值就萬(wàn)無(wú)一失了,但被動(dòng)接收數(shù)據(jù)時(shí)無(wú)論如何也找不合適的輪循時(shí)間值,因?yàn)閱?dòng)定時(shí)器和數(shù)據(jù)到來(lái)基本不同步,這就會(huì)出現(xiàn)一次發(fā)送的數(shù)據(jù)被分在兩個(gè)輪循期接收,所以被動(dòng)接收數(shù)據(jù)時(shí)不能假定每個(gè)輪循期數(shù)據(jù)接收完畢。在接收到結(jié)束字符后才確定一次數(shù)據(jù)接收完畢就可解決此問(wèn)題。
B、OnComm事件法。
方法和定時(shí)器輪循法基本相同,因?yàn)槊看蜲nCommg事件也只能接收到一部分?jǐn)?shù)據(jù)。在VB的在線幫助中這樣注解“設(shè)置 Rthreshold 為 1,接收緩沖區(qū)收到每一個(gè)字符都會(huì)使 MSComm 控件產(chǎn)生 OnComm 事件。”。但實(shí)際上OnComm事件并不是每收到一個(gè)字符便觸發(fā)一次 OnComm 事件。OnComm事件是在緩沖區(qū)收到幾個(gè)甚至幾十個(gè)字節(jié)數(shù)據(jù)后才被觸發(fā)的。版主認(rèn)為這是WINDOWS多任務(wù)使操作系統(tǒng)不能實(shí)時(shí)響應(yīng)造成的。如果要在每次OnComm事件接收一個(gè)字符似乎可設(shè)INPUTLEN屬性為1,但實(shí)際行不通。VB在線幫助中“有該屬性在從輸出格式為定長(zhǎng)數(shù)據(jù)的機(jī)器讀取數(shù)據(jù)時(shí)非常有用”的注解,好象在說(shuō)對(duì)定長(zhǎng)字符有效,但版主發(fā)現(xiàn)INPUTLEN設(shè)為16,接收16個(gè)字符定長(zhǎng)數(shù)據(jù)時(shí)卻被當(dāng)作兩次接收了,一次12個(gè),一次4個(gè)。建議在OnComm事件中接收數(shù)據(jù)要定義通訊協(xié)議并檢測(cè)數(shù)據(jù)的完整性。 對(duì)于不定長(zhǎng)格式數(shù)據(jù)的接收程序員更喜歡定時(shí)器輪循法,也許OnComm事件不好控制吧。
對(duì)于不定長(zhǎng)數(shù)據(jù)的接收,最佳方法可能是在OnComm事件中啟動(dòng)定時(shí)器輪循接收,并同時(shí)停止OnComm事件的觸發(fā),接收完畢后或超時(shí)開(kāi)啟OnComm事件。


用字符方式收發(fā)碼值大于127的字符數(shù)據(jù)

VB的通訊控件友好、功能強(qiáng)大,編程速度快是眾人皆知的。加上VB的易學(xué)、易用,快速開(kāi)發(fā)等特點(diǎn),數(shù)據(jù)通訊量不是很大時(shí),在單片機(jī)通訊領(lǐng)域廣泛地使用VB開(kāi)發(fā)PC上層通訊軟件。實(shí)際開(kāi)發(fā)時(shí)會(huì)有不少問(wèn)題,這里就用字符方式收發(fā)碼值大127的字符數(shù)據(jù)進(jìn)行討論。
在實(shí)際開(kāi)發(fā)中經(jīng)常遇到通訊只是用來(lái)發(fā)送一些控制字符命令和少量數(shù)據(jù)。在VB的中文在線幫助中有“若數(shù)據(jù)只用 ANSI 字符集,則用 comInputModeText”的表述。 ANSI字符集是0-127這容易使人誤解為&h88也可用“INPUTMIDE=comInputModeText”方式收發(fā)。我剛開(kāi)始用VB編通訊模塊時(shí)就為此迷惑過(guò),網(wǎng)上不少網(wǎng)友也時(shí)常問(wèn)及這種問(wèn)題。實(shí)際上在VB中0-127是可以正常收發(fā)的,大于127即&H7F的只有&H80和&HFF能夠收發(fā),其余ANSI字符都被過(guò)濾為0。由于串口通訊是以字節(jié)收發(fā)的,數(shù)據(jù)如以comInputModeText模式收發(fā)則非字符串?dāng)?shù)據(jù)會(huì)被過(guò)濾。在VB中用“INPUTMIDE = comInputModeBinary” 就可以解決這個(gè)問(wèn)題,只是收發(fā)都必須用動(dòng)態(tài)數(shù)組來(lái)完成。用comInputModeBinary模式編程稍有點(diǎn)復(fù)雜,調(diào)試也不直觀,對(duì)于初學(xué)者不易掌握。另外軟件完成后,在實(shí)際應(yīng)用時(shí)會(huì)增加工程維護(hù)難度,因?yàn)閷?duì)于二進(jìn)制代碼不是易于理解的。比如下端機(jī)發(fā)送現(xiàn)場(chǎng)統(tǒng)計(jì)數(shù)據(jù)233,comInputModeBinary模式下串口監(jiān)測(cè)到“:A &H233;",它代表A探針的溫度。一般串口監(jiān)測(cè)軟件要么用ASCII方式顯示,要么用二進(jìn)制方式顯示。用ASCII方式則不能看到&H233,而二進(jìn)制方式則示不好理解,如果顯示58 65 233 59,我想沒(méi)有人喜歡這種方式(如果有更好的方式的話)。但如果顯示“:A 2 3 3 ;”不就解決問(wèn)題了!用comInputModeText方式就可完成任務(wù)了,只是多了一段數(shù)據(jù)分離程序。對(duì)于一般通訊要求這種方法不為是一種好方法。由于通訊任務(wù)是多種多樣的,有時(shí)候這種方法就有點(diǎn)力不從心了,如傳送較多的的數(shù)據(jù)時(shí),這會(huì)顯著地增加通訊量,通訊變得復(fù)雜了,對(duì)于單片機(jī)系統(tǒng)就不太合適了;還有一些特殊要求,如數(shù)據(jù)包的識(shí)別符也不適此法,但能確定傳送數(shù)據(jù)碼值范圍也可用此法。下面介紹另一種方法,此法適用比較廣,傳送二進(jìn)制數(shù)據(jù)通訊量增加也不大。
這種方法實(shí)際上很簡(jiǎn)單,實(shí)際運(yùn)用中有不少采用此法。原理是一碼分為二碼。如設(shè)7E為臨界字符,對(duì)于7E則分為7E和0兩個(gè)ASCII碼,依此類推,8F分為7E和11。接收合并時(shí)遇到7E則將7E和后一個(gè)ASCII碼相加為下字符。下面給出C語(yǔ)言函數(shù),VB轉(zhuǎn)換一下便可。
由于C語(yǔ)言不能返回兩個(gè)參數(shù),所以用數(shù)組指針。


void Filt(char code[],char c)
{
if(c=='F')
{
if(code[0]>=0X7E)
{
code[1]=code[0]-0X7E;
code[0]=0X7E;
}
else
{
code[1]=0XFF; /*0XFF作為標(biāo)記code[1]不可能產(chǎn)生0XFF*/
}
}
else if(c=='H')
{
if(code[0]!=0X7E)
{
code[1]=0xFE; /*轉(zhuǎn)換完成標(biāo)記*/
}
else
{
if(code[1]==0XFE)
{
code[1]=0XFF; /*接收下一個(gè)碼的標(biāo)記*/
}
else
{
code[0]=code[0]+code[1];
code[1]=0XFE;
}
}
}
發(fā)送時(shí):
char SendChar[2]; /*存儲(chǔ)發(fā)送的值*/
....
SendChar[0]=c; /*c為待發(fā)ASCII碼*/
Filt(SendChar,'F');
if(SendChar(1)==0XFF)
{
..... /*發(fā)送SendChar[0]*/
}
else
{
...... /*發(fā)送SendChar[0],SendChar[1]*/
}
接收時(shí):
char ReceiveChar[2]; /*存儲(chǔ)接收的值*/
.....
ReceiveChar[0]=c0; /*c0接收的ASCII碼*/
Filt(ReceiveChar,'H');
if(ReceiveChar[1]==0xFF)
{
ReceiveChar[1]=c1; /*c1為下一個(gè)*/
Filt(ReceiveChar,'H);
}
else if(ReceiveChar[1]==0xFE)
{
...... /*存儲(chǔ)轉(zhuǎn)換后的ReceiveChar[0]*/
}
以上代碼僅提供一種思路,實(shí)際情況視編程需要而定。


串口通訊問(wèn)答錄
1、Q:各位vb高手:我有一個(gè)問(wèn)題想請(qǐng)教一下。我從COM口用BIN方式接收到數(shù)據(jù)(一串漢字),存入一BYTE數(shù)組,但無(wú)法還原為一串漢字,我認(rèn)為是ANSI和UNICODE的轉(zhuǎn)換,請(qǐng)問(wèn)如何轉(zhuǎn)換。
例:字符串“我”,按BIN方式接收成一BYTE數(shù)組,其值為“206,210”,如用“CHR(206)+CHR(210)”卻無(wú)法得到“我”,實(shí)際上“我”=CHR(-12860)請(qǐng)問(wèn)如何能實(shí)現(xiàn)BYTE數(shù)組(206,210)與字符串“我”之間的轉(zhuǎn)換?萬(wàn)分感謝。!

JY
1999.10
A:經(jīng)CHR(206)+CHR(210)轉(zhuǎn)換后實(shí)際上變成了兩個(gè)UNICODE字符,四個(gè)字節(jié)了。漢字的收發(fā)必須用BINARY方式。下面的程序能實(shí)現(xiàn)漢字收發(fā)。
發(fā):
Dim ytemp() As Byte
Dim stemp As String
stemp = "你好!"
ytemp = StrConv(stemp, vbFromUnicode)
Debug.Print UBound(ytemp)
MSComm1.Output = ytemp
收:
Private Sub mscTest_OnComm()
'中文收發(fā)
Dim yTemp() As Byte
Dim stemp As String
Dim i As Integer
If mscTest.InBufferCount > 0 Then
i = mscTest.InBufferCount
yTemp = mscTest.Input
stemp = StrConv(yTemp, vbUnicode)
txtTest1.Text = stemp
End If
End Sub


分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表