----一台工業專用實時檢測儀表,接高精度位移傳感器,用於測量微小形變或微量位移,儀表測量精度為0.01毫米,測量範圍最大值為50毫米。該儀表帶有一個9針的rs-232c 串口,能與微機進行串口數據通信,實時傳送檢測數據,通過微機軟件處理可實現工業實時監控。
----該儀表的串口數據通信協議是:數據傳輸速率為 9600bps,1位開始位,8位數據位,1位停止位,無奇偶校驗位。儀表每秒發送50幀檢測數據,每幀數據由4個字節組成。第一個字節定義為二進製常數0f0h,是每幀數據開始的標誌字節;後麵連續2個字節為數據字節,采用壓縮的bcd碼(ma)編(bian)碼(ma)方(fang)式(shi),高(gao)位(wei)在(zai)前(qian),低(di)位(wei)在(zai)後(hou),即(ji)一(yi)個(ge)字(zi)節(jie)表(biao)示(shi)兩(liang)位(wei)十(shi)進(jin)製(zhi)數(shu),則(ze)兩(liang)個(ge)字(zi)節(jie)表(biao)示(shi)四(si)位(wei)十(shi)進(jin)製(zhi)數(shu),小(xiao)數(shu)點(dian)采(cai)用(yong)固(gu)定(ding)形(xing)式(shi),定(ding)義(yi)在(zai)兩(liang)字(zi)節(jie)中(zhong)間(jian);第四個字節為符號字節,該字節第八位為1,即:
![圖]()
----則為負數;第八位為0,即:
![圖]()
----則為正數。
----例如:0f0h 26h 87h 80h 0f0h 34h 62h 00h 表示 -26.87 34.62。
----通信傳輸速率為9600bps,則最快速度1.04ms發送一個字節,儀表每秒發送50幀數據,每幀數據有4個字節,即每秒發送200個字節,平均5.0ms 發送一個字節,連續讀取串口數據時要在程序中添加循環等待程序。
----為了實現實時監測功能,接收數據的讀取要盡可能的快速,則設置mscomm1的屬性如下:
rthreshold = 1
接收緩衝區收到一個字節產生oncomm事件
inputlen = 1 每次讀取一個字節
----儀表每秒發送50幀數據,微機收到一幀完整數據至少需要20 ms時間,然後再進行數據處理。如果微機在下一幀數據接收前即20ms內能將數據計算處理完畢,則接收緩衝區內隻會保存有一幀數據,不會存有兩幀以上數據,接收緩衝區的大小不會影響實時監測效果(接收緩衝區>4字節),這時完全可以實現實時監測或實時控製;如果微機在20ms內(nei)不(bu)能(neng)將(jiang)數(shu)據(ju)計(ji)算(suan)處(chu)理(li)完(wan)畢(bi),接(jie)收(shou)緩(huan)衝(chong)區(qu)設(she)置(zhi)得(de)又(you)很(hen)大(da),在(zai)數(shu)據(ju)計(ji)算(suan)處(chu)理(li)完(wan)畢(bi)前(qian),接(jie)收(shou)緩(huan)衝(chong)區(qu)內(nei)就(jiu)會(hui)保(bao)存(cun)有(you)兩(liang)幀(zhen)以(yi)上(shang)數(shu)據(ju),而(er)且(qie)一(yi)次(ci)工(gong)作(zuo)時(shi)間(jian)越(yue)長(chang),緩(huan)衝(chong)區(qu)內(nei)滯(zhi)留(liu)數(shu)據(ju)幀(zhen)就(jiu)越(yue)多(duo),數(shu)據(ju)采(cai)集(ji)和(he)數(shu)據(ju)處(chu)理(li)之(zhi)間(jian)產(chan)生(sheng)逐(zhu)漸(jian)增(zeng)大(da)的(de)額(e)外(wai)時(shi)間(jian)差(cha),當(dang)接(jie)收(shou)緩(huan)衝(chong)區(qu)充(chong)滿(man)後(hou),時(shi)間(jian)差(cha)不(bu)再(zai)增(zeng)大(da),固(gu)定(ding)在(zai)某(mou)一(yi)值(zhi),部(bu)分(fen)數(shu)據(ju)因(yin)不(bu)能(neng)及(ji)時(shi)采(cai)集(ji)到(dao)接(jie)收(shou)緩(huan)衝(chong)區(qu)中(zhong),數(shu)據(ju)產(chan)生(sheng)丟(diu)失(shi)現(xian)象(xiang),真(zhen)實(shi)工(gong)作(zuo)情(qing)況(kuang)就(jiu)會(hui)和(he)微(wei)機(ji)處(chu)理(li)結(jie)果(guo)產(chan)生(sheng)較(jiao)大(da)的(de)時(shi)間(jian)差(cha),對(dui)實(shi)時(shi)監(jian)測(ce)和(he)實(shi)時(shi)控(kong)製(zhi)很(hen)不(bu)利(li),這(zhe)種(zhong)情(qing)況(kuang)下(xia)接(jie)收(shou)緩(huan)衝(chong)區(qu)的(de)大(da)小(xiao)就(jiu)會(hui)影(ying)響(xiang)實(shi)時(shi)監(jian)測(ce)效(xiao)果(guo),所(suo)以(yi)接(jie)收(shou)緩(huan)衝(chong)區(qu)設(she)置(zhi)不(bu)能(neng)過(guo)大(da),以(yi)保(bao)證(zheng)數(shu)據(ju)處(chu)理(li)的(de)實(shi)時(shi)性(xing)。
----設置接收數據模式采用二進製形式,即 inputmode=cominputmodebinary,但用input屬性讀取數據時,不能直接賦值給 byte 類型變量,隻能通過先賦值給一個 variant 類型變量,返回一個二進製數據的數組,再轉換保存到byte類型數變量中。
----vb中有byte類型變量,但沒有字節的位處理語句,符號字節的位處理要判斷符號字節的值是否大於 127,大於127則為負數;壓縮的bcd碼存入 byte類型變量,vb係統隻按十進製數處理,這要通過一個簡單算法換算,解壓bcd碼才能還原成十進製表示數值。假如a是byte類型變量,d是single類型變量,將一個壓縮的bcd 碼存入a中,則算法是:
d=(a\16)*10 + a-(a\16)*16
則d=a-(a\16)*6
----程序清單:
----在通用聲明中定義程序所用變量:
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
----‘判斷最大值,儀表在剛開始工作時有幹擾,會傳導一些亂碼,位移傳感器有參數偏差,最大值一般都略大於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 -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
----------------------------------------------
此篇文章從博客轉發
原文地址:
Http://blog.gkong.com/more.asp?id=69121&Name=yangyongxiang