现在需要精确到ms级,有没有关于多媒体计时器或高精度计时器之类的例子,搜了老半天也没有很全的

解决方案 »

  1.   

    从我保存的网页里面copy来的
    使用多媒体定时器timeSetEvent()函数,该函数定时精度为ms级。利用该函数可以实现周期性的函数调用。如示例工程中的Timer6和Timer6_1。函数的原型如下: 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()将之释放。   方式七:对于精确度要求更高的定时操作,则应该使用QueryPerformanceFrequency()和 QueryPerformanceCounter()函数。这两个函数是VC提供的仅供Windows 95及其后续版本使用的精确时间函数,并要求计算机从硬件上支持精确定时器。如示例工程中的Timer7、Timer7_1、Timer7_2、Timer7_3。QueryPerformanceFrequency()函数和QueryPerformanceCounter()函数的原型如下:BOOL QueryPerformanceFrequency(LARGE_INTEGER *lpFrequency); BOOL QueryPerformanceCounter(LARGE_INTEGER *lpCount);  数据类型ARGE_INTEGER既可以是一个8字节长的整型数,也可以是两个4字节长的整型数的联合结构, 其具体用法根据编译器是否支持64位而定。该类型的定义如下:typedef union _LARGE_INTEGER { struct { DWORD LowPart ;// 4字节整型数 LONG HighPart;// 4字节整型数 }; LONGLONG QuadPart ;// 8字节整型数 }LARGE_INTEGER ;  在进行定时之前,先调用QueryPerformanceFrequency()函数获得机器内部定时器的时钟频率, 然后在需要严格定时的事件发生之前和发生之后分别调用QueryPerformanceCounter()函数,利用两次获得的计数之差及时钟频率,计算出事件经 历的精确时间。下列代码实现1ms的精确定时:LARGE_INTEGER litmp; LONGLONG QPart1,QPart2; double dfMinus, dfFreq, dfTim; QueryPerformanceFrequency(&litmp); dfFreq = (double)litmp.QuadPart;// 获得计数器的时钟频率 QueryPerformanceCounter(&litmp); QPart1 = litmp.QuadPart;// 获得初始值 do { QueryPerformanceCounter(&litmp); QPart2 = litmp.QuadPart;//获得中止值 dfMinus = (double)(QPart2-QPart1); dfTim = dfMinus / dfFreq;// 获得对应的时间值,单位为秒 }while(dfTim<0.001);  其定时误差不超过1微秒,精度与CPU等机器配置有关。 下面的程序用来测试函数Sleep(100)的精确持续时间:LARGE_INTEGER litmp; LONGLONG QPart1,QPart2; double dfMinus, dfFreq, dfTim; QueryPerformanceFrequency(&litmp); dfFreq = (double)litmp.QuadPart;// 获得计数器的时钟频率 QueryPerformanceCounter(&litmp); QPart1 = litmp.QuadPart;// 获得初始值 Sleep(100); QueryPerformanceCounter(&litmp); QPart2 = litmp.QuadPart;//获得中止值 dfMinus = (double)(QPart2-QPart1); dfTim = dfMinus / dfFreq;// 获得对应的时间值,单位为秒   由于Sleep()函数自身的误差,上述程序每次执行的结果都会有微小误差。下列代码实现1微秒的精确定时:LARGE_INTEGER litmp; LONGLONG QPart1,QPart2; double dfMinus, dfFreq, dfTim; QueryPerformanceFrequency(&litmp); dfFreq = (double)litmp.QuadPart;// 获得计数器的时钟频率 QueryPerformanceCounter(&litmp); QPart1 = litmp.QuadPart;// 获得初始值 do { QueryPerformanceCounter(&litmp); QPart2 = litmp.QuadPart;//获得中止值 dfMinus = (double)(QPart2-QPart1); dfTim = dfMinus / dfFreq;// 获得对应的时间值,单位为秒 }while(dfTim<0.000001);其定时误差一般不超过0.5微秒,精度与CPU等机器配置有关
      

  2.   

    CreateWaitableTimer、SetWaitableTimer。
      

  3.   

    这些是可以的,不过从xp类系统从本质上来说是很难做到1ms的
      

  4.   

    UINT CRealTimeDlg::TimerScanStart(LPTIMECALLBACK fptc,int TimeCycle,BOOL bTime_OneShot)
    {
    UINT TimeID = 0;
    TIMECAPS tc;
    if(::timeGetDevCaps(&tc,sizeof(TIMECAPS))==TIMERR_NOERROR)
    {
    DWORD wAccuracy;
    wAccuracy=min(max(tc.wPeriodMin,TIMER_ACCURACY),tc.wPeriodMax);
    if(timeBeginPeriod(wAccuracy) == TIMERR_NOERROR )
    {
    // 参数 TIME_PERIODIC: 周期执行
    if(TimeCycle >= wAccuracy && TimeCycle <= tc.wPeriodMax)
    {
    if(bTime_OneShot)
    {//只执行一次
    TimeID = ::timeSetEvent(TimeCycle,wAccuracy,fptc,(DWORD)this,TIME_ONESHOT);
    }
    else
    {//周期执行
    TimeID = ::timeSetEvent(TimeCycle,wAccuracy,fptc,(DWORD)this,TIME_PERIODIC);
    }
    }
    timeEndPeriod(wAccuracy);
    }

    }
    return TimeID ;
    }
      

  5.   

    顶..
    多媒体计时器是综合CPU占用和精度两方面比较好的方法..