低功耗
2025/9/8大约 2 分钟
低功耗睡眠模式

内核停止通常指的是 CPU 停止执行指令,也就是处理器进入低功耗或挂起状态,不再主动运行程序代码。

// 挂起(暂停)系统时钟中断
HAL_SuspendTick();
/* 进入睡眠模式, 任意中断唤醒 */
HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
/* 恢复系统时钟中断 */
HAL_ResumeTick();
低功耗停止模式


int main(void)
{
···
while(1)
{
···
// 暂停滴答定时器,防止通过滴答定时器中断唤醒
HAL_SuspendTick();
/* 进入停止模式,设置电压调节器为低功耗模式,等待中断唤醒 */
HAL_PWR_EnterSTOPMode(PWR_MAINREGULATOR_ON,PWR_STOPENTRY_WFI);
//被唤醒后,重新配置系统时钟
SYSCLKConfig_STOP();
// 被唤醒后,恢复滴答定时器
HAL_ResumeTick();
···
}
}
static void SYSCLKConfig_STOP(void)
{
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
uint32_t pFLatency = 0;
/* 启用电源控制时钟 */
__HAL_RCC_PWR_CLK_ENABLE();
/* 根据内部 RCC 寄存器获取振荡器配置 */
HAL_RCC_GetOscConfig(&RCC_OscInitStruct);
/* 从停止模式唤醒后重新配置系统时钟: 启用 HSE 和 PLL */
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
while (1)
{;
}
}
/* 根据内部 RCC 寄存器获取时钟配置 */
HAL_RCC_GetClockConfig(&RCC_ClkInitStruct, &pFLatency);
/* 选择 PLL 作为系统时钟源, 并配置 HCLK、PCLK1 和 PCLK2 时钟分频系数 */
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, pFLatency) != HAL_OK)
{
while (1)
{;
}
}
}Question:
HAL_PWR_EnterSTOPMode(PWR_MAINREGULATOR_ON, PWR_STOPENTRY_WFI);使用该函数后所有时钟(HCLK,PCLK1,PCLK2)都停止,那为什么还要手动停止滴答定时器?
答:虽然进入 STOP 模式后,HCLK 关闭,SysTick 也无法运行,但 在进入 STOP 之前,SysTick 可能会触发一次中断,影响低功耗过程,所以 手动调用 HAL_SuspendTick(); 是为了避免 STOP 过程中被 SysTick 误中断。
低功耗待机模式



