發表于:2008/11/25 22:16:00
#0樓
----一臺工業專用實時檢測儀表,接高精度位移傳感器,用于測量微小形變或微量位移,儀表測量精度為0.01毫米,測量范圍最大值為50毫米。該儀表帶有一個9針的rs-232c 串口,能與微機進行串口數據通信,實時傳送檢測數據,通過微機軟件處理可實現工業實時監控。
----該儀表的串口數據通信協議是:數據傳輸速率為 9600bps,1位開始位,8位數據位,1位停止位,無奇偶校驗位。儀表每秒發送50幀檢測數據,每幀數據由4個字節組成。第一個字節定義為二進制常數0f0h,是每幀數據開始的標志字節;后面連續2個字節為數據字節,采用壓縮的bcd碼編碼方式,高位在前,低位在后,即一個字節表示兩位十進制數,則兩個字節表示四位十進制數,小數點采用固定形式,定義在兩字節中間;第四個字節為符號字節,該字節第八位為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內不能將數據計算處理完畢,接收緩沖區設置得又很大,在數據計算處理完畢前,接收緩沖區內就會保存有兩幀以上數據,而且一次工作時間越長,緩沖區內滯留數據幀就越多,數據采集和數據處理之間產生逐漸增大的額外時間差,當接收緩沖區充滿后,時間差不再增大,固定在某一值,部分數據因不能及時采集到接收緩沖區中,數據產生丟失現象,真實工作情況就會和微機處理結果產生較大的時間差,對實時監測和實時控制很不利,這種情況下接收緩沖區的大小就會影響實時監測效果,所以接收緩沖區設置不能過大,以保證數據處理的實時性。
----設置接收數據模式采用二進制形式,即 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
----該儀表的串口數據通信協議是:數據傳輸速率為 9600bps,1位開始位,8位數據位,1位停止位,無奇偶校驗位。儀表每秒發送50幀檢測數據,每幀數據由4個字節組成。第一個字節定義為二進制常數0f0h,是每幀數據開始的標志字節;后面連續2個字節為數據字節,采用壓縮的bcd碼編碼方式,高位在前,低位在后,即一個字節表示兩位十進制數,則兩個字節表示四位十進制數,小數點采用固定形式,定義在兩字節中間;第四個字節為符號字節,該字節第八位為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內不能將數據計算處理完畢,接收緩沖區設置得又很大,在數據計算處理完畢前,接收緩沖區內就會保存有兩幀以上數據,而且一次工作時間越長,緩沖區內滯留數據幀就越多,數據采集和數據處理之間產生逐漸增大的額外時間差,當接收緩沖區充滿后,時間差不再增大,固定在某一值,部分數據因不能及時采集到接收緩沖區中,數據產生丟失現象,真實工作情況就會和微機處理結果產生較大的時間差,對實時監測和實時控制很不利,這種情況下接收緩沖區的大小就會影響實時監測效果,所以接收緩沖區設置不能過大,以保證數據處理的實時性。
----設置接收數據模式采用二進制形式,即 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