1.定时器的概念
我们的手机上有闹钟,我们可以设定一个时间到点后它会提醒我们做一些特别的事情。
定时器有两种,一种是硬件定时器一种是软件定时器。
1.1硬件定时器
学过单片机都知道,在STM32中有很多定时器,高级定时器,通用定时器,低级定时器,他们不单单可以用来计时,他们还可以输出pwm波,输入捕获等。如果我们需要记很多个时间用硬件定时器根本不过,而且将硬件资源大大浪费,有没有什么方法可以既能定时又能节省单片机定时器资源呢?就使用软件定时器。
1.2软件定时器
软件定时器的实现是基于一个硬件定时器实现的。我们给硬件设定一个周期(Tick),每进入一次中断我们让Count++,我们根据这个Count值就可以知道我们时间走了多少。所以一切操作的核心就是这个Count值。那怎么设置多个定时器呢?一步一步来。
2.软件定时器的配置
我们知道如果我们需要表述一个复杂的事物,我们需要用结构体来表述:
比如定时器有哪些属性呢?状态,模式,到期时间,定时时间,回调函数。
这里讲一下几个内容
1:为啥有个回调函数,这里的回调函数是软件定时器的回调函数不是硬件中的回调函数,硬件定时器的回调函数只用来Count++,软件回调函数需要我们自己来写,回调函数就是指定定时器到达后执行的操作。
2:如何确定时间是否到达?
我们在执行开始定时器的时候有一个delay,到期时间==count+delay,根据到期时间与当前时间关系运算可以得出时间是否到达。
3:如何去防止count溢出?
假设count最大值是65535,当count==65530时我们延时了一个6,到期时间就等于count+delay->65536,溢出了。
别担心,在计算机系统中当一个数超出它的最大范围时,它会从它最小值重新开始。因此我们只要计算(count+delay)%(count最大值),得出来的值就是我们的到期时间。
4:如何去实现周期行的定时器?
我们可以根据模式如果是单次执行,我们直接调用完回调函数后,将该定时器状态设定为暂停。
如果是周期运行状态我们就更新到期时间即可。
6.实现软件定时器就是要实现以下接口函数
3.代码实现
类型定义,相关变量的定义
//定义的宏
#define Timer_num 3
/*定义类型开始*************************************************************************/
typedef void callback(void *argv, uint16_t argc);//软件定时器回调函数
//定时器结构体
typedef struct xtimerSTRUCT
{
uint8_t state; //状态
uin