本文只作为回顾自己在做低功耗设备时要点的备忘。
1.硬件方面:
MCU使用的是STM32L072系列低功耗单片机。裸机功耗在uA级别。
各外设供电采用MOS管进行控制,如下图所示。
2.软件方面:
本文采用的思路是需要进入低功耗模式时,先将MCU复位一次,然后根据保存的低功耗标记,做如下操作:
先将所有外部引脚配置为“模拟输入”模式,只有需要做唤醒用的引脚才配置为中断模式。
然后采用停止模式,如下:
void enterSleep(void)
{
HAL_SuspendTick(); //必须先关掉tick中断
/* Enable Power Control clock */
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
__HAL_FLASH_SLEEP_POWERDOWN_ENABLE();
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
}
关于保存各变量标记,采用如下方式实现:
keil工程的配置:
源码区的设置:
NOINIT_PARA noinitpara __attribute__((at(0x20004FC0)));//复位(非重启)变量值不会清除区域
void noinitpara_init(void)
{
BYTE_WORD crc;
crc.word = CRC16(sizeof(NOINIT_PARA)-2,(u8*)&noinitpara);
if((crc.word != noinitpara.crc)||(noinitpara.sync != 0x5EE55AA5))
{
memset((u8*)&noinitpara,0x00,sizeof(NOINIT_PARA));
noinitpara.sync = 0x5EE55AA5;
noinitpara.crc = crc.word;
}
}
void noinitpara_save(void)
{
BYTE_WORD crc;
crc.word = CRC16(sizeof(NOINIT_PARA)-2,(u8*)&noinitpara);
noinitpara.crc = crc.word;
}
以上的方法适合启动快的小设备,休眠唤醒后没什么业务上的衔接。这种方法在休眠前重启了设备,能有效避免设备内存溢出等疑难杂症。
当然,也可以使用另外一种思路,就是在休眠之前对各外设驱动去初始化(deinit)及模拟输入模式,然后调用enterSleep()函数休眠。