Visual Basic串口通訊調(diào)試方法
2024-07-21 02:20:43
供稿:網(wǎng)友
現(xiàn)有電子秤一臺,使用串口與計算機(jī)進(jìn)行通訊。編寫vb程序來訪問串口,達(dá)到讀取電子秤上顯示的數(shù)據(jù)。該電子秤為be01型儀表,輸出為rs-232c標(biāo)準(zhǔn)接口,波特率為300-9600、偶校驗、7個數(shù)據(jù)位、2個停止位。所有字符均發(fā)送11位ascii碼,一個起始位。在vb中與串口通訊需要引入控件mscomm串口通訊控件(在microsoft comm control 6.0中)。具體程序如下:控件簡稱:msc
dim out(12) as byte '接收var中的值
dim var as variant '接收msc.input中的數(shù)值
dim nrece as integer '計算msc.inputbuffer的個數(shù)
dim i as integer, j as integer '隨即變量,計算循環(huán)
****************************************************************************
private sub form_load()
cleartext
with msc
.commport = 1 '設(shè)置com1為通信端口
.settings = "9600,e,7,2" '設(shè)置通信端口參數(shù) 9600赫茲、偶校驗、7個數(shù)據(jù)位、1個停止位.(這里需要進(jìn)一步說明的是:.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è)置接收一個字節(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 '計數(shù)器清零
with msc
.inputmode = cominputmodebinary '設(shè)置數(shù)據(jù)接收模式為二進(jìn)制形式
.inbuffercount = 0 '清除接收緩沖區(qū)
if not .portopen then
.portopen = true '打開通信端口
end if
end with
end sub
private sub msc_oncomm()
delaytime ‘用來延續(xù)時間
cleartext
with msc
select case .commevent '判斷通信事件
case comevreceive: '收到rthreshold個字節(jié)產(chǎn)生的接收事件
swichvar 1
if out(1) = 2 then '判斷是否為數(shù)據(jù)的開始標(biāo)志
.rthreshold = 0 '關(guān)閉oncomm事件接收
end if
do
doevents
loop until .inbuffercount >= 3 '循環(huán)等待接收緩沖區(qū)>=3個字節(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 '打開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可以計算從子夜到現(xiàn)在所經(jīng)過的秒數(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ā)送一個字節(jié),儀表每秒發(fā)送50幀數(shù)據(jù),每幀數(shù)據(jù)有4個字節(jié),即每秒發(fā)送200個字節(jié),平均5.0ms 發(fā)送一個字節(jié),連續(xù)讀取串口數(shù)據(jù)時要在程序中添加循環(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ù)時,不能直接賦值給 byte 類型變量,只能通過先賦值給一個 variant 類型變量,返回一個二進(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
(儀表每秒發(fā)送50幀數(shù)據(jù),微機(jī)收到一幀完整數(shù)據(jù)至少需要20 ms時間,然后再進(jìn)行數(shù)據(jù)處理。如果微機(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控制;如果微機(jī)在20ms內(nèi)不能將數(shù)據(jù)計算處理完畢,接收緩沖區(qū)設(shè)置得又很大,在數(shù)據(jù)計算處理完畢前,接收緩沖區(qū)內(nèi)就會保存有兩幀以上數(shù)據(jù),而且一次工作時間越長,緩沖區(qū)內(nèi)滯留數(shù)據(jù)幀就越多,數(shù)據(jù)采集和數(shù)據(jù)處理之間產(chǎn)生逐漸增大的額外時間差,當(dāng)接收緩沖區(qū)充滿后,時間差不再增大,固定在某一值,部分?jǐn)?shù)據(jù)因不能及時采集到接收緩沖區(qū)中,數(shù)據(jù)產(chǎn)生丟失現(xiàn)象,真實工作情況就會和微機(jī)處理結(jié)果產(chǎn)生較大的時間差,對實時監(jiān)測和實時控制很不利,這種情況下接收緩沖區(qū)的大小就會影響實時監(jiān)測效果,所以接收緩沖區(qū)設(shè)置不能過大,以保證數(shù)據(jù)處理的實時性。) 小結(jié):本文所用的儀表為梅特勒公司出產(chǎn)的be01型電子秤,其輸出的每個編碼均為標(biāo)準(zhǔn)的ascii碼。其他的儀表存在發(fā)射的編碼中含有bcd壓縮碼,而且分為高低位,需要接收后對其進(jìn)行解碼換算,之后還要將高位和低位數(shù)字進(jìn)行相加,即可以將其bcd碼換算成實數(shù)。另還存在誤差的可能:判斷最大值,儀表在剛開始工作時有干擾,會傳導(dǎo)一些亂碼,位移傳感器有參數(shù)偏差,最大值一般都略大于50毫米,所以取51為極限最大值,取-51為極限最小值。暫時先寫這些,當(dāng)然其他的情況可以依此類推!