STM32本身就支持低功耗模式,以STM32F1为例,其有三种低功耗模式:睡眠(Sleep)模式、停止(Stop)模式、待机(Standby)模式
1,在Config parameters 中,USE_TICKLESS_IDLE 选择Built in Functionality enabled 即内置的低功耗方案(启用低功耗Tickless模式),第三个为自定义;
2,在FreeRTOSConfig.h 中,可以看到:
#define configUSE_TICKLESS_IDLE 1
3,需要在app_freertos.c中,重定义两个函数:
//=====================================================================方法一
__weak void PreSleepProcessing(uint32_t ulExpectedIdleTime)
{
__HAL_RCC_GPIOF_CLK_SLEEP_DISABLE(); // 注意芯片引脚,目前不确定
ulExpectedIdleTime = 0;
HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON,PWR_SLEEPENTRY_WFI);
/* place for user code */
}
__weak void PostSleepProcessing(uint32_t ulExpectedIdleTime)
{
(void)ulExpectedIdleTime;
/* place for user code */
}
Tickless模式需要满足两个条件,才可进入睡眠模式:
1,空闲任务正在运行:
2,可运行低功耗时间大于参数configEXPECTED_IDLE_TIME_BEFORE_SLEEP(默认为2,且最小不能小于2个时钟节拍),用户需要注意的是进入睡眠的时间有最大值 xMaximumPossibleSuppressedTicks 限制,该变量在设置滴答定时器中断 vPortSetupTimerInterrupt() 函数中被计算,当 MCU 频率为168MHz,FreeRTOS 频率为 1000Hz 时,该值为 99 ,也即单次最长进入睡眠时间的最大值为 99 个节拍。
0XFFFFFF/(168000000/1000) = 99 -> 99ms
//=======================================================================方法二
//进入睡眠模式之前关闭系统滴答定时器,在退出睡眠模式之后开启系统滴答定时器
__weak void PreSleepProcessing(uint32_t ulExpectedIdleTime)
{
/* place for user code */
HAL_SuspendTick();
}
__weak void PostSleepProcessing(uint32_t ulExpectedIdleTime)
{
/* place for user code */
HAL_ResumeTick();
}