vc6.0中c說話掌握台法式中的准時技巧(准時器)。本站提示廣大學習愛好者:(vc6.0中c說話掌握台法式中的准時技巧(准時器))文章只能為提供參考,不一定能成為您想要的結果。以下是vc6.0中c說話掌握台法式中的准時技巧(准時器)正文
翻開main.c編譯運轉,留意,翻開main.c以後必定要將win32timer.c也加進工程中一路編譯,上面有圖。
在開辟單片機、ARM和Linux體系的法式時,由於硬件准時中止的存在我們很便利結構出准時ISR,但是在VC6.0中,我們若何寫一個准時法式呢?
其實,就是timeSetEvent()這個函數的挪用。這個函數的說明見MSDN。具體道理,請看我代碼中的正文,我寫得很具體了。
main.c
//======================
// main.c
//======================
#include <stdio.h>
#include "win32timer.h" // UserTimerSet(uDelay,UserFun)
int cnt = 0;
void myISR_Called_Per_1000ms(void);
int main(void)
{
/* 每1000ms挪用一次myISR_Called_Per_1000ms */
UserTimerSet ( 1000, myISR_Called_Per_1000ms ) ;
while (cnt<10);
return 0;
}
void myISR_Called_Per_1000ms(void)
{
printf("The Program has run %ds\n",cnt++);
}
win32timer.h
/*
* 應用解釋:
*
* 1. 用戶法式須要 #include "win32timer.h" ;
* 2. 用戶須要將 win32timer.c 添加至根目次,或添加至工程;
* 3. 用戶法式直接挪用UserTimerSet(uDelay,UserFun); 便可,
* 個中,uDelay為准時挪用的准時周期,單元為毫秒(ms),
* UserFun為用戶被調函數void ISR(void)的函數名ISR。
* 4. 可以同時應用多個timeSetEvent,每一個timeSetEvent都可以
* 前往准時器編號,具體見MSDN關於timeSetEvent的解釋。
*/
//=======================
// win32timer.h
//=======================
#ifndef __WIN32TIMER_H__
#define __WIN32TIMER_H__
void UserTimerSet ( unsigned int uDelay, void (*UserFun)(void) ) ;
#endif // @ #ifndef __WIN32TIMER_H__
win32timer.c
//=======================
// win32timer.c
//=======================
#include <windows.h>
#include "win32timer.h"
#pragma comment(lib,"winmm.lib") //導入winmm.lib多媒體庫
/* 全局變量 */
HANDLE mainhandle; //主線程句柄
CONTEXT Context; //主線程切換高低文
static void (*TimerCallFun)(void); //聲明用戶挪用函數指針
/* 函數聲明 */
static void __stdcall TimerISR(unsigned int uTimerID, unsigned int uMsg, unsigned long dwUser, unsigned long dw1, unsigned long dw2);
//======================================================================================
// 函數功效:用戶須要挪用的准時器設置(初始化)函數
// 進口參數:uDelay:准時器准時時長,單元為ms
// void (*UserFun)(void):指向用戶函數 void fun (void) 的函數指針
// 返 回 值:無
//======================================================================================
void UserTimerSet ( unsigned int uDelay, void (*UserFun)(void) )
{
HANDLE cp,ct;
TimerCallFun = UserFun; //獲得用戶被准時挪用的函數的函數指針
Context.ContextFlags = CONTEXT_CONTROL;
cp = GetCurrentProcess(); //獲得以後過程句柄
ct = GetCurrentThread(); //獲得以後線程偽句柄
DuplicateHandle( cp, ct, cp, &mainhandle, 0, TRUE, 2 ); //偽句柄轉換,獲得線程真句柄
/*模仿設置准時器中止,開啟一個准時器線程*/
timeSetEvent( uDelay, 0, TimerISR, 0, TIME_PERIODIC );
/*假如須要撤消准時器,則可以挪用timeKillEvent()函數,詳見MSDN*/
}
//======================================================================================
// 函數功效:timeSetEvent須要准時挪用的函數
// 進口參數:unsigned int uTimerID, unsigned int uMsg, unsigned long dwUser, unsigned long dw1, unsigned long dw2,詳見MSDN
// 返 回 值:無
//======================================================================================
static void __stdcall TimerISR(unsigned int uTimerID, unsigned int uMsg, unsigned long dwUser, unsigned long dw1, unsigned long dw2)
{
SuspendThread(mainhandle); //中斷主線程的運轉,模仿中止發生.但沒有保留存放器
GetThreadContext(mainhandle, &Context); //獲得主線程高低文,為切換義務做預備
//===========================================================================================
(*TimerCallFun)(); //或許TimerCallFun(); ———— 用戶自界說完成的中止挪用
//===========================================================================================
ResumeThread(mainhandle); //模仿中止前往,主線程得以持續履行
}
工程圖
運轉成果