2024年3月5日发(作者:)

多媒体定时器的使用

在Windows系统下播放多媒体时,需要去精确控制播放过程,如果用Windows产生的WM_TIMER常规定时器来实现,多媒体画面会出现断断续续的现象,原因在于WM_TIMER只能提供大于等于55ms的精确定时。解决办法就是利用Windows系统本身提供的一个可以精确到1ms的多媒体定时器,它完全可以保证多媒体播放的实时性要求。

多媒体定时器不依赖于WM_TIMER消息,使用自己单独的线程来调用一个自己的回调函数。它的优先级很高,每隔一定时间就发送一个消息而不管其它消息是否执行完。所以无论应用程序在进行什么工作,操作系统都能在多媒体定时器事件到来时中断该程序,而先去调用多媒体定时器的回调函数。此外,对于现在的Intel CPU来说,它的最小定时精度通常都可以达到微秒级,足以满足步进电机控制的定时要求。

利用QueryPerformanceFrequency()和QueryPerformanceCounter()函数即可实现精确定时。该函数的定时精度与CPU的时钟频率高低有关系,即需要硬件支持,它们的函数原型如下:

BOOL QueryPerformanceFrequency (LARGE_INTEGER *lpFrequency)

BOOL QueryPerformanceCounter (LARGE_INTEGER *lpCount);

LARGE_INTEGER是一个联合结构,它可以是8字节的整型数,亦可两个4字节的整数,该联合的原型如下:

typedef union _LARGE_INTEGER

{

struct

{

DWORD LowPart ;

LONG HighPart ;

};

LONG QuadPart ;

} LARGE_INTEGER ;

在该联合的字段含义需要在定时使用之前进行定义,其定义过程为首先调用QueryPerformanceFrequency(),去获取CPU的时钟频率计数,然后在需要严格定时的事件发生之前和发生之后,各调用一次QueryPerformanceCounter()函数,根据两次调用该函数所获取的时钟频率计数值做差,即可得到计算机执行一次指令所消耗的技术值,从而根据实际定时或延时需求,按倍数的扩大计数值即可。使用这两个函数进行采样周期定时可按如下操作步骤完成:

1、利用QueryPerformanceFrequency()函数去获取计算机CPU的时钟频率;

多媒体定时器的使用

2、在采样周期定时的起始和终止处,分别调用QueryPerformanceCounter()获得两次CPU的时钟频率计数值,分别记为Num1和Num2,再将计数值转换成时间间隔,如果时钟频率为Freq,那么时间间隔interval=(Num2-Num1)/Freq,如果应用程序判别到interval值大于等于定时采样周期时,那么终止延迟或定时子程序的调用。

下边的代码实现了定时时间为大于1微秒的精确定时,用于步进电机驱动器脉冲周期延迟。其实现函数为MotorPulseDelay(double fTs),double fTs表示需要延迟的时间的微秒数,代码描述如下:

void MotorPulseDelay(double fTs)

{

LARGE_INTEGER litmp;

LONGLONG QPart1=0.0;

LONGLONG QPart2=0.0;

double dfMinus=0;

double dfFreq=0;

double dfTim=0;

QueryPerformanceFrequency(&litmp);

dfFreq=(double)rt;

QueryPerformanceCounter(&litmp);

QPart1=rt;

QPart2=QPart1;

dfTim=0.0;

while(dfTim<=fTs)

{

QueryPerformanceCounter(&litmp);

QPart2=rt;

dfMinus=(double)(QPart2-QPart1);

dfTim=dfMinus/dfFreq;

}

}