STM32低功耗模式
一.什么是低功耗
低功耗是在嵌入式微处理器系列的一个重要优势,特别适用于需要长时间运行且功耗敏感的应用场景。在很多应用场合中对电子设备的功耗非常苛刻,如某些传感器信息采集设备,仅仅靠小型的电池提供能源,要求工作长达数年之久,所以很有必要从控制功耗入手。
二.STM32电源系统结构
VDDA和VSSA必须分别连到VDD和VSS
三.低功耗模式介绍
1.stm32具有运行,睡眠,停止,等待四种工作模式,上电后默认是在运行模式。当内核不需要继续运行,就可以选择进入后面的三种低功耗模式降低功耗,这三种模式中,电源消耗不同、唤醒时间不同、唤醒源不同,用户需要根据应用需求,选择最佳的低功耗模式。三种低功耗的模式说明如下图
低功耗模式一览
2.睡眠模式(sleep mode)
在睡眠模式下,cpu停止工作,但所有的外设仍然运行,时钟继续运转。用于暂时关闭CPU但外设需要继续工作的场景。
模式特点:
进入条件:
唤醒条件:
2.1停机模式(stop mode)
在停机模式下,CPU和核心外围设备的时钟会停止,但部分唤醒源(如外部中断和某些定时器)扔在运行。适用于需要长时间等待外部事件唤醒的应用,如等待用户输入或外部信号。STOP模式实现了非常低的功耗,同时保留了SPAM和寄存器的内容。
模式特点:
进入条件:
唤醒条件:
2.2待机模式(standby mode)
在该模式下,CPU,外围设备和时钟都被关闭,只保留唤醒逻辑和备份寄存器,这适用于不需要保留RAM内容可以从复位状态恢复的设备,常见于需要极低且稀疏唤醒的应用,待机模式时STM32中功耗最低的模式之一。
模式特点:
进入条件:
唤醒条件:
四.低功耗小实验
实验目的:
1.按下按键2,进入低功耗模式(睡眠,停机,待机)
2.按下按键1,退出低功耗模式
3.正常模式下 led1闪烁,进入低功耗模式led2常亮,退出则熄灭、
实验步骤:
实验采用的时按键中断唤醒,配置为上升沿触发。按键1刚好是待机模式需要WKUP唤醒引脚
1.初始化按键1,并开启中断
void lpwr_init(void)
{
GPIO_InitTypeDef gpio_initstruct;
__HAL_RCC_GPIOA_CLK_ENABLE();
gpio_initstruct.Pin = GPIO_PIN_0;
gpio_initstruct.Mode = GPIO_MODE_IT_RISING;
gpio_initstruct.Pull = GPIO_PULLUP; // 上拉
gpio_initstruct.Speed = GPIO_SPEED_FREQ_HIGH; // 高速
HAL_GPIO_Init(GPIOA, &gpio_initstruct);
HAL_NVIC_SetPriority(EXTI0_IRQn,2,2);
HAL_NVIC_EnableIRQ(EXTI0_IRQn);
}
void EXTI0_IRQHandler(void)
{
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
}
2.初始化按键2
void key_init(void)
{
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitTypeDef gpio_iniystruct;
gpio_iniystruct.Pin = GPIO_PIN_1;
gpio_iniystruct.Mode = GPIO_MODE_INPUT;
gpio_iniystruct.Pull = GPIO_PULLUP;
gpio_iniystruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA,&gpio_iniystruct);
}
//按键扫描
uint8_t key_scan(void)
{
if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_1) == GPIO_PIN_RESET)
{
delay_ms(10);
if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_1) == GPIO_PIN_RESET)
{
while(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_1) == GPIO_PIN_SET);
return 2;
}
}
return 0;
}
3.编写睡眠模式代码(这里只需要调用一个函数)定时器不暂停好像也可以。
void lpwr_enter_sleep(void)
{
HAL_SuspendTick();//暂停定时器
HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON,PWR_SLEEPENTRY_WFI);
}
4.编写停机模式代码,由于退出停机模式后,系统会自动使用 HSI为系统时钟,所以要重新设置时钟。
void lpwr_enter_stop(void)
{
HAL_SuspendTick();//暂停定时器
led2_on();
HAL_PWR_EnterSTOPMode(PWR_MAINREGULATOR_ON,PWR_STOPENTRY_WFI);
led2_off();
//唤醒重新配置时钟
stm32_clock_init(RCC_PLL_MUL9);
}
5.编写待机模式代码,
void lpwr_enter_standby(void)
{
//使能电源时钟(关闭电压调节器)
__HAL_RCC_PWR_CLK_ENABLE();
//使能wake up 的引脚唤醒功能
HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN1);
//清除唤醒标记,不然一直保持唤醒状态
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
//进入待机模式
HAL_PWR_EnterSTANDBYMode();
led2_on();
}
6.main函数调用这里只实验一个模式。
int main(void)
{
HAL_Init(); /* 初始化HAL库 */
stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
led_init(); /* 初始化LED灯 */
lpwr_init();
key_init();
uint8_t i = 0;
while(1)
{
if (key_scan() == 2) //检测按键2
{
//lpwr_enter_sleep(); //进入睡眠模式
lpwr_enter_stop(); //进入停机模式
//lpwr_enter_standby(); //进入待机模式
}
if((i % 20) == 0) led1_toggle();
i++;
delay_ms(10);
}
}
实验现象:
现象
开头的概念大部分都参考了许多大佬的,只是为了辅助学习而用。
作者:走下去-别回头