logo资料库

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

第1页 / 共24页
第2页 / 共24页
第3页 / 共24页
第4页 / 共24页
第5页 / 共24页
第6页 / 共24页
第7页 / 共24页
第8页 / 共24页
资料共24页,剩余部分请下载后查看
用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,即: 1 x x x x x x x 则为负数;第八位为 0,即: 0 x x x x x x x 则为正数。 ----例如: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=comInputModeBina ry,但用 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 的 MSCo mm 控件。 ---- [开始]按钮的 Click 事件处理程序主要是对 MSComm1 控制的参数初始化设 置,程序中大部分参数在设计时可在 MSComm1 控制的属性窗口中设置: Private Sub Command1_Click() ‘开始按钮 ‘使用 COM2 ‘设置通信口参数 With MSComm1 .CommPort=2 .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 接收事件,然后接收数据字节,将压缩 BC D 进行还原转换,再接收符号字节,判断数据符号,判断数据最大最小值,最后打开 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
基于 VB 的串口数据采集 [ 来源:机电论文 | 类别:技术 | 时间:2008-6-21 14:44:00 ] [字体:大 中 小] 要求:用 VB 编写一个小软件,采集电子数显千分表的数据 数显表接口参数:数显表的专用接口可与 PC 机的 RS232(9 针)相接,其波特率 4800, 无奇偶校检,8 位数据位,1 位停止位,以 AcsII 码发送数据 窗体设计:1 个 listbox,1 个 textbox,1 个 MSComm 控件,2 个 CommandButton 程序设计: Dim indata As Variant Dim data(100) As Single Private Sub Command1_Click() Static i i = i + 1 data(i) = Text1.Text List1.AddItem data(i) End Sub ‘...按键一次,采集一个数据,并存入 List1 中 Private Sub Command2_Click() MSComm1.PortOpen = False '….关端口 Unload Me End Sub '...退出
Private Sub Form_Load() MSComm1.CommPort = 1 '...使用 Com1 口 MSComm1.Settings = "4800,n,8,1" '...设置通讯参数 MSComm1.RThreshold = 10 MSComm1.streshold = 10 MSComm1.PortOpen = True '...打开串口 Text1.Text = "" End Sub Private Sub MSComm1_OnComm() Select Case MSComm1.CommEvent Case comEvReceive '...有接收事件发生 indata = MSComm1.Input Text2.Text = (indata / 10) ‘…text1 实时显示数显表的数据 MSComm1.InBufferCount = 0 '...清空输入寄存器 End Select End Sub
我这有一段 VB 程序是为了画实时采集曲线的。 软件编程我不行,如果大家有看得懂得,请帮我看看。 程序不多 Private Sub MSComm1_OnComm() Dim Inbyte() As Byte Dim buffer As String Dim datatemp(1000) As Single If num > 199 Then Call '读取仪表返回数据串 Select Case MSComm1.CommEvent renew 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, ") & Mid(buffer, 1, 2)) * 0.01 Else 3, 2) & Str( "0 " & Mid(buffer, 3, 2) & Mid(buffer, 1, 2)) * 0.01 datatemp(num) = Val( "&H End If ‘绘制曲线 Private Sub draw() Picture1.Cls Picture1.DrawWidth = 2 Picture1.BackColor = QBColor(7) ’下面的程序我看不懂,用的是什么原理画的曲线呢? Picture1.Scale For i = 1 To num - 1 (0, 50)-(200, 0) - 1): Y1 = datatemp(i X1 = (i X2 = i: Y2 = datatemp(i) Picture1.Line (X1, Y1)-(X2, Y2), QBColor(1) - 1)
Next i End Sub 问题点数:100 回复次数:10 显示所有回复 修改 删除 举报 引用 回复 加为好友 发送私信 在线聊天 CathySun118 失.悟 等级: 可用分等级:富农 总技术分:88266 总技术分排名:66 发表于:2007-06-25 14:44:411 楼 得分:0 连点法阿 修改 删除 举报 引用 回复        发表于:2007-06-26 09:41:372 楼 得分:0 画曲线啊,用这个吧: '实时曲线左移函数,定义在模块中 Public " (ByVal hDestDC As Declare As Long, ByVal nWidth As Function Long, ByVal BitBlt Lib Long, ByVal Long, ByVal nHeight As "gdi32 y Lo x As ng, ByVal hSrcDC As ySrc As Long, ByVal dwRop As Long, ByVal '建立一个类,作为画实时曲线 Option Explicit Public pCurveNUM Public pCurveName Public pCurveMax Public pCurvemin xSrc As Long) As Long, ByVal Long Integer As As String As Double As Double 2 加 为 好 友 发 送 私 信 在 线 聊 天  Winte
分享到:
收藏