通过回调函数注册定时器触发事件
1、说明
使用回调函数,注册定时器触发事件的模式,提高定时器中断的可操作性,那如何实现呢?
2、.h文件
下面是定时器句柄的声明
3、.c文件
3.1、静态定时器句柄头
3.2、定时器回调函数处理
下面的函数是放在1ms的中断中的,不断执行;注意中断中不宜挂载过多的定时器句柄
3.3、注册定时器句柄
3.4、删除注册的句柄
3.5、启动xxx定时器句柄
3.6、暂停xxx定时器句柄
4、定时器中断函数
1ms定时器中断中,就放定时器回调处理的函数即可
5、应用说明
1、注册定时器句柄
2、启动定时器句柄
3、根据实际需要,删除 or 暂停 某个定时器句柄,之后再重新注册 or 启动
6、源码
//1ms定时器中断
void timer_interrupt_1ms(void)
{
timerCallbackHandle_1ms();
}
typedef void (*pCallback)(void); //回调函数指针类型
typedef enum{
IDLE = 0,
ONGOING
}E_STATE;
typedef struct TimerHandle_st{
const char *name; //名字
uint32_t cnt; //累积值
uint32_t upperCnt; //目标值
E_STATE state; //运行状态
pCallback callback; //回调函数
struct TimerHandle_st *pNext; //指向下一个 TimerHandle_st
}TimerHandle_st;
//初始化一个静态的定时器句柄头
static TimerHandle_st *pTimerHandle = NULL;
//1ms 定时器回调处理
void timerCallbackHandle_1ms(void)
{
TimerHandle_st *pTHd = pTimerHandle;
while(pTHd != NULL)
{
if(pTHd->callback != NULL && pTHd->state == ONGOING)
{
//定时到了
if(pTHd->cnt >= pTHd->upperCnt)
{
pTHd->cnt = 0; //重装载计数值
pTHd->callback(); //执行回调函数
}
else
{
pTHd->cnt++;
}
pTHd = pTHd->pNext; //遍历下一个 TimerHandle_st
}
}
}
//注册定时器句柄
bool timerHandleRegister(const char *name, pCallback *p, uint32_t upperCnt)
{
TimerHandle_st *pTHd = pTimerHandle;
//首次注册,头部 TimerHandle_st
if(pTHd == NULL)
{
pTHd = (TimerHandle_st *)malloc(sizeof(TimerHandle_st));
if(pTHd == NULL)
{
return false;
}
pTHd->name = name;
pTHd->cnt = 0;
pTHd->upperCnt = upperCnt;
pTHd->state = IDLE;
pTHd->callback = p;
pTHd->pNext = NULL;
}
else
{
while(pTHd != NULL)
{
if(pTHd->pNext == NULL)
{
pTHd->pNext = (TimerHandle_st *)malloc(sizeof(TimerHandle_st));
if(pTHd->pNext == NULL)
{
return false;
}
pTHd->pNext.name = name;
pTHd->pNext.cnt = 0;
pTHd->pNext.upperCnt = upperCnt;
pTHd->pNext.state = IDLE;
pTHd->pNext.callback = p;
pTHd->pNext.pNext = NULL;
break;
}
pTHd = pTHd->pNext;
}
}
return true;
}
//通过 name 删除注册的句柄
bool timerHandleDelete(const char *name)
{
TimerHandle_st *pTHd = pTimerHandle;
TimerHandle_st *preTHd = pTHd;
while(pTHd != NULL)
{
if(strncmp(pTHd->name, name, strlen(pTHd->name)) == 0)
{
preTHd->pNext = pTHd->pNext; //上一个句柄连接到下一个句柄
free(pTHd);
return true;
}
preTHd = pTHd; //记录当前句柄
pTHd = pTHd->pNext; //跳转下一个句柄
}
return false;
}
//通过 name 启动xxx定时器句柄
bool timerHandleStart(const char *name)
{
TimerHandle_st *pTHd = pTimerHandle;
while(pTHd != NULL)
{
if(strncmp(pTHd->name, name, strlen(pTHd->name)) == 0)
{
pTHd->state = ONGOING;
return true;
}
pTHd = pTHd->pNext; //跳转下一个句柄
}
return false;
}
//通过 name 暂停xxx定时器句柄
bool timerHandleStop(const char *name)
{
TimerHandle_st *pTHd = pTimerHandle;
while(pTHd != NULL)
{
if(strncmp(pTHd->name, name, strlen(pTHd->name)) == 0)
{
pTHd->state = IDLE;
return true;
}
pTHd = pTHd->pNext; //跳转下一个句柄
}
return false;
}