----在通用聲明中定義程序所用變量:
Dim ab(4) As Byte
‘字節數據類型數組,用來存儲接收到的一組字節數據
Dim av As Variant ‘用來從接收緩沖區讀取數據
Dim i As Integer
Dim j As Integer
Dim w As Integer ‘接收數據個數計數器
Dim b1 As Single
Dim b2 As Single
Dim WW As Single ‘十進制檢測值
Dim MaxW As Single ‘最大值
Dim MinW As Single ‘最小值
----在窗體中添加名為Command1的[開始]按鈕和名為 MSComm1的MSComm控件。
---- [開始]按鈕的Click事件處理程序主要是對MSComm1控制的參數初始化設置,程序中大部分參數在設計時可在MSComm1控制的屬性窗口中設置:
Private Sub Command1_Click()
‘開始按鈕
With MSComm1
.CommPort=2 ‘使用COM2
.Setting=“9600,N,8,1" ‘設置通信口參數
.InBufferSize=40
‘設置MSComm1接收緩沖區為40字節
.OutBufferSize=2
‘設置MSComm1發送緩沖區為2字節
.InputMode = comInputModeBinary
‘設置接收數據模式為二進制形式
.InputLen = 1
‘設置Input 一次從接收緩沖讀取字節數為1
.SThreshold = 1
‘設置Output 一次從發送緩沖讀取字節數為1
.InBufferCount = 0 ‘清除接收緩沖區
.OutBufferCount = 0 ‘清除發送緩沖區
MaxW = -99
‘最大值賦初值
MinW = 99 ‘最小值賦初值
w = 0
‘數據個數計數器清零
.RThreshold = 1
‘設置接收一個字節產生OnComm事件
If .PortOpen = False Then
‘判斷通信口是否打開
.PortOpen = True ‘打開通信口
If Err Then ‘錯誤處理
MsgBox “串口通信無效"
Exit Sub
End If
End If
End With
End Sub
----為了達到實時數據采集目的,實時數據采集處理程序采用MSComm事件驅動方式。
----MSComm1_OnComm的事件處理程序只處理 comEvReceive事件,首先判斷幀數據的開始字節,關閉OnComm接收事件,然后接收數據字節,將壓縮BCD進行還原轉換,再接收符號字節,判斷數據符號,判斷數據最大最小值,最后打開OnComm接收事件,等待下一次OnComm事件產生:
Private Sub MSComm1_OnComm()
With MSComm1
Select Case .CommEvent
‘判斷MSComm1通信事件
Case comEvReceive
‘收到Rthreshold個字節產生的接收事件
av = .Input
‘讀取一個接收字節
ab(1) = av(0)
‘轉換保存到字節數據類型數組
If ab(1) = &HF0 Then
‘判斷是否為數據開始標志
RThreshold = 0
‘關閉OnComm事件接收
Do
DoEvents
Loop Until .InBufferCount >= 3
‘循環等待MSComm1接收緩沖區>=3個字節
w = w + 1 ‘計數器累加計數
av = .Input
‘讀取第二個數據字節(BCD碼高位字節)
ab(2) = av(0)
‘轉換保存到字節數據類型數組
av = .Input
‘讀取第三個數據字節(BCD碼低位字節)
ab(3) = av(0)
‘轉換保存到字節數據類型數組
av = .Input
‘讀取第四個數據字節(符號位字節)
ab(4) = av(0)
‘轉換保存到字節數據類型數組
b1 = ab(2) - 6 * (ab(2)\16)
‘高位字節壓縮BCD碼轉換為實數
b2 = ab(3) - 6 * (ab(3)\16)
‘低位字節壓縮BCD碼轉換為實數
WW = b1 + b2 / 100
‘數值組合,標定小數點
If ab(4) > 127 Then WW=?WW
‘判斷數據符號位
Label1(0) = Format(WW, “0.00")
‘顯示毫米單位數值,2位小數
Label1(1) =Format(WW /25.4, “0.000")
‘顯示英寸單位數值,3位小數
If WW > MaxW And WW < 51 Then
----‘判斷最大值,儀表在剛開始工作時有干擾,會傳導一些亂碼,位移傳感器有參數偏差,最大值一般都略大于50毫米,所以取51為極限最大值,取-51為極限最小值。
MaxW = WW
Label1(2) = Format(MaxW, “0.00")
‘顯示毫米單位最大值,2位小數
Label1(3) = Format(MaxW/25.4,“0.000")
‘顯示英寸單位最大值,3位小數
End If
If WW < MinW And WW > -51 Then
‘判斷最小值
MinW = WW
Label1(4) = Format(MinW, “0.00")
‘顯示毫米單位最小值,2位小數
Label1(5) = Format(MinW/25.4,“0.000")
‘顯示英寸單位最小值,3位小數
End If
.RThreshold = 1
‘打開MSComm1事件接收
End If
Case Else
End Select
End With
End Sub
VB有一個例子在Samples\CompTool\Mscomm中。你可以利用這個例子來學習串口編程。
打開串口先設置CommPort屬性(端口號),使用PortOpen=True就可以了。
串口數據保存在MSComm的Input屬性中。你可以使用下面的代碼:
Dim v As Variant
v = MSComm1.Input
For i = 0 To MSComm1.InBufferCount - 1
Debug.Print v(i)
Next
現有電子秤一臺,使用串口與計算機進行通訊。編寫VB程序來訪問串口,達到讀取電子秤上顯示的數據。該電子秤為BE01型儀表,輸出為RS-232C標準接口,波特率為300-9600、偶校驗、7個數據位、2個停止位。所有字符均發送11位ASCII碼,一個起始位。在VB中與串口通訊需要引入控件MSComm串口通訊控件(在Microsoft Comm Control 6.0中)。具體程序如下:控件簡稱:MSC
Dim Out(12) As Byte '接收var中的值
Dim var As Variant '接收MSC.input中的數值
Dim nRece As Integer '計算MSC.inputbuffer的個數
Dim i As Integer, j As Integer '隨即變量,計算循環
Private Sub ClearText()
Text3.Text = ""
Text2.Text = "5"
Text1.Text = ""
End Sub
Private Sub Command1_Click()
ClearText
' nRece = 0 '計數器清零
With MSC
.InputMode = comInputModeBinary '設置數據接收模式為二進制形式
.InBufferCount = 0 '清除接收緩沖區
If Not .PortOpen Then
.PortOpen = True '打開通信端口
End If
End With
End Sub
Private Sub MSC_OnComm()
DelayTime ‘用來延續時間
ClearText
With MSC
Select Case .CommEvent '判斷通信事件
Case comEvReceive: '收到Rthreshold個字節產生的接收事件
SwichVar 1
If Out(1) = 2 Then '判斷是否為數據的開始標志
.RThreshold = 0 '關閉OnComm事件接收
End If
Do
DoEvents
Loop Until .InBufferCount >= 3 '循環等待接收緩沖區>=3個字節
' 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 '打開MSComm事件接收
Case Else
' .PortOpen = False
End Select
End With
Private Sub MSComm_OnComm ()
Select Case MSComm1.CommEvent
' 錯誤
Case comEventBreak ' 收到 Break。
Case comEventCDTO ' CD (RLSD) 超時。
Case comEventCTSTO ' CTS Timeout。
Case comEventDSRTO ' DSR Timeout。
Case comEventFrame ' Framing Error
Case comEventOverrun '數據丟失。
Case comEventRxOver'接收緩沖區溢出。
Case comEventRxParity' Parity 錯誤。
Case comEventTxFull '傳輸緩沖區已滿。
Case comEventDCB '獲取 DCB] 時意外錯誤
' 事件
Case comEvCD ' CD 線狀態變化。
Case comEvCTS ' CTS 線狀態變化。
Case comEvDSR ' DSR 線狀態變化。
Case comEvRing ' Ring Indicator 變化。
Case comEvReceive ' 收到 RThreshold # of chars.
Case comEvSend ' 傳輸緩沖區有 Sthreshold 個字符 '
Case comEvEof ' 輸入數據流中發現 EOF 字符
Private Sub TmrComm_Timer()
'采用輪循法采集數據
Dim Rx_buff() As Byte
Dim okstring As String
Dim ReceivedLen As Integer
On Error GoTo ErrorHandler
TmrComm.Enabled = False '關閉定時器
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 '打開定時器
End Sub
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 函數,掛起當前進程一段時間
Loop Until comReceive.InBufferCount = nReceiveCount
If comReceive.PortOpen = True Then
sComm = comReceive.Input
End If
End Function
注:此函數參照了xth一文。
此法一般是能確保數據接收的正確,但由于WINDOWS是多任務操作系統,當有耗時的進程運行時會丟失數據。如果系統會出現這種情況,可增大函數sleep()的參數值。
JY
1999.10
A:經CHR(206)+CHR(210)轉換后實際上變成了兩個UNICODE字符,四個字節了。漢字的收發必須用BINARY方式。下面的程序能實現漢字收發。
發:
Dim ytemp() As Byte
Dim stemp As String
stemp = "你好!"
ytemp = StrConv(stemp, vbFromUnicode)
Debug.Print UBound(ytemp)
MSComm1.Output = ytemp
收:
Private Sub mscTest_OnComm()
'中文收發
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