51单片机软定时器程序分享
之前自己的一个项目请教过坛友,如何对多个任务定时: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.mode = mode;
softTimerList.period = interval;
softTimerList.count = 0;
softTimerList.callback = cb;
softTimerList.state = SOFT_TIMER_STOPPED;
}
创建定时器,后面的变量分别是定时器编号、定时器模式(单次或循环)、定时器触发时间、定时器事件(一个指针,指向函数)
void softTimer_Start(unsigned int id)
{
softTimerList.state = SOFT_TIMER_RUNNING;
}
//开启定时器
void softTimer_Stop(unsigned int id)
{
softTimerList.state = SOFT_TIMER_STOPPED;
}
//停止定时器
void softTimer_Clr(unsigned int id)
{
if (softTimerList.mode == MODE_ONE_SHOT)
{
softTimerList.state = SOFT_TIMER_STOPPED;
}
else
{
softTimerList.state = SOFT_TIMER_RUNNING;
}
}
//清除定时器。如果定时器是单次触发模式,则定时器关闭;如果是循环模式,则重新开始计时。
unsigned char softTimer_GetState(unsigned int id)
{
return softTimerList.state;
}
//获取定时器状态。
void softTimer_Update(void) //更新定时器状态,在硬件定时器中1ms调用一次
{
unsigned char id;
for (id = 0; id <= SOFT_TIMER_MAX; id++)
{
switch (softTimerList.state)
{
case SOFT_TIMER_STOPPED:
break;
case SOFT_TIMER_RUNNING:
if (softTimerList.count < softTimerList.period)
{
softTimerList.count++;
}
else
{
softTimerList.count = 0;
softTimerList.state = SOFT_TIMER_TIMEOUT;
softTimerList.callback();
}
break;
case SOFT_TIMER_TIMEOUT:
if (softTimerList.mode == MODE_ONE_SHOT)
{
softTimerList.state = SOFT_TIMER_STOPPED;
}
else
{
softTimerList.count++;
softTimerList.state = SOFT_TIMER_RUNNING;
}
break;
default: //state error
break;
}
}
}//更新定时器状态,在中断中调用。
这个软定时器的缺点:不是很准确。如果定时时间长的话还好,误差基本上就抵消了,如果只是计时几个周期的话波形宽度会变,不适合做PWM,只适合秒级别的定时。
顺便原作者提供了一个protus的仿真,反正我是打不开。。。谁能打开谁玩玩吧。已经在“中颖”单片机上移植过了,很好用。
谢谢。 帮顶。。。。 8.9SP2仿真可以运行,{:victory:}回头看看怎样使用。 打赏!
庆祝论坛“打赏”功能实施, 现在开始发技术主题,可以获得打赏
https://www.amobbs.com/thread-5735948-1-1.html 有问题,楼主 call_back()最好不能在中断里
页:
[1]