用VB进行串口实时数据采集.docx

上传人:b****0 文档编号:12763685 上传时间:2023-04-22 格式:DOCX 页数:34 大小:63.29KB
下载 相关 举报
用VB进行串口实时数据采集.docx_第1页
第1页 / 共34页
用VB进行串口实时数据采集.docx_第2页
第2页 / 共34页
用VB进行串口实时数据采集.docx_第3页
第3页 / 共34页
用VB进行串口实时数据采集.docx_第4页
第4页 / 共34页
用VB进行串口实时数据采集.docx_第5页
第5页 / 共34页
点击查看更多>>
下载资源
资源描述

用VB进行串口实时数据采集.docx

《用VB进行串口实时数据采集.docx》由会员分享,可在线阅读,更多相关《用VB进行串口实时数据采集.docx(34页珍藏版)》请在冰豆网上搜索。

用VB进行串口实时数据采集.docx

用VB进行串口实时数据采集

用VB进行串口实时数据采集

VB-界面速成通道/ChenLL 发表于2007-08-10,20:

28

用VB进行串口实时数据采集

本文介绍VB6.0利用MSComm通信控件,开发微机通过串口对工业仪表进行实时数据采集的编程技术。

给出的程序代码具有通用性,并有详细的注释,可以直接或稍加改动后用于其他数据采集或实时控制程序中。

----一台工业专用实时检测仪表,接高精度位移传感器,用于测量微小形变或微量位移,仪表测量精度为0.01毫米,测量范围最大值为50毫米。

该仪表带有一个9针的RS-232C串口,能与微机进行串口数据通信,实时传送检测数据,通过微机软件处理可实现工业实时监控。

----该仪表的串口数据通信协议是:

数据传输速率为9600bps,1位开始位,8位数据位,1位停止位,无奇偶校验位。

仪表每秒发送50帧检测数据,每帧数据由4个字节组成。

第一个字节定义为二进制常数0F0H,是每帧数据开始的标志字节;后面连续2个字节为数据字节,采用压缩的BCD码编码方式,高位在前,低位在后,即一个字节表示两位十进制数,则两个字节表示四位十进制数,小数点采用固定形式,定义在两字节中间;第四个字节为符号字节,该字节第八位为1,即:

1xxxxxxx 则为负数;第八位为0,即:

0xxxxxxx则为正数。

----例如:

0F0H26H87H80H0F0H34H62H00H表示-26.8734.62。

----通信传输速率为9600bps,则最快速度1.04ms发送一个字节,仪表每秒发送50帧数据,每帧数据有4个字节,即每秒发送200个字节,平均5.0ms发送一个字节,连续读取串口数据时要在程序中添加循环等待程序。

----为了实现实时监测功能,接收数据的读取要尽可能的快速,则设置MSComm1的属性如下:

RThreshold=1

接收缓冲区收到一个字节产生OnComm事件

   InputLen=1              每次读取一个字节

----仪表每秒发送50帧数据,微机收到一帧完整数据至少需要20ms时间,然后再进行数据处理。

如果微机在下一帧数据接收前即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

----程序清单:

----在通用声明中定义程序所用变量:

Dimab(4)AsByte   

 ‘字节数据类型数组,用来存储接收到的一组字节数据

   DimavAsVariant‘用来从接收缓冲区读取数据

   DimiAsInteger

   DimjAsInteger

   DimwAsInteger  ‘接收数据个数计数器

   Dimb1AsSingle

   Dimb2AsSingle

   DimWWAsSingle          ‘十进制检测值

   DimMaxWAsSingle        ‘最大值

   DimMinWAsSingle        ‘最小值

----在窗体中添加名为Command1的[开始]按钮和名为MSComm1的MSComm控件。

----[开始]按钮的Click事件处理程序主要是对MSComm1控制的参数初始化设置,程序中大部分参数在设计时可在MSComm1控制的属性窗口中设置:

PrivateSubCommand1_Click()

       ‘开始按钮

 WithMSComm1

    .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=FalseThen                  

   ‘判断通信口是否打开

       .PortOpen=True         ‘打开通信口

       IfErrThen              ‘错误处理

         MsgBox“串口通信无效"

         ExitSub

       EndIf

    EndIf

 EndWith

EndSub

----为了达到实时数据采集目的,实时数据采集处理程序采用MSComm事件驱动方式。

----MSComm1_OnComm的事件处理程序只处理comEvReceive事件,首先判断帧数据的开始字节,关闭OnComm接收事件,然后接收数据字节,将压缩BCD进行还原转换,再接收符号字节,判断数据符号,判断数据最大最小值,最后打开OnComm接收事件,等待下一次OnComm事件产生:

PrivateSubMSComm1_OnComm()

 WithMSComm1

SelectCase.CommEvent

       ‘判断MSComm1通信事件

     CasecomEvReceive                      

              ‘收到Rthreshold个字节产生的接收事件

       av=.Input   

              ‘读取一个接收字节

       ab

(1)=av(0)                

              ‘转换保存到字节数据类型数组

       Ifab

(1)=&HF0Then                

         ‘判断是否为数据开始标志

         RThreshold=0                            

         ‘关闭OnComm事件接收

         Do

           DoEvents

         LoopUntil.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                

       ‘数值组合,标定小数点

         Ifab(4)>127ThenWW=WW

                 ‘判断数据符号位

         Label1(0)=Format(WW,“0.00")

                 ‘显示毫米单位数值,2位小数

         Label1

(1)=Format(WW/25.4,“0.000")

       ‘显示英寸单位数值,3位小数

         IfWW>MaxWAndWW<51Then

----‘判断最大值,仪表在刚开始工作时有干扰,会传导一些乱码,位移传感器有参数偏差,最大值一般都略大于50毫米,所以取51为极限最大值,取-51为极限最小值。

    MaxW=WW

    Label1

(2)=Format(MaxW,“0.00")          

    ‘显示毫米单位最大值,2位小数

    Label1(3)=Format(MaxW/25.4,“0.000")

    ‘显示英寸单位最大值,3位小数

    EndIf

    IfWW-51Then

    ‘判断最小值

    MinW=WW

    Label1(4)=Format(MinW,“0.00")          

    ‘显示毫米单位最小值,2位小数

    Label1(5)=Format(MinW/25.4,“0.000")

      ‘显示英寸单位最小值,3位小数

          EndIf

          .RThreshold=1    

         ‘打开MSComm1事件接收

    EndIf

  CaseElse

 EndSelect

 EndWith

EndSub

基于VB的串口数据采集

[来源:

机电论文|类别:

技术|时间:

2008-6-2114:

44:

00]

[字体:

大中小]

 

要求:

用VB编写一个小软件,采集电子数显千分表的数据

数显表接口参数:

数显表的专用接口可与PC机的RS232(9针)相接,其波特率4800,无奇偶校检,8位数据位,1位停止位,以AcsII码发送数据

窗体设计:

1个listbox,1个textbox,1个MSComm控件,2个CommandButton

程序设计:

DimindataAsVariant

Dimdata(100)AsSingle

 

PrivateSubCommand1_Click()

Statici

i=i+1

data(i)=Text1.Text

List1.AddItemdata(i)

EndSub ‘...按键一次,采集一个数据,并存入List1中

 

PrivateSubCommand2_Click()

MSComm1.PortOpen=False  '….关端口

UnloadMe

EndSub '...退出

 

PrivateSubForm_Load()

MSComm1.CommPort=1'...使用Com1口

MSComm1.Settings="4800,n,8,1" '...设置通讯参数

MSComm1.RThreshold=10

MSComm1.streshold=10

MSComm1.PortOpen=True'...打开串口

Text1.Text=""

EndSub

 

PrivateSubMSComm1_OnComm()

SelectCaseMSComm1.CommEvent

CasecomEvReceive'...有接收事件发生

indata=MSComm1.Input

Text2.Text=(indata/10)‘…text1实时显示数显表的数据

MSComm1.InBufferCount=0'...清空输入寄存器

EndSelect

EndSub

我这有一段VB程序是为了画实时采集曲线的。

软件编程我不行,如果大家有看得懂得,请帮我看看。

程序不多

Private Sub MSComm1_OnComm()

  Dim Inbyte() As Byte

  Dim buffer As String

  Dim datatemp(1000) As Single 

  If num > 199 Then Call renew    '刷新绘图区

  '读取仪表返回数据串

  Select Case MSComm1.CommEvent

    Case comEvReceive

      Inbyte = MSComm1.Input'这地方看不懂,数组可以这样赋值吗?

      

      For i = LBound(Inbyte) To UBound(Inbyte)

        buffer = buffer + Hex(Inbyte(i)) + Chr(32) 'for语句也没看懂,尤其是buffer这赋的是什么值?

      Next i

    Case comEvSend

  End Select

  '获取十进制测量数据

  ’这下面的又是没看懂,应该是将十六进制转换为十进制,怎么转换的呢?

  If Len(Trim(Mid(buffer, 1, 2))) = 1 Then

    datatemp(num) = Val("&H" & Mid(buffer, 3, 2) & Str("0") & Mid(buffer, 1, 2)) * 0.01

  Else

    datatemp(num) = Val("&H" & Mid(buffer, 3, 2) & Mid(buffer, 1, 2)) * 0.01

  End If

 

‘绘制曲线

Private Sub draw()

  Picture1.Cls

  Picture1.DrawWidth = 2

  Picture1.BackColor = QBColor(7)

’下面的程序我看不懂,用的是什么原理画的曲线呢?

  Picture1.Scale (0, 50)-(200, 0)

  For i = 1 To num - 1

    X1 = (i - 1):

 Y1 = datatemp(i - 1)

    X2 = i:

 Y2 = datatemp(i)

    Picture1.Line (X1, Y1)-(X2, Y2), QBColor

(1)

  Next i

End Sub

问题点数:

100 回复次数:

10

修改删除举报引用回复

加为好友

发送私信

在线聊天

CathySun118

∙等级:

∙可用分等级:

富农

∙总技术分:

88266

∙总技术分排名:

66

∙2

发表于:

2007-06-2514:

44:

411楼 得分:

0

连点法阿

修改删除举报引用回复

加为好友

发送私信

在线聊天

Winters_lee

∙等级:

∙可用分等级:

中农

∙总技术分:

1658

∙总技术分排名:

12870

发表于:

2007-06-2609:

41:

372楼 得分:

0

画曲线啊,用这个吧:

'实时曲线左移函数,定义在模块中

Public Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long

'建立一个类,作为画实时曲线

Option Explicit

Public pCurveNUM                        As Integer

Public pCurveName                       As String

Public pCurveMax                        As Double

Public pCurvemin                        As Double

Private pricCurve                       As PictureBox

Private priCurvePoint(6)                As Integer

Private priCurveData(6)                 As Double

Private priDrawY0(6)                    As Double

Private priDrawY1(6)                    As Double

Private priDrawNMinute                  As Integer

Private priDrawTMinute                  As Integer

Private WithEvents priTimerDraw         As Timer

Public Property Let ltDrawTimer(ByRef lTimer As Timer)

    

    Set priTimerDraw = lTimer

    

End Property

Public Property Let ltGiveCurveData(ByVal lDataPoint As Variant)

    Dim i%

    For i = 1 To pCurveNUM

        priCurvePoint(i) = CInt(lDataPoint(i))

    Next

End Property

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 考试认证 > 交规考试

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1