多媒体定时器_第1页
多媒体定时器_第2页
多媒体定时器_第3页
多媒体定时器_第4页
多媒体定时器_第5页
免费预览已结束,剩余10页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、速度参数实时数据采集的软件实现1实时数据采集的要求及软件平台-数据采集一般是通过软件或硬件的定时中断通过A/D来读取外界传感器的数据。因此实时数据采集的首要的基本要求是定时准确,即采样间隔具有较好的一致性。-实时数据采集系统过去一般是在DOS操作系统下应用汇编语言开发的。Windows操作系统的普及应用,尤其是可视化开发软件VisualC+的出现,为软件开发提供了强大的图形界面功能,使得开发出来的应用程序具有良好的人机交互功能。汇编语言的特点是难调试,而高级语言具有良好的可读性及方便的调试手段。-本文采用美国微软公司推出的VisualC+为软件开发工具,采样间隔采用多媒体定时器进行精确定时,并

2、采用VisualC+提供的端口操作的操作台函数进行硬件I/O编程。2多媒体定时器和硬件接口函数-VisualC+提供了两种定时器。一般常用的是系统计时器,它使用函数SetTimer进行初始化,应用程序响应SetTimer函数发送来的消息WM_TIMER。这个定时器是IBMPC硬件和ROMBIOS构造的定时器逻辑的一个相当简单的扩展。PC的ROM初始化Intel8259定时器芯片来产生硬件中断08H。这个中断有时称为"定时器滴答"中断。中断08H每隔54.925毫秒产生一次,或大约每秒18.2次。BIOS使用中断08H更新存于BIOS数据区的"时间"值。因

3、此,这个定时器在Windows中的最大缺点是计时器的最大分辨率是55毫秒,也就是说应用程序每秒只能接收到18个消息。止匕外,这个计时器消息的优先权太低,只有在所有的消息(除了消息WM_PAINT)被处理后才能被处理。因此函数SetTimer只能用于一般的定时,如扉屏显示时间定时等,它远远不能满足实时数据采集的要求。本文重点介绍的是多媒体定时器(MultimediaTimer)。它使用自己单独的线程(Thread),来调用一个自己的回调函数(CallbackFunction)。它的优先级很高,它每隔一定时间就发送一个消息而不管其它消息是否执行完。止匕外,对于现在的IntelCPU来说,它的最小定

4、时精度通常都可以达到1毫秒,足够满足实时数据采集的定时精度。第4节将详细阐明VisualC+5.0中多媒体定时器使用的详细过程。VisualC+5.0作为C+的可视化编程工具,具有C语言对硬件操作的能力。它提供了大量的操作台函数(可参阅VisualC+提供的帮助)。例如:从端口地址读取数据的函数_inp(读字节),_inpw(读字),_inpd(读双字)和向端口写操作字和赋初值的函数_outp(写字节),_outpw(写字),_outpd(写双字)。_inp,_inpw,_inpd三个函数的参数均为地址变量,返回的是该地址口读取的数据。_outp,_outpw,_outpd三个函数的第一个参数

5、是地址,第二个参数是须写入地址的数据。-读端口地址的三个函数原型分别是:int_inp(unsignedshortport);unsignedshort_inpw(unsignedshortport);unsignedlong_inpd(unsignedshortport);向端口地址写数据或命令字的三个函数原型分别如下:int_outp(unsignedshortport,intdatabyte);unsignedshort_outpw(unsignedshortport,unsignedshortdataword);unsignedlong_outpd(unsignedshortport,

6、unsignedlongdataword);-举例来说,对端口地址0xAddress写入字节数据0xData是_outp(0xAddress,0xData),而若从该地址读取字节数据,则用_inp(0xAddress)。第5节将以一实例介绍硬件操作的全过程。3VisualC+多媒体定时器的编程实现# -3.1设定Windows95多媒体定时器12-多媒体定时器可直接用ComponentGallery在项目中插入WindowsMultimedia组件,此时多媒体定时器所需的头文件和库将自动插入工程的Stdafx.h中,或用手直接将以下语句添入Stdafx.h,即:#include/CG:Thef

7、ollowinglinewasaddedbytheWindowsMultimediacomponent.#pragmacomment(lib,"winmm.lib")# -3.2多媒体定时器的应用1)定义定时器参数# defineTEN_MILLI_SECOND200定时器间隔# defineTIMER_ACCURACY1定时器精度UINTTimer_ID;定时器句柄UINTwAccuracy;定时器精度参数2)通过多媒体定时器设备函数timeGetDeviceCaps获得本微机的最大分辨率。TIMECAPStc;定时器分辨率的结构If(timeGetDeviceCaps(

8、&tc,sizeof(TIMECAPS)=TIMERR_NOERROR)获得本系统的最小定时器分辨率,所有应用必须大于等于该分辨率wAccuracy=min(max(tc.wPeriodMin,TIMER_ACCURACY),tc.wPeriodMax);设定本应用的所需的定时器分辨率,本例为微机的所允许的最大分辨率timeBeginPeriod(wAccuracy);3)应用多媒体定时器的timeSetEvent函数设定事件的触发方式,它的函数原形是:MMRESULTtimeSetEvent(UINTuDelay,UINTuResolution,LPTIMECALLBACKlpTim

9、eProc,DWORDdwUser,UINTfuEvent);uDelay用于设定事件触发间隔;uResolution用于设定程序所需的最小分辨率;lpTimeProc调用回调函数;dwUser用户提供的回调数据;fuEvent事件触发方式,在VisualC+中有两种方式:TIME_ONESHOT:事件仅触发一次TIME_PERIODIC:每隔一定时间触发一次TimeSetEvent函数返回定时器句柄,具体应用是:Timer_ID=timeSetEvent(TEN_MILLI_SECOND,wAccuracy,(LPTIMECALLBACK)CatchMMTimer,(DWORD)hWnd,T

10、IME_PERIODIC);4)声明一个全局的回调(Callback)函数voidCALLBACKTwoHundredMilliSecondProc(UINTwTimerID,UINTnMsg,DWORDdwUser,DWORDdw1,DWORDdw2),-在回调函数中调用事件触发消息且在回调函数中语句尽量简单,不要在回调函数内做一些耗时的操作;-5)添加用户消息CatchMMTimer函数,用来接收多媒体定时器的事件通知。其过程是首先在类的头文件定义:#defineMYMSG_TIMERWM_USER+101,然后在类头文件的AFX_MSG块中说明消息处理函数:afx_msgLRESULTO

11、nMymsgTimer(WPARAMwParam,LPARAMlParam);在类实现的消息映射块中,使用ON_MESSAGE宏指令将消息映射到消息处理函数中:ON_MESSAGE(MYMSG_TIMER,OnMymsgTimer)。最后在相应类中实现消息处理函数。关于用户自定义消息具体可参考VisualC+s书籍。如:PostMessage(HWND)dwUser,MYMSG_TIMER,0,0);/PostMessage发送消息-6)定时器的任务完成后,要及时删除,否则占用太多内存,系统会越来越慢。删除定时器分两步,首先调用timeKillEvent函数删除定时器句柄,然后用timeEnd

12、Period函数删除定时器的分辨率。具体应用如下:-timeKillEvent(Timer_ID);timeEndPeriod(wAccuracy);-本节所用所有函数的使用可参阅VisualC+提供的在线帮助。4VisualC+硬件I/O操作的编程实现-在对硬件的操作中,除了应用本文2节中的函数外还必须在相关类的实现文件中添加操作台的头文件#include"conio.h"。本文以康拓研制的IPC5387计数板中的82C54计数器芯片u24的第一个计数器通道为例进行较为系统的说明。该板有4片82C54芯片,具有12路16位计数。它直接插在PC总线插梢中。下面例中命令字的含

13、义及读写操作顺序可参考82C54的有关资料,其中所用的地址值可参考IPC5387计数板的说明书。-1)定义控制口地址变量和计数器0高低字节变量unsignedshortU24CtrlPort;unsignedinti1L,i1H;计数器0高低字节变量并在类的构造函数中赋命令口地址值及初值usCtrlPort=0x163;i1L=0;i1H=0;-2)初始化82C54时,给本芯片的控制口地址赋操作命令字并赋初值Initialize82C54()在本文中芯片的读写操作均为先读低字节,再读高字节_outp(usCtrlPort,0x30);/写命令字_outp(0x160,0x00);计数器0赋初值

14、_outp(0x160,0x00);-3)用_inp函数读出各地址的值,读数之前先锁存计数值再读数voidRead82C54Data()锁存82C54计数器的通道_outp(CtrlPort1,0x00);锁存82C54计数器0读出计数值,先读取低字节,再读取高字节读取82C54计数器0i1L=_inp(0x160);i1H=_inp(0x160);_outp(0x160,0x00);计数器0重赋初值_outp(0x160,0x00);)5防滑器速度参数实时数据采集的编程实现-防滑器速度参数数据的采集过程如图1所示。计数板(本文采用康拓公司的IPC5387,计数芯片是82C54)插在PC机主板

15、的ISA插梢,车辆四轴的脉冲速度传感器安装在轴头。并采用"飞读”方式,计算机按一定的时间间隔读取计数板内的脉冲数,将脉冲数按公式(1)转换为速度值。图1防滑器速度参数采集过程-式中:轴切线速度,:脉冲数,:采集周期。-根据4、5两节所阐述的内容,我们在VisualC+的工作台上用New建立一个新的MFCAppWizard(exe)项目Project,确保建立一个单文档程序并选择中文字库。在ResourceView资源Menu的IDR_MAINFRAME中添加一个弹出式菜单,在Caption中填入"数据采集",然后在两个菜单项的Caption中填入"开始&

16、quot;、"结束"并分别定义ID为ID_DATA_START和ID_DATA_STOP。用鼠标右击菜单,并在弹出的浮动菜单上选择ClassWizard进入MFCClassWizard中的MessageMaps中定义消息处理函数,在ClassName中选择文档类,在ObjectIds中分另U选择ID_DATA_START和ID_DATA_STOP,在Messages中双击Command并接受缺省的函数名OnDataStart和OnDataStop。点击EditCode按钮,VC将光标自动定位到所定义的函数。-在文档类的头文件中定义一个全局回调函数和一些地址和数据变量,并按第

17、4节的过程设置定时器参数,在OnDataStart()函数中启动多媒体定时器,完成对硬件的初始化。多媒体定时器每隔一定的时间间隔在回调函数中调用自定义的Read82C54Data函数,实现计数值的连续实时采集。OnDataStop()函数完成定时器的删除工作。具体的实现按4、5节的编程过程操作。-所有操作完成后,通过编译连接并生成执行文件后,该程序将按用户设定的时间间隔从计数器I/O端口读取传感器所采集的脉冲数数据。6结论-VisualC+实现实时数据采集系统的主要关键是保证定时器的定时精度和对数据采集卡等硬件I/O接口地址数据的读写操作。本文利用了VisualC+5.0的多媒体定时器和硬件操

18、作函数大大提高了实时数据的采集精度。本文的多媒体定时器的定时精度可达到1毫秒,可以满足绝大部分实时数据采集系统的定时要求。ThisarticlewascontributedbySimonWood.Thissimpleclassencapsulatesthemultimediatimers.TousetheclassincludemmTimers.cppandmmTimers.hinyourproject.Linkwithwinmm.lib.TouseatimerderiveaclassfromCMMTimersandoverridemembertimerProc.timerProcwillbe

19、calledwhenthetimergoesoff.Instantiateavariableofthenewclass.Theparametertotheconstructoristhetimerresolutioninms.TostartatimercallstartTimer.Thefirstparameterspecifiestheperiodofthetimerinms.Thesecondparameterspecifieswhetherthetimerisaoneshotorperiodictimer.TostopaperiodictimercallstopTimer.Thiscod

20、ewasdevelopedwithVisualC+5.0andhasbeentestedonNT4.0.Thesourcefollows:Theheaderfile,mmTimers.h#ifndefmultimedia_timers#definemultimedia_timers#includeclassCMMTimerspublic:CMMTimers(UINTresolution);virtualCMMTimers();UINTgetTimerRes()returntimerRes;boolstartTimer(UINTperiod,booloneShot);boolstopTimer();virtualvoidtimerProc();protected:UINTtimerRes;UINTtimerId;#endifThesourcefile,mmTimers.cpp#include"StdAfx.h"#include"mmTimers.h"CMMTimers:CMMTimers(UINTresolution):timerRes(0),timerId(0)TIMECAPStc;if(TIMERR_NOERROR=timeGetDevCap

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论