前言
泰凌微的定时器可以应用在计时、电平测量、脉冲捕捉等方面,本章主要讲解下硬件定时器与软定时器的配置使用
如有异议,欢迎留言指正
特性
- 硬件定时器支持Timer0~Timer2
- 支持四种模式
- 系统时钟模式(System Clock)
- GPIO触发模式(脉冲数捕捉)
- GPIO脉宽模式(脉冲宽度捕获)
- 计时模式(Tick)
- 定时器Timer2可用于看门狗计时
- 休眠状态下定时器停止计时
寄存器组
- Wd_status:地址0x72,看门狗复位状态寄存器,最低位为1时为看门狗复位状态,写1清除
- TMR_CTRL0:地址0x620,控制寄存器0,配置定时器使能位与模式选择
- TMR_CTRL[1~2]:地址0x621~0x622, 看门狗比较计数配置
- TMR_STATUS:地址0x623,Timer0~2与wdog状态寄存器,写1清除状态
- TMR_CAPT0_[0~3]:地址0x624~0x627, timer0 4字节捕获寄存器
- TMR_CAPT1_[0~3]:地址0x628~0x62b,timer1 4字节捕获寄存器
- TMR_CAPT2_[0~3]:地址0x62c~0x62f,timer2 4字节捕获寄存器
- TMR_TICK0_[0-3]:地址0x630~0x633,timer0 4字节tick寄存器
- TMR_TICK1_[0-3]:地址0x634~0x637,timer1 4字节tick寄存器
- TMR_TICK2_[0-3]:地址0x638~0x63b,timer2 4字节tick寄存器
硬件定时器
代码实例
参考SDK中app_timer.c
中的例程代码讲解
- 定时器初始化,封装好的API接口可以查看驱动目录下的
timer.c
void app_timer_test_init(void)
{
//timer0 配置
reg_irq_mask |= FLD_IRQ_TMR0_EN;//使能timer0中断
reg_tmr0_tick = 0; //tick清0
reg_tmr0_capt = 100 * CLOCK_SYS_CLOCK_1MS;//100ms定时
reg_tmr_sta = FLD_TMR_STA_TMR0; //清中断状态
reg_tmr_ctrl |= FLD_TMR0_EN; //使能定时器0
//timer1 配置
reg_irq_mask |= FLD_IRQ_TMR1_EN;//使能timer1中断
reg_tmr1_tick = 0; //tick清0
reg_tmr1_capt = 500 * CLOCK_SYS_CLOCK_1MS;//500ms定时
reg_tmr_sta = FLD_TMR_STA_TMR1; //清中断状态
reg_tmr_ctrl |= FLD_TMR1_EN; //使能定时器1
//timer2 配置
reg_irq_mask |= FLD_IRQ_TMR2_EN;//使能timer2中断
reg_tmr2_tick = 0; //tick清0
reg_tmr2_capt = 1000 * CLOCK_SYS_CLOCK_1MS;//1000ms定时
reg_tmr_sta = FLD_TMR_STA_TMR2; //清状态
reg_tmr_ctrl |= FLD_TMR2_EN; //使能定时器2
irq_enable(); //使能中断
}
- 定时中断处理函数,需要放到中断入口irq_handler中处理
_attribute_ram_code_ void app_timer_test_irq_proc(void)
{
if(reg_tmr_sta & FLD_TMR_STA_TMR0)
{
reg_tmr_sta = FLD_TMR_STA_TMR0; //清中断状态
printf("timer0 irq");
}
if(reg_tmr_sta & FLD_TMR_STA_TMR1)
{
reg_tmr_sta = FLD_TMR_STA_TMR1; //清中断状态
printf("timer1 irq");
}
if(reg_tmr_sta & FLD_TMR_STA_TMR2)
{
reg_tmr_sta = FLD_TMR_STA_TMR2; //清中断状态
printf("timer2 irq");
}
}
软定时器
软件定时器是BLE SDK提供的基于system tick非精确定时,通过轮询超时方式实现,可应用在定时时间大于5ms的场景
- 软件定时器在
blt_soft_timer.c
文件中实现,需要使能宏定义#define BLT_SOFTWARE_TIMER_ENABLE 1
API接口
- soft timer初始化API,注册提前唤醒的回调函数
void blt_soft_timer_init(void);
- 添加定时任务,形参为具体的定时回调函数与定时时间;最大支持定时器可修改宏
MAX_TIMER_NUM
int blt_soft_timer_add(blt_timer_callback_t func, u32 interval_us)
- 删除指定的定时任务,形参为注册时的任务函数
int blt_soft_timer_delete(blt_timer_callback_t func);
- 查询处理接口,需要循环周期调用
void blt_soft_timer_process(int type);
代码实例
参考SDK中feature_soft_timer.c
中的例程代码讲解
//软定时器0回调
int soft_timer_test0(void)
{
printf("soft_timer_test0");
}
//软定时器1回调
int soft_timer_test1(void)
{
printf("soft_timer_test1");
}
//软定时器2回调
int soft_timer_test2(void)
{
printf("soft_timer_test2");
}
//软定时器3回调
int soft_timer_test3(void)
{
printf("soft_timer_test3");
}
//初始化软定时器
void feature_soft_timer_test_init_normal(void)
{
//*********忽略代码段
//common/blt_soft_timer.h #define BLT_SOFTWARE_TIMER_ENABLE 1
blt_soft_timer_init();
blt_soft_timer_add(&soft_timer_test0, 100 * 1000);//100ms
blt_soft_timer_add(&soft_timer_test1, 500 * 1000); //500ms
blt_soft_timer_add(&soft_timer_test2, 1000 * 1000);//1000ms
blt_soft_timer_add(&soft_timer_test3, 2000 * 1000);//2000ms
}
//加入到轮询接口中
_attribute_ram_code_ void main_loop (void)
{
blt_soft_timer_process(MAINLOOP_ENTRY);//增加周期处理
blt_sdk_main_loop();
}
总结
- 在资源充足并且要求定时精确的情况下可以使用硬件定时器,如果开启了看门狗那么定时器Timer2就不能使用了;
- 软件定时器弥补了硬件定时器资源不足的非精确延迟的情况,并且支持休眠后的定时唤醒,具体根据实际的应用来评估使用