陶 峰,史学涛,付 峰,刘锐岗,尤富生,董秀珍
多媒体定时器在EIT数据采集精度评价中的应用
陶 峰,史学涛,付 峰,刘锐岗,尤富生,董秀珍
目的:实现电阻抗断层成像(EIT)高精度数据采集系统性能评价软件中的数据快速采集和存储功能。方法:分析比较了Timer和多媒体2种Windows定时器,基于Visual C++分别编程实现了EIT数据采集系统性能评价软件并比较了结果。结果:2种定时器均可以完成对EIT数据的采集、显示、存放和简单处理功能,但是多媒体定时器的定时精度更高,能够更准确而有效地完成上述任务。结论:多媒体定时器稳定可靠,可以满足一般情况下的高精度定时要求。
Windows定时器;数据采集;Visual C++
AbstractObjectiveTo realize fast data acquisition and storage in the performance evaluation software of high-precision data acquisition system of electrical impedance tomography(EIT).MethodsTwo kinds of Windows timer were compared and the performance evaluation software of EIT data acquisition system was realized respectively based on Visual C++.Results Both two timers were able to complete the tasks about EIT data,such as acquisition,display,storage and simple processing.However,multimedia timer,whose timing accuracy was higher,was able to complete all the above tasks precisely and effectively.ConclusionMultimedia timer is reliable and can meet the general requirements of high precision timing.[Chinese Medical Equipment Journal,2011,32(2):1-3]
Key wordsWindows timer;data acquisition;Visual C++
电阻抗断层成像 (electrical impedance tomography,EIT)是新一代无创医学成像技术,其基本原理是根据人体内不同组织在不同的生理、病理状态下具有不同的电阻(导)率,通过各种方法给人体施加小的安全驱动电流(电压),在体外测量相应电压(电流)信号以重建人体内部的电阻率分布或其变化的图像[1]。与传统成像手段(CT、MRI等)相比,EIT 具有自身优势[2]:一方面,现有成像设备如CT等体积大、成本高、操作复杂甚至对人体有创,而EIT恰恰具有无创、低成本以及功能成像的特点;另一方面,现有成像设备无法对患者进行长时间连续性成像检查,从而不能对持续性或迟发性出血这一类疾病做出及时诊断,而EIT则可以进行连续的床旁监护,进而达到对具有这种倾向的患者进行早期检测的目的。因此,作为一种辅助成像手段,EIT展现出良好的临床应用前景。
第四军医大学的EIT课题组已成功研制了能够初步应用于临床的EIT图像监护系统。从EIT的原理可以知道,连续稳定高速采集电压(电流)信号是准确重建图像的前提。在改进和完善现有EIT系统的过程中,需要对其性能——如数据采集的精度和稳定性等做出评估,因此需要编写相对独立的测试软件完成对相关指标的测试工作,包括对EIT数据的采集、显示、存放和简单处理。在这一过程中,为了保证采样信号的准确性,采样时间的精确度十分关键。
目前的信号处理软件大多基于Windows平台编写。Windows操作系统的普及应用,尤其是可视化开发软件Visual C++的出现,为软件开发提供了强大的图形界面功能,使得对数据采集进行图形化处理更为方便,开发出来的应用程序具有良好的人机交互功能[3]。Windows环境下有不同类型的定时器,本研究拟通过对比选择最佳的采样控制定时器,以达到最佳的采样速度。
Timer是Visual C++提供的一个普通的定时器,属于秒级精度的定时器。使用函数SetTimer()设定一个时间间隔之后,Windows系统将每隔该时间间隔发送一条WM_TIMER消息,从而实现应用程序的定时处理。Timer实现定时操作非常方便,但它有2大缺陷:定时精度差和消息优先权低[4]。首先,由函数SetTimer()设定的时间间隔被转换为IRQ 0请求中断的次数,CPU以18.2 Hz的频率响应中断,周期为54.945 ms[5],也就是说应用程序每秒最多接收18个消息。其次,Windows系统是基于消息机制的系统,任何事件的执行都是通过发送和接收消息来完成的[6]。WM_TIMER消息的优先权太低,只有在除WM_PAINT消息之外的所有消息被处理完之后,它才能得到处理。因此,Timer控件可以用于一般的定时,但不能实现高精度的定时任务。
多媒体定时器属于毫秒级精度的定时器。它不依赖于消息机制,而是用函数TimeSetEvent()产生一个独立的线程,在一定的中断次数达到后,直接调用预先设置好的回调函数进行处理,不必等到应用程序的消息队列为空,从而切实保障了定时中断得到实时响应,使其定时精度可达1 ms[7]。利用多媒体计时器可以很精确地读出系统的当前时间,并且能够在非常精确的时间间隔内完成既定的功能。因此,多媒体定时器完全可以满足本软件的要求。
本软件的编写是在Microsoft Visual Studio 2008环境下基于对话框类(CDialog)完成的。整个软件(工程名为SYMS)的主要功能包括电阻抗的数据采集、保存,一维曲线的实时显示以及停止采集后获取特定范围内数据的简单统计信息。为了比较结果,分别采用Timer控件和多媒体定时器实现了软件的数据采集和读写功能。
作者单位:710032 西安 第四军医大学生物医学工程学院(陶 峰、史学涛、付 峰、刘锐岗、尤富生、董秀珍)
首先,在头文件里添加afx_msg void OnTimer(UNIT_PTR nIDEvent);然后,在.cpp文件中的消息映射部分添加ON_WM_TIMER();最后,由3个函数来完整的实现既定功能。
在MFC中SetTimer被封装在CWnd类中,函数原形如下:UNIT_PTR SetTimer (UINT_PTR nIDEvent,UINT uElapse,void(CALLBACK*(lpfnTimer)(HWND,UINT,UINT_PTR,DWORD))其中,nIDEvent为定时器ID,多个定时器时,可以通过该ID判断是哪个定时器;uElapse为时间间隔,单位为ms;lpfnTimer为应用程序所提供的处理WM_TIMER消息的回调函数的地址,若该参数为NULL,则使用系统默认的回调函数即OnTimer函数。
本软件中,在 “开始”按钮的响应函数void CSYMSDlg::OnBnClickedButtonStart()中添加如下语句:
SetTimer(1,1000/m_uSampleFreq,NULL),其中 m_uSampleFreq为采样频率。这样即完成了定时器的设置。
此函数为系统默认的回调函数,在该函数中添加代码,完成数据的采集、读写和保存。函数形式如下:
SetTimer定时器是系统资源,使用完毕应及时用KillTimer销毁。Cwnd类中的函数原型如下:
BOOL KillTimer(UINT_PTR nIDEvent)
其中nIDEvent为SetTimer函数中的定时器ID。
本软件中,在 “停止”按钮的响应函数void CSYMSDlg::OnBnClickedButtonStop()中添加如下语句:
KillTimer(1);
这样就完成了定时器的销毁。
多媒体定时器的使用比Timer控件复杂一些,流程图如图1所示。
图1 使用多媒体定时器的程序流程图
首先,应该在.cpp文件的开头添加如下语句:
#include “mmsystem.h”
#pragma comment(lib,“winmm”)
然后,通过以下一系列函数实现所要求的功能。
通过该函数得到系统的最大和最小分辨率,单位为ms,多媒体定时器设置的分辨率应该在此范围内。函数原型如下:
MMRESULT timeGetDevCaps(LPTIMECAPS ptc,UINT cbtc)
其中,ptc为指向TIMECAPS结构体的指针,其成员变量wPeriodMin和wPeriodMax给出了系统的最小和最大分辨率,单位为ms;cbtc为TIMECAPS结构的字节数。
本软件中该函数位于自定义的定时器创建函数Create-Timer中,与函数timeBeginPeriod配合使用(该函数用于设定程序的最小分辨率),具体语句如下:
通过该函数启动定时器事件,函数原型如下:
MMRESULT timeSetEvent(UINT uDelay,UINT uResolution,LPTIMECALLBACK lpTimeProc,DWORD_PTR dwUser,UINT fuEvent)
其中,uDelay为事件触发间隔,单位为ms;uResolution为程序所需的最小分辨率;lpTimeProc为指向回调函数的指针,定时调用;dwUser为用户提供的回调数据,传递给lpTimeProc;fuEvent为事件触发方式,可以设定为TIME_ONESHOT(仅触发一次)或者TIME_PERIODIC(每隔一段时间触发一次)。
本软件中,该函数位于自定义的定时器创建函数Create-Timer中,具体语句如下:
timerID=timeSetEvent(timePeriod,wTimeRes,(LPTIMECALLBACK)TimerHandler,(DWORD)this,TIME_PERIODIC)
return timerID;
其中,timePeriod为自定义的时间间隔,也就是采样频率的倒数;TimerHandler为回调函数名称。
回调函数是一个中断服务程序,由开发者自己编写,当到达事件触发间隔时被调用。该函数为Windows API类型的函数,不能将其定义为某个具体类的成员。当需要调用MFC类中某个具体的成员函数时,需要先获取这个类的指针。回调函数的原型如下:
void CALLBACK TimeProc(UINT uID,UINT uMsg,DWORD dwUser,DWORD dw1,DWORD dw2)
其中,dwUser为开发者自定义参数,其余参数均未使用。在回 调 函 数 中 ,除 PostMessage、timeGettime、timeSetEvent、time KillEvent等少数几个函数外,不能调用其他系统定义的函数。在回调函数内的语句应当尽量简单,不要在回调函数内做一些耗时的操作[8]。可通过用户自定义消息的方法处理定时器事件(在本软件中就是数据的采集和读写),而在回调函数中使用函数PostMessage发送用户自定义消息。
首先,在类(本软件中为CSYMSDlg)的头文件中定义用户消息,如下:
#Define MY_TIMER WM_USER+101
然后,在头文件的AFX_MSG模块中说明消息处理函数,如下:
afx_msg LRESULT OnMyTimer(WPARAM wParam,LPARAM lParam);
最后,在.cpp文件中的消息映射部分使用ON_MESSAGE宏进行消息映射,如下:
ON_MESSAGE(MY_TIMER,OnMyTimer)本软件中回调函数的具体语句如下:
关于自定义消息处理函数的编写需要注意的是:函数定义中均要求返回LRESULT,如果返回值不需要处理,可直接返回0;如果该消息需要返回特殊值,就根据程序的需要返回相应的值。在本软件的自定义消息处理函数中,完成的工作是数据的采集和读写,不需要处理返回值,故具体语句如下:
定时器的任务完成后应及时删除,否则占用太多的内存会导致系统越来越慢。这2个函数分别删除定时器的句柄和分辨率。函数原型分别如下:
MMRESULT timeKillEvent(UINT uTimerID);
MMRESULT timeEndPeriod(UINT uPeriod);
其中,uTimerID为timeSetEvent函数返回的定时器句柄,u-Period为timeBeginPeriod函数设定的定时器分辨率。本软件中在自定义的DestroyTimer函数中实现对多媒体定时器的删除,具体语句如下:
被测试EIT系统采用16电极,对向驱动模式,激励电流为354 μA或884 μA(有效值)。软件提供了可供用户选择的激励及测量方式,并对电极工作情况和所采得的数据进行了实时显示。为使用户对数据的细节及整体趋势有所了解,软件还提供了实时曲线的移动和缩放功能。此外,软件还为用户提供了停止采集后由用户所选择的范围内数据的简单统计功能。软件界面如图2所示。
图2 软件界面一览
利用2种Windows定时器均成功实现了对数据的采集与实时显示及存储功能。但是经测试发现,利用Timer控件实现的软件每秒最多采集130个数据。即使利用SetTimer函数将采样频率设定为更高,采样的实际频率均为130Hz;还可以观察到,当频率设定为高于130Hz时,在采样过程中帧数的显示不稳定,这意味着每次Timer函数的触发时间不完全一致。而利用多媒体定时器所实现软件的实际采样频率最高为250Hz,若设定更高的采样频率会造成死机。
使用多媒体定时器的注意事项之一是任务处理的时间不能大于周期间隔的时间。本软件中,多媒体定时器完成的任务包括数据的采集和读写,因此,如果设定过高的频率就造成触发间隔小于一次数据的采集读写周期,从而导致死机。可以从以下2方面来进一步提高本测试软件的采样频率:一方面,采用专门的采样芯片以减少一次采样的时间;另一方面,可以从软件上进行改进,例如可以先将采集的数据存在内存中,达到一定量后再一次性写入硬盘。据文献报道[4],可以用多媒体定时器实现300Hz左右的采样频率。
[1]董秀珍.生物电阻抗成像研究的现状与挑战[J].中国生物医学工程年报,2008,27(5):641-643.
[2]史学涛,霍旭阳,尤富生,等.颅内出血电阻抗成像系统及初步动物实验[J].航天医学与医学工程,2007,20(1):24-27.
[3]郑存红,胡荣强,赵瑞峰.用Visual C++实现实时数据采集[J].计算机应用研究,2002,22(4):103-106.
[4]文治洪,胡文东,李晓京,等.多媒体计时器在医学信号采集中的应用[J].医疗卫生装备,2008,29(9):356-359.
[5]王伟,徐国华.多媒体定时器在工业控制中的应用[J].微型机与应用,2001,20(12):8-12.
[6]高伟,关宏伟.Windows环境下串口数据的高速实时采集[J].哈尔滨师范大学自然科学学报,2003,19(6):53-56.
[7]常发亮,刘静.多线程下多媒体定时器在快速数据采集中的应用[J].计算机应用,2003,23(S1):177-181.
[8]周鸣籁,邵雷.Windows环境下精确定时的实现[J].微计算机应用,2001,22(5):311-314.
(收稿:2010-08-20)
Application of Multimedia Timer in Evaluation of Precision of EIT Data Acquisition
TAO Feng,SHI Xue-tao,FU Feng,LIU Rui-gang,YOU Fu-sheng,DONG Xiu-zhen
(Department of Biomedical Engineering,the Fourth Military Medical University,Xi'an 710032,China)
TP311.131
A
1003-8868(2011)02-0001-03
国家自然科学基金重点项目(50937005);国家科技支撑计划项目(2006BAI03A14)
陶峰(1985-),男,陕西西安人,硕士研究生,主要研究方向为电阻抗成像算法的改进,E-mail:mailtotf@stu.xjtu.edu.cn;董秀珍(1945-),女,河北丰润人,教授,博士研究生导师,本刊编委,主要从事生物医学工程及生物医学成像新技术方面的研究。
董秀珍,E-mail:dongyang@fmmu.edu.cn