W indows操作系统下的软件定时器的设计与应用

摘要:为了实现计算机软件的精确定时,设计了一种高精度的微秒级定时器。该定时器利用计算机的高精度计数器完成定时功能,在长城Pentiurn 1V计算机上的定时精度可以达到几十微秒。为了检验此高精度定时器的性能,利用Visual C++编制了基于Windows多线程机制的控制程序,使计算机通过一个l6位的D/A转换器输出不同频率和波形的模拟信号。试验结果表明,基于Windows的高精度定时器具有很高的定时稳定性和准确性。最后,利用该定时器对压电陶瓷驱动器的特性进行了试验研究。
关键词:高精度定时器 Windows编程 多线程

1)Windows操作系统的定时器。
该定时器利用WM—TIMER消息映射来进行简单的时间控制。WM—TIMER消息由操作系统18.2Hz的系统中断产生。其定时精度可达到55ms左右。此定时器的使用非常简单,只需要在SetTimer()中设置时间间隔,并在OnTimer()中添加消息响应处理语句,用来完成定时时间的操作。由于Windows操作系统工作方式为多线程的抢先式多任务,并且WM—TIMER消息的优先级较低,因此,这种定时方法使用于屏幕的定时刷新和位图动态显示等要求定时精度不高的情况。

2)多媒体定时器。
该定时器拥有自己单独的线程,调用回调函数。它不依赖于消息机制,而是建立在中断的基础上。在20ms以上的定时任务中,精度可达1ms。定时间隔在7~20ms之间,误差在1~3ms。对于小于7ms的定时,则不易实现。

3)为了提高定时精度,还可以采用软硬件结合的形式。
这种定时器利用外部硬件时钟电路来获取精确的定时时间触发信号,将外部的定时触发作为一个硬件中断,定时精度可以达到几个微秒。
由于Windows操作系统屏蔽了对硬件的操作,系统应用程序只能工作于CPU的ring 3级,没有对硬件端口的操作权限。因此,需要编写虚拟设备驱动程序(VxD),增加了很大的工作量和不稳定因素。
在较新的计算机硬件系统中,包含有高精度性能的计数器,其计数频率与CPU的时钟频率有关。利用它可以较准确地估计一段程序代码的运行时间。Win 32 API提供的QueryPerformanceFrequency()函数可以取得高精度计数器的频率,QueryPerformanceCounter()函数可以用来取得计数器的当前记数值。其函数的原型如下:
BOOL QueryPerformanceFrequency f LARGE—INTEGER1 pFrequency);
BOOL QueryPerformanceCounter f LA RGE —INTEGER1pCount);
其中,数据类型LARGE—INTERGER既可以是一个8字节长的整型数,也可以是两个4字节长的整型数的联合结构,其具体用法根据编译器是否支持64位而定。该类型的定义如下:
typedef union—LARGE—INTEGER{
struct{
DWORD LowPart;//4字节整型数
LONG HightPart;/4字节整型数
}
LONGLONG QuadPart;/8字节整型数
}La.RGE—INTEGER;
进行时间计算时,先调用QueryPerformance.Frequency()函数,获得计算机内部定时器的时钟频率I厂c接着,在需要严格定时的时间发生之前和发生之后,分别调用QueryPerformanceCounter()函数。利用两次获得的计数之差和时钟频率,就可以计算出事件经历的准确时间。对以上算法稍加改造,就可以得到微秒级的精确定时器。为了定时,就要得到一段精确的时间段。其具体方法为:
1)获得定时器的时钟频率.厂;
2)计算一段时间t所需要的记数值Count=I厂×t;
3)读取计时开始时的高精度计数器的初始值Countl;
4)反复读取高精度计数器的数值Count 2,直到Count 2一Count 1/Count为止。发送定时时间到达的消息。
5) 将Count 2的记数值赋给Count 1,转入4)。
这样,就可以得到一个定时时间长度近似为t的微秒级定时器。但是实际使用过程中,定时器会存在一些误差,误差的大小和高精度计数器的频率有关。计数器的频率越高,误差也就越小。另外,由于Windows操作系统为基于抢占式多任务的工作方式,因此,此定时器的定时精度也受到一定的影响。
利用Windows操作系统的多线程机制,可以实现定时和实时显示的功能。将主线程用于与用户的交互,如参数的设定、反馈信息的显示等。工作线程用于启动定时器,发送控制信号,并将控制信息传给主线程。工作线程的流程图如图1所示:

 

你可能感兴趣的:(多线程,工作,windows,Integer,任务,编译器)