注册低功耗设备
以按键扫描为例,正常情况下,如果按键没有按下,那么系统休眠可以进入休眠状态,对按键功能是没有影响的。如果按键按下时,那么系统需要定时唤醒并轮询按键任务。
所以在一个低功耗系统下,为了不影响按键实时性需要处理好两个事情:
系统休眠状态下,如果有按键按下,那系统系统应立即唤醒,以便处理接下来的扫描工作。
如果按键按下时,系统可以进入休眠,但需要定时唤醒起来轮询按键任务。
对于第一种情况,将按键配置为边沿中断唤醒即可,以STM32F4为例(参考key_task.c),它支持外部中断唤醒功能。
/*
* @brief 按键 io初始化
* PC0 -> key;
* @return none
*/
static void key_io_init(void)
{
/* Enable GPIOA clock */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
gpio_conf(GPIOC, GPIO_Mode_IN, GPIO_PuPd_UP, GPIO_Pin_0);
//低功耗模式下,为了能够检测到按键,配置为中断唤醒
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC, EXTI_PinSource0);
exti_conf(EXTI_Line0, EXTI_Trigger_Falling, ENABLE);
nvic_conf(EXTI0_IRQn, 0x0F, 0x0F);
key_create(&key, readkey, key_event); /*创建按键*/
}
对于第二种情况,可以通过pm_dev_register来处理,当系统请求休眠时,如果此时按键按下,则返回下次唤醒时间即可,如下面的例子所示。
//参考key_task.c
#include "pm.h"
/*
* @brief 休眠通知
*/
static unsigned int key_sleep_notify(void)
{
return key_busy(&key) || readkey() ? 20 : 0; /* 非空闲时20ms要唤醒1次*/
} pm_dev_register("key", NULL, key_sleep_notify, NULL);
|