用VB進行串口實時數據採集

 本文介紹VB6.0利用MSComm通信控件,開發微機通過串口對工業儀表進行實時數據採集的編程技術。給出的程序代碼具有通用性,並有詳細的註釋,可以直接或稍加改動後用於其他數據採集或實時控制程序中。
----一臺工業專用實時檢測儀表,接高精度位移傳感器,用於測量微小形變或微量位移,儀表測量精度爲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=(a16)*10 + a-(a16)*16 
則D=a-(a16)*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 < 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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章