?? timer.c
字號:
/*********************************************************************
*Copyright-(c) 2003, *
*All rights reserved. *
* *
* 文件名稱: TIMER.C *
* 摘要 : For 80x86 *
* *
* 當前版本: 2.3 *
* 作者 : Liy-tj *
* 完成日期: 2006年2月23日 *
* 修改 : 1、把在中斷內調用任務函數功能作為可裁減功能,可以通過頭 *
* 文件中的TMR_INTR_FNCT_EN來裁減。 *
* *
* 當前版本: 2.2 *
* 作者 : Liy-tj *
* 完成日期: 2005年4月15日 *
* 修改 : 1、修改了TMR_Delete()函數,增加對ptmrid指針是否為NULL的*
* 判斷。 *
* *
* 取代版本: 2.1 *
* 作者 : Liy-tj *
* 完成日期: 2005年3月3日 *
* 修改 : 1、加入獲取計數值函數TMR_GetCtr(),用于實時獲取定時器的*
* 計數值。 *
* *
* 取代版本: 2.0 *
* 作者 : Liy-tj *
* 完成日期: 2004年9月29日 *
* 修改 : 1、將系統節拍TMR_TICK_LENGTH的單位由毫秒變為微秒,從而 *
* 使計時器的定時范圍可以小于1毫秒。但在編程時注意,系 *
* 統節拍不應太短,使系統負載過大; *
* 2、定時長度的單位由原先統一的毫秒,改為可在微秒、毫秒和*
* 秒之間選擇,以免在長時間定時時,數據過大而溢出。 *
* *
* 取代版本: 1.2 *
* 作者 : Liy-tj *
* 完成日期: 2004年9月20日 *
* 修改 : 1、對模塊內的函數進行重新命名,采用"模塊名_函數名"的格 *
* 式,以期與其他模塊統一; *
* 2、將全局變量的定義放到頭文件中; *
* 3、修改TMR_Reload()的工作方式,使其在復位計時器計數值后*
* 讓計時器開始運行; *
* *
* 取代版本: 1.1 *
* 作者 : Liy-tj *
* 完成日期: 2003年10月22日 *
* 修改 : 1、將計時器數據結構由結構體改為數組,提高代碼效率; *
* 2、增加計時器工作模式屬性,包含CONT(連續)、ONCE(單次) *
* 和DELAY(延時)模式; *
* 3、增加了LongDelay()函數,用以實現數毫秒到幾十秒范圍的 *
* 延時,若使用TMR_LARG_RANG模式,延時長達數天; *
* 4、定義了計時器中斷使用的寄存器組常數,可以根據中斷函 *
* 數設定TmrIntTask()函數使用的寄存器組。 *
* 5、修改了TmrDelet()函數,傳入計時器id的指針,在刪除計 *
* 時器后,將計時器id賦為TMR_MAX; *
* *
* 取代版本: 1.0 *
* 作者 : Liy-tj *
* 完成日期: 2003年9月22日 *
* 修改 : 1、計時器計時范圍分為兩檔,小范圍為0~65,535,大范圍為 *
* 0~4,294,967,295,通過宏定義TMR_LARG_RANG進行選擇。 *
* 2、完善了TmrInit()函數,對計時器參數都進行了初始化; *
* 3、對計時器函數進行修改的程序段都放入臨界區,防止中斷進*
* 入,發生沖突; *
* 4、修改了TmrDelet()函數,傳入計時器指針的指針,在刪除計*
* 時器后,將計時器指針指向空; *
* 5、在大部分函數中添加了計時器指針非空判斷,以免發生誤操*
* 作; *
* 6、將定時計數單位統一為毫秒,取消TmrSetMST()函數。 *
* *
* 取代版本: 0.4 *
* 作者 : Liy-tj *
* 完成日期: 2003年9月5日 *
* 修改 : 1、增加了兩個函數(宏定義),分別是TmrCallIntFnct()和 *
* TmrCallFnct(),用于直接調用關聯函數,并且將計時器重 *
* 置,重新開始計時。 *
* *
* 取代版本: 0.3 *
* 作者 : Liy-tj *
* 完成日期: 2003年8月31日 *
* 修改 : 1、不再使用分配動態內存方式創建新計時器,而是在程序運 *
* 開始處根據最多計時器數量來定義計時器數組,將計時器 *
* 分配到靜態內存中; *
* 2、分別由工作計時器鏈表和空閑計時器鏈表來管理計時器模 *
* 塊; *
* 3、新創建的計時器插入到工作鏈表的首部,而刪除的計時器 *
* 則被插入到空閑計時器鏈表的尾部。 *
* *
* 取代版本: 0.2 *
* 作者 : Liy-tj *
* 完成日期: 2003年8月29日 *
* 修改 : 1、取消觸發標志結構體,將標志添加到計時器結構體中; *
* 2、計時器操作函數不再通過標志結構體來獲取計時器地址; *
* 3、在計時器結構體中增加的一個函數指針,兩個函數指針分 *
* 別用于指向中斷內運行函數和中斷外運行函數; *
* 4、計時器溢出后,若指向中斷內運行函數指針非空,則直接 *
* 調用函數;反之,將觸發標志置位; *
* *
* 取代版本: 0.1 *
* 作者 : Liy-tj *
* 完成日期: 2003年8月28日 *
*********************************************************************/
#define TMR_GLOBALS
#include "includes.h"
/*********************************************************************
* 初始化計時器模塊 *
* *
* 功能描述 : 對計時器數組進行初始化,在程序開始時調用。 *
* *
* 輸入參數 : 無 *
* 返回參數 : 無 *
* 文件名稱 : TIMER.C *
* 作者 : Liy-tj *
*********************************************************************/
void TMR_Init(void)
{
TMR_ID tmrid = 0;
OS_ENTER_CRITICAL();
for(; tmrid<MAX_TMR; tmrid++)
{
TmrSta[tmrid] = 0;
TmrInit[tmrid] = 0;
TmrCtr[tmrid] = 0;
TmrFnct[tmrid] = NULL; //指向在中斷過程外運行的函數的指針
#ifdef TMR_INTR_FNCT_EN
TmrIntFnct[tmrid] = NULL; //指向在中斷過程中運行的函數的指針
#endif
}
OS_EXIT_CRITICAL();
}
/**********************************************************************
* 獲取一個空計時器 *
* *
* 功能描述 : 這個函數計時器數組中獲取一個空計時器,并返回計時器 *
* id。 *
* *
* 輸入參數 : 無 *
* 返回參數 : tmrid 計時器的編號 *
* 文件名稱 : TIMER.C *
* 作者 : Liy-tj *
**********************************************************************/
TMR_ID TMR_GetFree(void)
{
TMR_ID tmrid = 0;
while((TmrSta[tmrid]&TMR_EN) && (tmrid < MAX_TMR))
{
tmrid++;
}
return (tmrid);
}
/**********************************************************************
* 創建一個計時器 *
* *
* 功能描述 : 這個函數創建一個新計時器。并且根據輸入的參數對計時 *
* 器進行初始化。 *
* *
* 輸入參數 : tmrinit 計時器計時長度 *
* tmrunit 計時器計時長度單位,微秒:UNIT_US *
* 毫秒:UNIT_MS *
* 秒 :UNIT_S *
* tmrmod 計時器工作模式 *
* intfnct 指向中斷內調用函數的指針 *
* fnct 指向中斷外調用函數的指針 *
* 返回參數 : tmrid 創建的計時器的id *
* 文件名稱 : TIMER.C *
* 作者 : Liy-tj *
**********************************************************************/
#ifdef TMR_LARG_RANG
TMR_ID TMR_Create(INT32U tmrinit, INT8U tmrunit, INT8U tmrmod,
void (*intfnct)(void), void (*fnct)(void))
#else
TMR_ID TMR_Create(INT16U tmrinit, INT8U tmrunit, INT8U tmrmod,
void (*intfnct)(void), void (*fnct)(void))
#endif
{
TMR_ID tmrid = TMR_GetFree();
if(tmrid < MAX_TMR)
{
if((tmrmod != TMR_MOD_CONT)&&(tmrmod != TMR_MOD_ONCE)
&&(tmrmod != TMR_MOD_DELAY))
{
tmrid = MAX_TMR;
}
else
{
OS_ENTER_CRITICAL();
TmrSta[tmrid] = 0x01;
TmrSta[tmrid] |= tmrmod;
TMR_SetLen(tmrid, tmrinit, tmrunit);
TmrFnct[tmrid] = fnct;
#ifdef TMR_INTR_FNCT_EN
TmrIntFnct[tmrid] = intfnct;
#endif
OS_EXIT_CRITICAL();
}
}
return (tmrid);
}
/*********************************************************************
* 開始一個計時器 *
* *
* 功能描述 : 這個函數使一個計時器開始計數。 *
* *
* 輸入參數 : tmrid 計時器id *
* 返回參數 : 無 *
* 文件名稱 : TIMER.C *
* 作者 : Liy-tj *
*********************************************************************/
void TMR_Start(TMR_ID tmrid)
{
if((tmrid < MAX_TMR)&&((TmrSta[tmrid]&TMR_EN)==1)) //計時器已經創建
{
OS_ENTER_CRITICAL();
TmrSta[tmrid] |= TMR_RUN;
TmrSta[tmrid] &= TMR_FLG_DOWN;
OS_EXIT_CRITICAL();
}
}
/*********************************************************************
* 停止一個計時器 *
* *
* 功能描述 : 這個函數使一個計時器停止計數。 *
* *
* 輸入參數 : tmrid 計時器id *
* 返回參數 : 無 *
* 文件名稱 : TIMER.C *
* 作者 : Liy-tj *
*********************************************************************/
void TMR_Stop(TMR_ID tmrid)
{
if(tmrid < MAX_TMR)
{
OS_ENTER_CRITICAL();
TmrSta[tmrid] &= TMR_STOP;
TmrSta[tmrid] &= TMR_FLG_DOWN;
OS_EXIT_CRITICAL();
}
}
/*********************************************************************
* 重載計時器 *
* *
* 功能描述 : 這個函數使計時器的計數器重新開始計數。 *
* *
* 輸入參數 : tmrid 計時器id *
* 返回參數 : 無 *
* 文件名稱 : TIMER.C *
* 作者 : Liy-tj *
*********************************************************************/
#ifdef TMR_RELOAD_EN
void TMR_Reload(TMR_ID tmrid)
{
if(tmrid < MAX_TMR)
{
OS_ENTER_CRITICAL();
TmrCtr[tmrid] = TmrInit[tmrid];
TmrSta[tmrid]|= TMR_RUN;
TmrSta[tmrid]&= TMR_FLG_DOWN;
OS_EXIT_CRITICAL();
}
}
#endif
/**********************************************************************
* 修改計時器計時長度 *
* *
* 功能描述 : 修改計時器計時長度。 *
* *
* 輸入參數 : tmrid 計時器id *
* tmrinit 計時長度 *
* tmrunit 計時器計時長度單位,微秒:UNIT_US *
* 毫秒:UNIT_MS *
* 秒 :UNIT_S *
* 返回參數 : 無 *
* 文件名稱 : TIMER.C *
* 作者 : Liy-tj *
**********************************************************************/
#ifdef TMR_LARG_RANG
void TMR_SetLen(TMR_ID tmrid, INT32U tmrinit, INT8U tmrunit)
#else
void TMR_SetLen(TMR_ID tmrid, INT16U tmrinit, INT8U tmrunit)
#endif
{
INT32U inittemp; //計算定時長度的中間變量
if(tmrid < MAX_TMR)
{
switch(tmrunit)
{
case UNIT_MS: //定時單位為毫秒
inittemp = (INT32U)(((FP64)tmrinit/TMR_TICK_LENGTH)*1000+0.5)-1;
break;
case UNIT_S: //定時單位為秒
inittemp = ((INT32U)((FP64)tmrinit*(1000000.0/TMR_TICK_LENGTH)+0.5))-1;
break;
default: //缺省定時單位為微秒
inittemp = (INT32U)((FP64)tmrinit/TMR_TICK_LENGTH+0.5)-1;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -