|
之前自己的一个项目请教过坛友,如何对多个任务定时:
https://www.amobbs.com/thread-5735769-1-1.html
不少坛友都说软定时器可以解决。
这两天找到一个可以用的,分享给大家。
typedef enum tmrMode
{
MODE_ONE_SHOT = 0, //单次模式
MODE_PERIODIC, //周期模式
} tmrMode;//定时器模式
typedef enum tmrState
{
SOFT_TIMER_STOPPED = 0, //停止
SOFT_TIMER_RUNNING, //运行
SOFT_TIMER_TIMEOUT, //超时
SOFT_TIMER_WAITING //等待
} tmrState;//定时器状态。可通过函数获取这个状态。
typedef struct softTimer
{
unsigned char state; //状态
unsigned char mode; //模式
unsigned int period; //定时周期
unsigned int count; //定时计数用
pFun callback; //定时器回调函数
} softTimer;//定时器结构体。存储定时器任务内容及其他参数。
主要函数:
void softTimer_Creat(unsigned char id, tmrMode mode, unsigned int interval, pFun cb)
{
softTimerList[id].mode = mode;
softTimerList[id].period = interval;
softTimerList[id].count = 0;
softTimerList[id].callback = cb;
softTimerList[id].state = SOFT_TIMER_STOPPED;
}
创建定时器,后面的变量分别是定时器编号、定时器模式(单次或循环)、定时器触发时间、定时器事件(一个指针,指向函数)
void softTimer_Start(unsigned int id)
{
softTimerList[id].state = SOFT_TIMER_RUNNING;
}
//开启定时器
void softTimer_Stop(unsigned int id)
{
softTimerList[id].state = SOFT_TIMER_STOPPED;
}
//停止定时器
void softTimer_Clr(unsigned int id)
{
if (softTimerList[id].mode == MODE_ONE_SHOT)
{
softTimerList[id].state = SOFT_TIMER_STOPPED;
}
else
{
softTimerList[id].state = SOFT_TIMER_RUNNING;
}
}
//清除定时器。如果定时器是单次触发模式,则定时器关闭;如果是循环模式,则重新开始计时。
unsigned char softTimer_GetState(unsigned int id)
{
return softTimerList[id].state;
}
//获取定时器状态。
void softTimer_Update(void) //更新定时器状态,在硬件定时器中1ms调用一次
{
unsigned char id;
for (id = 0; id <= SOFT_TIMER_MAX; id++)
{
switch (softTimerList[id].state)
{
case SOFT_TIMER_STOPPED:
break;
case SOFT_TIMER_RUNNING:
if (softTimerList[id].count < softTimerList[id].period)
{
softTimerList[id].count++;
}
else
{
softTimerList[id].count = 0;
softTimerList[id].state = SOFT_TIMER_TIMEOUT;
softTimerList[id].callback();
}
break;
case SOFT_TIMER_TIMEOUT:
if (softTimerList[id].mode == MODE_ONE_SHOT)
{
softTimerList[id].state = SOFT_TIMER_STOPPED;
}
else
{
softTimerList[id].count++;
softTimerList[id].state = SOFT_TIMER_RUNNING;
}
break;
default: //state error
break;
}
}
}//更新定时器状态,在中断中调用。
这个软定时器的缺点:不是很准确。如果定时时间长的话还好,误差基本上就抵消了,如果只是计时几个周期的话波形宽度会变,不适合做PWM,只适合秒级别的定时。
顺便原作者提供了一个protus的仿真,反正我是打不开。。。谁能打开谁玩玩吧。已经在“中颖”单片机上移植过了,很好用。
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?注册
x
阿莫论坛20周年了!感谢大家的支持与爱护!!
该献的血还是要献的。你不献他不献。难道让我去献? --- 出自坛友:lovejp1981
|