目录
int hal_timer_init(ap_tm_hdl_t callback);
int hal_timer_set(User_Timer_e timeId, uint32_t us);
int hal_timer_mask_int(User_Timer_e timeId, bool en);
int hal_timer_stop(User_Timer_e timeId);
void __attribute__((used)) hal_TIMER5_IRQHandler(void);
void __attribute__((used)) hal_TIMER6_IRQHandler(void);
PHY6222-simpleBLEPeripheral的基本介绍【蓝牙篇】
前言
定时器也是常见的基础外设,一般的开发版中都有,同时定时器也被广泛运用在开发当中。所以,掌握定时器基本的开发思路,便可触类旁通了。
1、定时器的基本开发思路
首先需要确认定时器用来做什么的。然后根据定时器的作用配置定时器的相关参数。最后在中断回调函数中,进行功能代码的编写就好啦。大致思路如下图所示,
2、定时器的基本介绍
① 相关函数的介绍
Ⅰ、函数声明:
-
int hal_timer_init(ap_tm_hdl_t callback);
- 初始化定时器,并设置定时器中断处理函数的回调 (
ap_tm_hdl_t callback
是一个函数指针类型,用于指定中断处理函数)。
- 初始化定时器,并设置定时器中断处理函数的回调 (
-
int hal_timer_deinit(void);
- 反初始化定时器,释放定时器占用的资源。
-
int hal_timer_set(User_Timer_e timeId, uint32_t us);
- 设置定时器的定时时间。
timeId
是定时器的标识符,us
是定时时间,单位为微秒。
- 设置定时器的定时时间。
-
int hal_timer_mask_int(User_Timer_e timeId, bool en);
- 屏蔽或使能定时器中断。
timeId
是定时器的标识符,en
为true
表示使能中断,为false
表示屏蔽中断。
- 屏蔽或使能定时器中断。
-
int hal_timer_stop(User_Timer_e timeId);
- 停止定时器的运行。
timeId
是要停止的定时器的标识符。
- 停止定时器的运行。
Ⅱ、中断处理函数声明:
-
void __attribute__((used)) hal_TIMER5_IRQHandler(void);
- 处理定时器5的中断事件。
__attribute__((used))
是一个编译器指令,用于确保即使在源代码中未使用该函数,编译器也不会优化掉这个函数。
- 处理定时器5的中断事件。
-
void __attribute__((used)) hal_TIMER6_IRQHandler(void);
- 处理定时器6的中断事件。同样地,
__attribute__((used))
指令确保编译器不会优化掉这个函数。
- 处理定时器6的中断事件。同样地,
②定时器的基本实现
Ⅰ、定时器的初始化
注意:所传参数(ap_tm_hdl_t callback),为回调函数。
int hal_timer_init(ap_tm_hdl_t callback)
{
s_ap_callback = callback;
hal_timer_stop(AP_TIMER_ID_5);
hal_timer_stop(AP_TIMER_ID_6);
return hal_pwrmgr_register(MOD_TIMER, hal_timer_sleep_handler, hal_timer_wakeup_handler);
}
//在main()函数中的应用
hal_timer_init(timer_callback);//timer_callback--回调函数
Ⅱ、定时器的相关配置
//定时器的设置函数
int hal_timer_set(User_Timer_e timeId, uint32_t us)
{
uint32_t time = us;
switch(timeId)
{
case AP_TIMER_ID_5:
JUMP_FUNCTION(TIM5_IRQ_HANDLER) = (uint32_t)&hal_TIMER5_IRQHandler;
NVIC_EnableIRQ((IRQn_Type)TIM5_IRQn);
NVIC_SetPriority((IRQn_Type)TIM5_IRQn, IRQ_PRIO_HAL);
hal_timer_set_loadtimer(AP_TIM5, time);
hal_clk_gate_enable(MOD_TIMER5);
break;
case AP_TIMER_ID_6:
JUMP_FUNCTION(TIM6_IRQ_HANDLER) = (uint32_t)&hal_TIMER6_IRQHandler;
NVIC_EnableIRQ((IRQn_Type)TIM6_IRQn);
NVIC_SetPriority((IRQn_Type)TIM6_IRQn, IRQ_PRIO_HAL);
hal_timer_set_loadtimer(AP_TIM6, time);
hal_clk_gate_enable(MOD_TIMER6);
break;
default:
return PPlus_ERR_INVALID_PARAM;
}
return PPlus_SUCCESS;
}
//定时器的使用
hal_timer_set(AP_TIMER_ID_5, 10 * 1000);//0.01s=10ms
Ⅲ、定时器的回调函数
// 在这里实现你的定时器事件处理逻辑
// evt 参数可能用来传递事件相关的信息
// 可以根据实际需求编写相应的处理代码
// 示例:打印事件类型
void timer_callback(uint8_t evt) {
switch(evt)
{
case HAL_EVT_TIMER_5:
// LOG("t5\n");
button_callback();
break;
case HAL_EVT_TIMER_6:
LOG("t6\n");
LOG("g_button[0].button_last:%s\n",buttonStateToString(g_button[0].button_last));
LOG("g_button[1].button_last:%s\n",buttonStateToString(g_button[1].button_last));
break;
case HAL_EVT_WAKEUP:
LOG("wakeup\n");
LOG("timer will disable when sleep,so if you want it work please init it when wakeup");
break;
case HAL_EVT_SLEEP:
LOG("sleep\n");
break;
default:
LOG("err ");
break;
}
}
3、总结
这部分函数涉及到函数指针、指针函数的应用,还需要巩固这方面的知识。整体来说,定时器这部分难度不大,但是也加深了对定时器开发的认识。
如有错误,恳请批评指正!