前后台系统和多任务操作系统,在简单功能上差别不大,唯一不顺手的就是前后台系统没有合适的软件定时器。封装一层软件定时器接口,对后续功能开发事半功倍。
定义结构体数组,其基础成员如下:
static uint32_t hw_interrupt_timer_ticks = 0;
typedef void (*timer_callback)(void);
#define SW_TIMER_MAX 10
typedef struct
{
uint32 delay;
uint32 auto_repeat;
timer_callback callback;
} timer_struct;
timer_struct my_timer[SW_TIMER_MAX] = {0};
void timer_start(uint8 index, uint32 delay, bool loop, timer_callback callback);
void timer_stop(uint8 index);
bool timer_is_running(uint8 index);
对应用提供的启动定时器接口实现可以参考如下:
static void timer_start(uint8 index, uint32 delay, bool loop, timer_callback callback)
{
if((index >= SW_TIMER_MAX) || (delay == 0) || (callback == NULL))
{
return;
}
my_timer[index].delay = hw_timer_ticks + delay;
if(loop)
{
my_timer[index].auto_repeat = delay;
}
else
{
my_timer[index].auto_repeat = 0;
}
my_timer[index].callback = callback;
}
使用硬件定时中断,例如1ms中断一次,每次中断hw_timer_ticks自增一次。主程序中查询hw_timer_ticks 大于delay表示当前定时器任务超时,执行callback。这种在8位单片机系统合适,如果硬件资源有限或者系统时钟太低,可以调整硬件定时中断的精度。这样多个定时器时事件的执行只需要一个硬件定时器。
static void timer_loop(void)
{
uint8 i = 0, n = 0, min = 0;
for(i = 0 ; i < SW_TIMER_MAX ; i++)
{
if(my_timer[i].delay > 0 && my_timer[i].callback != NULL)
{
if(hw_timer_ticks >= my_timer[i].delay)
{
if(my_timer[i]->auto_repeat > 0)
{
my_timer[i].delay = hw_timer_ticks + my_timer[i]->auto_repeat;
}
else
{
my_timer[i].delay = 0;
}
my_timer[i].callback();
}
}
}
}
实现基础框架后,应用层只需要简单的操作就是实现,例如定时每60秒读取一次ADC结果,和延时30秒后关闭LED显示。
static void timer_start(READ_ADC_TIMER_ID, 60*1000, TRUE, read_adc_callback);
static void timer_start(LED_ON_TIMEROUT_TIMER_ID, 30*1000, FALSE, led_on_timeout_callback);
这种方案的缺点是my_timer数组下标index与应用绑定,即使没有全部使用,主程序每次都要查询全部数组成员;11个定时任务即使明确最多只有9个同时在运行,该接口也无法满足需求。
增加申请定时器资源的接口,在10个定时器池中获取没有被使用的,将index下标返回,再传入timer_statrt,同样的定义,可以满足10个定时任务同时运行,提高了定时器的利用率。
因为主程序轮流查询定时器状态,加上前面的回调函数执行的时间,实际执行回调时间与期望的延时时间存在一定误差。在硬件资源充足的情况下,可以将数组改为链表,按delay从小到大排序,新启动的定时器按顺序插入到合适的位置,这样主程序查询速度会加快,在最近的软件定时器,也就是第一个软件定时器超时前可以休眠省电。或者分为多个数组映射不同的优先级和时间精度,这样提高回调函数执行的时间准确度。
工欲善其事,必先利其器,基础件完美才能支撑复杂多变的应用层。
已剪辑自: https://mp.weixin.qq.com/s?__biz=Mzg3OTQ3NDQ2Mg==&mid=2247483751&idx=1&sn=7f20c6527b60ad8b3eef6d913f9eb9db&chksm=cf02a316f8752a00fa901c26c0b187a49659d8f1bcbb55d84b354edc0c9c4a30ed2fb0b9cb51&scene=178&cur_album_id=1856108351068143619#rd
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)