多线程实时数据采集MFC VISUAL C++ /C++
美国国家仪器公司为用户提供了许多高性能、高速度、高分辨率的数据采集卡,而与之接口的软件大多采用 Labview,Labview是一种图形化编程软件,你只需拖动控件到容器,使用起来确实比较方便。但用户无法知 道底层的东西,这样针对具体的应用,还要自己去理解封装得很深的函数或程序,费时、费力。因此,c++/MFC还是一种 比较好的选择。如何在MFC中实现实时数据采集呢? 首...
美国国家仪器公司为用户提供了许多高性能、高速度、高分辨率的数据采集卡,而与之接口的软件大多采用
Labview,Labview是一种图形化编程软件,你只需拖动控件到容器,使用起来确实比较方便。但用户无法知
道底层的东西,这样针对具体的应用,还要自己去理解封装得很深的函数或程序,费时、费力。因此,
c++/MFC还是一种
比较好的选择。如何在MFC中实现实时数据采集呢? 首先,得有定时器,定时器在指定的时间内向窗口发送
WM_TIMER消息,用户在消息处理函数里面完成数据采集和直观的图形或数值实现。设置定时器很简单,只需
简单的调用Settimer(1,100,NULL),消息映射为OnTimer()函数。但实际上,大型的程序设计一般不会采用
这样的方法,而是把数据采集和图形显示放到一个DLL里面,
,但如何在采集完数据后,发消息给视图类,以便视图类把数据以需要的格式显示出来,
曾经尝试发送用户自定义消息,但发现在视图类接收不到该用户自定义消息。因此,眼前要解决的问题关键
在于文档对象需要定时连续地采集数据,然后通知多个视图类以不的格式处理和显示这些数据。在文档要实
现有规律连续数据采集,需要有个定时器事件。
定时器事件通常通过调用UINT SetTimer(
HWND hWnd, // handle of window for timer messages
UINT nIDEvent, // timer identifier
UINT uElapse, // time-out value
TIMERPROC lpTimerFunc // address of timer procedure
);函数来实现,
其中, hWnd是与定时器相关联的窗口句柄,此窗口为调用线程所拥有。nIDEvent是定时器标志符,也就是
标识定时器的唯一性,如果要定义多个定时器,就需要用这个参数来区别该定时器。 uElapse是指隔多长时
间来执行后面的第四个参数所指向的函数,lpTimerFunc 是uElapse流逝后系统再次调用的函数的指针。现
在我们对这个API函数有些认识,如要设计一个时间间隔为100毫秒的定时器事件,如SetTimer
(NULL,1,100,lpTimerFunc); 第一个参数为NULL是指没有与定时器相关联的窗口,因而第二个参数也被忽略
了,也意味着在没有窗口的文档类中,不可以实现多个定时器.
回调函数说明如下,VOID CALLBACK TimerProc(
HWND hwnd, // handle of window for timer messages
UINT uMsg, // WM_TIMER message
UINT idEvent, // timer identifier
DWORD dwTime // current system time
);
该Windows 定时器是IBM PC硬件和ROM BIOS构造的定时器的简单扩充。计算机的ROM初始化8523定时器使
其产生硬件中断08H,而该中断的频率为18.2Hz,即每隔54.9ms产生一次中断。也就是说该Windows定时器的
时间精度是54.9ms,基本上能满足数据采集的要求,因为计算机显示屏的刷新频率最快为50Hz-60Hz。
该定时器的优点是初始化简单,容易实现,然而缺点也显而易见,因为WM_TIMER消息的优先级比较低,只有
应用程序队列中的所有其他消息被处理完后,才能处理该WM_TIMER消息,不能保证数据采集的一致性。而且
定时器的分辨率不高,不能满足工业上日益增长德高精度的实时采集的需要。因此,这里提出了一种新的
多媒体定时器,该定时器的相关说明如下:
MMRESULT timeSetEvent( UINT uDelay,
UINT uResolution,
LPTIMECALLBACK lpTimeProc,
WORD dwUser,
UINT fuEvent )
该函数设置一个定时回调事件,此事件可以是一个一次性事件或周期性事件。事件一旦被激活,便调用指定的回调函数, 成功后返回事件的标识符代码,否则返回NULL。函数的参数说明如下:
uDelay:以毫秒指定事件的周期。 Uresolution:以毫秒指定延时的精度,数值越小定时器事件分辨率越高。缺省值为1ms。 LpTimeProc:指向一个回调函数。 DwUser:存放用户提供的回调数据。 FuEvent:指定定时器事件类型: TIME_ONESHOT:uDelay毫秒后只产生一次事件 TIME_PERIODIC :每隔uDelay毫秒周期性地产生事件
具体应用时,可以通过调用timeSetEvent()函数,将需要周期性执行的任务定义在LpTimeProc回调函数 中(如:定时采样、控制等),
从而完成所需处理的事件。需要注意的是,任务处理的时间不能大于周期间隔时间。另外,在定时器使用完毕后, 应及时调用
timeKillEvent()将之释放。
更多推荐
所有评论(0)