27,375
社区成员
发帖
与我相关
我的任务
分享
#include "timerconfig.h"
#include "chiptypedef.h"
#include <limits.h>
#include <string.h>
code const WORD TIMER0_INIT_VALUE = UINT_MAX - ((WORD)((float)OSC_FREQUENCY * 1.0f / 12 * 1000)) * TIMER0_BASE_INTERVAL;
idata TIMERINFO TimerInfoArray[MAX_TIMER_EVENT_NUM] = {0};
TIMERPROC g_pfnTimerFunc = NULL;
BYTE g_nTimerInfoNum = 0; //当前队列的元素个数
void InitTimer0()
{
TMOD |= T0_M0_; //定时器0,工作方式1
TH0 = HIBYTE(TIMER0_INIT_VALUE);
TL0 = LOBYTE(TIMER0_INIT_VALUE);
TR0 = 0; //停止定时器0
ET0 = 0; //关定时器0中断
EA = 1;
}
BOOL SetTimerCallback(TIMERPROC lpTimerFunc)
{
if(lpTimerFunc == NULL)
return FALSE;
g_pfnTimerFunc = lpTimerFunc;
return TRUE;
}
BOOL SetTimer0(BYTE nID, WORD wInterval)
{
TIMERINFO ti;
if(g_pfnTimerFunc == NULL || nID == 0 || wInterval == 0)
return FALSE;
if(wInterval % TIMER0_BASE_INTERVAL != 0) //定时间隔必须是TIMER0_BASE_INTERVAL的整数倍
return FALSE;
if(FindID(nID) != MAX_TIMER_EVENT_NUM) //若已经有相同的ID存在
return FALSE;
ti.nID = nID;
ti.wInterval = wInterval;
ti.wElapse = wInterval;
if(!AddTail(&ti))
return FALSE;
TR0 = 1; //启动定时器0
ET0 = 1; //开定时器0中断
return TRUE;
}
/*
BOOL KillTimer0(BYTE nID)
{
if(!Remove(nID) || nID == 0)
return FALSE;
if(g_nTimerInfoNum == 0) //若最后一个定时事件已经停止,则关定时器中断
ET0 = 0;
return TRUE;
} */
static BYTE FindID(BYTE nID)
{
BYTE i = 0;
for(i = 0; i < MAX_TIMER_EVENT_NUM; i++)
{
if(TimerInfoArray[i].nID == nID)
return i;
}
return MAX_TIMER_EVENT_NUM;
}
static BOOL AddTail(const TIMERINFO* pTimerInfo)
{
if(g_nTimerInfoNum == MAX_TIMER_EVENT_NUM || pTimerInfo == NULL)
return FALSE;
memcpy(&TimerInfoArray[g_nTimerInfoNum], pTimerInfo, sizeof(TIMERINFO));
g_nTimerInfoNum++;
return TRUE;
}
/*
static BOOL Remove(BYTE nID)
{
BYTE nIndex = FindID(nID);
BYTE nRest = g_nTimerInfoNum - nIndex - 1;
if(nIndex == MAX_TIMER_EVENT_NUM || nID == 0)
return FALSE;
if(nRest == 0) //已经是队列尾元素
{
memset(&TimerInfoArray[nIndex], 0, sizeof(TIMERINFO));
}
else
{
//删除后,前移
memcpy(&TimerInfoArray[nIndex], &TimerInfoArray[nIndex + 1], sizeof(TIMERINFO) * nRest);
memset(&TimerInfoArray[nIndex + nRest], 0, sizeof(TIMERINFO) * (MAX_TIMER_EVENT_NUM - (nIndex + nRest) - 1));
}
g_nTimerInfoNum--;
return TRUE;
} */
void Timer0ISR() interrupt TF0_VECTOR
{
BYTE i = 0;
TF0 = 0;
TH0 = HIBYTE(TIMER0_INIT_VALUE);
TL0 = LOBYTE(TIMER0_INIT_VALUE);
for(i = 0; i < g_nTimerInfoNum; i++)
{
TimerInfoArray[i].wElapse -= TIMER0_BASE_INTERVAL;
if(TimerInfoArray[i].wElapse == 0)
{
(*g_pfnTimerFunc)(TimerInfoArray[i].nID);
TimerInfoArray[i].wElapse = TimerInfoArray[i].wInterval;
}
}
}