多媒體定時器


Windows定時器

  在以Windows以平台的實時控制系統中,常常需要定時或周期性的完成某個動作,采樣時間的精度是系統得以正常運行的關鍵,對以Dos為平台的控制系統,可以通過對硬件的直接操作而得到精確的采樣時間,而對於Windows平台,由於Windows平台為搶占式多任務操作系統,系統管理所有硬件資源,用戶無法直接同硬件打交道,時間控制離不開操作系統的支持,因此,在Windows平台下如何精確的控制采樣頻率是一個很關鍵的技術。

一.普通定時器

  普通定時器是依賴消息機制的時間控制方法,首先由SetTimer函數創建一個內存對象,設定間隔時間,當到達要求的時間間隔時,計時器對象發送一個WM_TIMER消息,由相應函數處理,WM_TIMER消息優先級不高,且易出現消息合並情況,不能滿足工業實時控制系統的要求。

二.多媒體定時器

  多媒體定時器不依賴消息機制,而是有TimeSetEvent()產生一個獨立的線程,在一定的中斷次數到達后,直接調用預先設置的回調函數進行處理,而不必等待應用程序的消息隊列為空,保證的定時器的實時相應,是一種很理想的高精度定時器,可以實現精度為1ms的定時精度,相關的API如下:

1. MMRESULT timeGetDevCaps(

  LPTIMECAPS ptc, 

  UINT cbtc       

);

函數功能:獲取定時器設備能力

參數:ptc指向一個TIMECAPS型的結構,TIMECAPS有兩個成員,wPeriodMin和WperiodMax,表示定時器設備支持的最小時間周期和最大時間周期;cbtc表示TIMECAPS結構的大小

返回值:

2. MMRESULT timeBeginPeriod(

  UINT uPeriod 

);

函數功能:設置定時器設備的最小時間分辨率

參數:最小時間分辨率,以毫秒為單位

3. MMRESULT timeEndPeriod(

  UINT uPeriod 

);

函數功能:清除之前對定時器設備的設置

參數:timeBeginPeriod中指定的最小分辨率

注:

對定時器設備使用完成后,立刻調用這個函數,timeBeginPeriod和timeEndPeriod必須配對存在,並且指定的參數值也相同。

4. MMRESULT timeSetEvent(

  UINT           uDelay,     

  UINT           uResolution,

  LPTIMECALLBACK lpTimeProc, 

  DWORD_PTR      dwUser,     

  UINT           fuEvent     

);

函數功能:

創建並初始化定時器事件,給定定時器回調函數的入口地址

參數:

uDelay:定時器觸發的時間間隔,以毫秒為單位

uResolution:定時器設備的時間精度,以毫秒為單位,應大於或等於timeBeginPeriod中設置的值,默認為1ms,精度越高,系統在定時器上的負載就越大,通常選擇適合於應用程序的最大值

LpTimeProc:定時器觸發的事件的回調函數的地址

dwUser:傳遞給回調函數的數據

fuEvent:定時類型,TIME_ONESHOT表示uDelay毫秒后只產生一次事件,TIME_PERIODIC表示每隔uDelay毫秒周期性的產生事件

返回值:返回定時器事件的ID

5. MMRESULT timeKillEvent(

  UINT uTimerID 

);

函數功能:刪除一個指定的定時器事件

參數:指向要刪除的定時器事件的ID

注:

timeSetEvent和timeKillEvent必須配對出現,釋放系統為定時器分配的資源,定時器任務完成后,要及時刪除定時器,否則占用太多內存,導致系統越來越慢。

6. void CALLBACK TimeProc(UINT uID,UINT uMsg,DWORD dwUsers,DWORD dw1,DWORD dw2);

函數功能:回調函數

參數:uID,多媒體定時器的ID,ID值由timeSetEvent創建定時器事件時返回

uMsg,保留,當前未使用

dwUser,由timeSetEvent傳遞的用戶數據

dw1,dw2保留未使用

三.使用多媒體定時器的程序例子:

#include <Windows.h>

#include <MMSystem.h>

#include <iostream>

using namespace std;

#pragma comment(lib, "winmm.lib")

void CALLBACK TimeProc(UINT uID,UINT uMsg,DWORD dwUsers,DWORD dw1,DWORD dw2);

int main()

{

    UINT wTimerRes;

    UINT timerID;

    TIMECAPS ts;

    //確定多媒體定時器提供的最大和最小定時器事件周期

    timeGetDevCaps(&ts, sizeof(ts));

    wTimerRes = 1;

    //建立最小定時器精度

    timeBeginPeriod(wTimerRes);

    //啟動定時器事件,設置定時周期為100ms,分辨率是10毫秒

    timerID = timeSetEvent(100,10,TimeProc,NULL,TIME_PERIODIC);

    Sleep(50000);

    //關閉定時器事件

    timeKillEvent(timerID);

    //清除最小定時器精度

    timeEndPeriod(wTimerRes);

    return 0;

};

void CALLBACK TimeProc(UINT uID,UINT uMsg,DWORD dwUsers,DWORD dw1,DWORD dw2)

{

    cout<<uID<<endl;

}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM