?? vb2.txt
字號:
本文介紹VB6.0利用MSComm通信控件,開發(fā)微機通過串口對工業(yè)儀表進行實時數(shù)據(jù)采集的編程技術。給出的程序代碼具有通用性,并有詳細的注釋,可以直接或稍加改動后用于其他數(shù)據(jù)采集或?qū)崟r控制程序中。
----一臺工業(yè)專用實時檢測儀表,接高精度位移傳感器,用于測量微小形變或微量位移,儀表測量精度為0.01毫米,測量范圍最大值為50毫米。該儀表帶有一個9針的RS-232C 串口,能與微機進行串口數(shù)據(jù)通信,實時傳送檢測數(shù)據(jù),通過微機軟件處理可實現(xiàn)工業(yè)實時監(jiān)控。
----該儀表的串口數(shù)據(jù)通信協(xié)議是:數(shù)據(jù)傳輸速率為 9600bps,1位開始位,8位數(shù)據(jù)位,1位停止位,無奇偶校驗位。儀表每秒發(fā)送50幀檢測數(shù)據(jù),每幀數(shù)據(jù)由4個字節(jié)組成。第一個字節(jié)定義為二進制常數(shù)0F0H,是每幀數(shù)據(jù)開始的標志字節(jié);后面連續(xù)2個字節(jié)為數(shù)據(jù)字節(jié),采用壓縮的BCD碼編碼方式,高位在前,低位在后,即一個字節(jié)表示兩位十進制數(shù),則兩個字節(jié)表示四位十進制數(shù),小數(shù)點采用固定形式,定義在兩字節(jié)中間;第四個字節(jié)為符號字節(jié),該字節(jié)第八位為1,即:
----則為負數(shù);第八位為0,即:
----則為正數(shù)。
----例如:0F0H 26H 87H 80H 0F0H 34H 62H 00H 表示 -26.87 34.62。
----通信傳輸速率為9600bps,則最快速度1.04ms發(fā)送一個字節(jié),儀表每秒發(fā)送50幀數(shù)據(jù),每幀數(shù)據(jù)有4個字節(jié),即每秒發(fā)送200個字節(jié),平均5.0ms 發(fā)送一個字節(jié),連續(xù)讀取串口數(shù)據(jù)時要在程序中添加循環(huán)等待程序。
----為了實現(xiàn)實時監(jiān)測功能,接收數(shù)據(jù)的讀取要盡可能的快速,則設置MSComm1的屬性如下:
RThreshold = 1
接收緩沖區(qū)收到一個字節(jié)產(chǎn)生OnComm事件
InputLen = 1 每次讀取一個字節(jié)
----儀表每秒發(fā)送50幀數(shù)據(jù),微機收到一幀完整數(shù)據(jù)至少需要20 ms時間,然后再進行數(shù)據(jù)處理。如果微機在下一幀數(shù)據(jù)接收前即20ms內(nèi)能將數(shù)據(jù)計算處理完畢,則接收緩沖區(qū)內(nèi)只會保存有一幀數(shù)據(jù),不會存有兩幀以上數(shù)據(jù),接收緩沖區(qū)的大小不會影響實時監(jiān)測效果(接收緩沖區(qū)>4字節(jié)),這時完全可以實現(xiàn)實時監(jiān)測或?qū)崟r控制;如果微機在20ms內(nèi)不能將數(shù)據(jù)計算處理完畢,接收緩沖區(qū)設置得又很大,在數(shù)據(jù)計算處理完畢前,接收緩沖區(qū)內(nèi)就會保存有兩幀以上數(shù)據(jù),而且一次工作時間越長,緩沖區(qū)內(nèi)滯留數(shù)據(jù)幀就越多,數(shù)據(jù)采集和數(shù)據(jù)處理之間產(chǎn)生逐漸增大的額外時間差,當接收緩沖區(qū)充滿后,時間差不再增大,固定在某一值,部分數(shù)據(jù)因不能及時采集到接收緩沖區(qū)中,數(shù)據(jù)產(chǎn)生丟失現(xiàn)象,真實工作情況就會和微機處理結果產(chǎn)生較大的時間差,對實時監(jiān)測和實時控制很不利,這種情況下接收緩沖區(qū)的大小就會影響實時監(jiān)測效果,所以接收緩沖區(qū)設置不能過大,以保證數(shù)據(jù)處理的實時性。
----設置接收數(shù)據(jù)模式采用二進制形式,即 InputMode=comInputModeBinary,但用Input屬性讀取數(shù)據(jù)時,不能直接賦值給 Byte 類型變量,只能通過先賦值給一個 Variant 類型變量,返回一個二進制數(shù)據(jù)的數(shù)組,再轉(zhuǎn)換保存到Byte類型數(shù)變量中。
----VB中有Byte類型變量,但沒有字節(jié)的位處理語句,符號字節(jié)的位處理要判斷符號字節(jié)的值是否大于 127,大于127則為負數(shù);壓縮的BCD碼存入 Byte類型變量,VB系統(tǒng)只按十進制數(shù)處理,這要通過一個簡單算法換算,解壓BCD碼才能還原成十進制表示數(shù)值。假如a是Byte類型變量,D是Single類型變量,將一個壓縮的BCD 碼存入a中,則算法是:
D=(a\16)*10 + a-(a\16)*16
則D=a-(a\16)*6
----程序清單:
----在通用聲明中定義程序所用變量:
Dim ab(4) As Byte
‘字節(jié)數(shù)據(jù)類型數(shù)組,用來存儲接收到的一組字節(jié)數(shù)據(jù)
Dim av As Variant ‘用來從接收緩沖區(qū)讀取數(shù)據(jù)
Dim i As Integer
Dim j As Integer
Dim w As Integer ‘接收數(shù)據(jù)個數(shù)計數(shù)器
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控制的參數(shù)初始化設置,程序中大部分參數(shù)在設計時可在MSComm1控制的屬性窗口中設置:
Private Sub Command1_Click()
‘開始按鈕
With MSComm1
.CommPort=2 ‘使用COM2
.Setting=“9600,N,8,1" ‘設置通信口參數(shù)
.InBufferSize=40
‘設置MSComm1接收緩沖區(qū)為40字節(jié)
.OutBufferSize=2
‘設置MSComm1發(fā)送緩沖區(qū)為2字節(jié)
.InputMode = comInputModeBinary
‘設置接收數(shù)據(jù)模式為二進制形式
.InputLen = 1
‘設置Input 一次從接收緩沖讀取字節(jié)數(shù)為1
.SThreshold = 1
‘設置Output 一次從發(fā)送緩沖讀取字節(jié)數(shù)為1
.InBufferCount = 0 ‘清除接收緩沖區(qū)
.OutBufferCount = 0 ‘清除發(fā)送緩沖區(qū)
MaxW = -99
‘最大值賦初值
MinW = 99 ‘最小值賦初值
w = 0
‘數(shù)據(jù)個數(shù)計數(shù)器清零
.RThreshold = 1
‘設置接收一個字節(jié)產(chǎn)生OnComm事件
If .PortOpen = False Then
‘判斷通信口是否打開
.PortOpen = True ‘打開通信口
If Err Then ‘錯誤處理
MsgBox “串口通信無效"
Exit Sub
End If
End If
End With
End Sub
----為了達到實時數(shù)據(jù)采集目的,實時數(shù)據(jù)采集處理程序采用MSComm事件驅(qū)動方式。
----MSComm1_OnComm的事件處理程序只處理 comEvReceive事件,首先判斷幀數(shù)據(jù)的開始字節(jié),關閉OnComm接收事件,然后接收數(shù)據(jù)字節(jié),將壓縮BCD進行還原轉(zhuǎn)換,再接收符號字節(jié),判斷數(shù)據(jù)符號,判斷數(shù)據(jù)最大最小值,最后打開OnComm接收事件,等待下一次OnComm事件產(chǎn)生:
Private Sub MSComm1_OnComm()
With MSComm1
Select Case .CommEvent
‘判斷MSComm1通信事件
Case comEvReceive
‘收到Rthreshold個字節(jié)產(chǎn)生的接收事件
av = .Input
‘讀取一個接收字節(jié)
ab(1) = av(0)
‘轉(zhuǎn)換保存到字節(jié)數(shù)據(jù)類型數(shù)組
If ab(1) = &HF0 Then
‘判斷是否為數(shù)據(jù)開始標志
RThreshold = 0
‘關閉OnComm事件接收
Do
DoEvents
Loop Until .InBufferCount >= 3
‘循環(huán)等待MSComm1接收緩沖區(qū)>=3個字節(jié)
w = w + 1 ‘計數(shù)器累加計數(shù)
av = .Input
‘讀取第二個數(shù)據(jù)字節(jié)(BCD碼高位字節(jié))
ab(2) = av(0)
‘轉(zhuǎn)換保存到字節(jié)數(shù)據(jù)類型數(shù)組
av = .Input
‘讀取第三個數(shù)據(jù)字節(jié)(BCD碼低位字節(jié))
ab(3) = av(0)
‘轉(zhuǎn)換保存到字節(jié)數(shù)據(jù)類型數(shù)組
av = .Input
‘讀取第四個數(shù)據(jù)字節(jié)(符號位字節(jié))
ab(4) = av(0)
‘轉(zhuǎn)換保存到字節(jié)數(shù)據(jù)類型數(shù)組
b1 = ab(2) - 6 * (ab(2)\16)
‘高位字節(jié)壓縮BCD碼轉(zhuǎn)換為實數(shù)
b2 = ab(3) - 6 * (ab(3)\16)
‘低位字節(jié)壓縮BCD碼轉(zhuǎn)換為實數(shù)
WW = b1 + b2 / 100
‘數(shù)值組合,標定小數(shù)點
If ab(4) > 127 Then WW=
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -