STM32低功耗模式

一.什么是低功耗

低功耗是在嵌入式微处理器系列的一个重要优势,特别适用于需要长时间运行且功耗敏感的应用场景。在很多应用场合中对电子设备的功耗非常苛刻,如某些传感器信息采集设备,仅仅靠小型的电池提供能源,要求工作长达数年之久,所以很有必要从控制功耗入手。

二.STM32电源系统结构

VDDA和VSSA必须分别连到VDD和VSS

三.低功耗模式介绍

1.stm32具有运行,睡眠,停止,等待四种工作模式,上电后默认是在运行模式。当内核不需要继续运行,就可以选择进入后面的三种低功耗模式降低功耗,这三种模式中,电源消耗不同、唤醒时间不同、唤醒源不同,用户需要根据应用需求,选择最佳的低功耗模式。三种低功耗的模式说明如下图

低功耗模式一览

2.睡眠模式(sleep mode)

在睡眠模式下,cpu停止工作,但所有的外设仍然运行,时钟继续运转。用于暂时关闭CPU但外设需要继续工作的场景。

模式特点:

  • 对系统影响小,但节能效果最差。
  • 在睡眠模式下,所有的I/O口都保持在它们运行模式时的状态

进入条件:

  •    当系统控制寄存器中的SLEEPDEEF位被清除(通常为0),并且SLEEPONEXIT位根据需求设置时。
  • 执行WFI 或WFE指令来进入

唤醒条件:

  • 任意一个中断都可以将系统从睡眠模式唤醒。
  • 如果执行WFE指令进入sleep模式,则一旦发生唤醒事件时,MCU将唤醒。

2.1停机模式(stop mode)

在停机模式下,CPU和核心外围设备的时钟会停止,但部分唤醒源(如外部中断和某些定时器)扔在运行。适用于需要长时间等待外部事件唤醒的应用,如等待用户输入或外部信号。STOP模式实现了非常低的功耗,同时保留了SPAM和寄存器的内容。

模式特点:

  • 节能效果好,程序不会复位。
  • 在停机模式下,所有的I/O口都保持它们在运行时的状态。
  • 退出停止模式时,HSI RC振荡器被选为系统时钟。

进入条件:

  • 需要将SLEEPDEEP位设置为1以进入深度睡眠模式,然后通过设置电源控制/状态寄存器(PWR_CSR) 中的PDDS位为0来选择进入Stop模式。
  • 根据需求设置LPDS位(LPDS = 0:表示在深睡眠模式下,电压调节器保持开启状态;LPDS = 1:表示 在深睡眠模式下,电压调节器进入低功耗模式。)。
  • 执行WFI(Wait For Interrupt)或WFE(Wait For Event)指令来进入。
  • 在进入Stop模式之前,通常需要关闭不必要的外设时钟,并保存需要保留的状态信息。

唤醒条件:

  • STOP模式可以通过外部中断(如按键中断,串口接受中断)等唤醒。
  • rtc闹钟,usb唤醒,以太网唤醒等也可以作为唤醒源,但这些通常需要外部中断来触发。

2.2待机模式(standby mode)

在该模式下,CPU,外围设备和时钟都被关闭,只保留唤醒逻辑和备份寄存器,这适用于不需要保留RAM内容可以从复位状态恢复的设备,常见于需要极低且稀疏唤醒的应用,待机模式时STM32中功耗最低的模式之一。

模式特点:

  • 节能效果最好,但程序会独卫,只有少数条件唤醒。
  • 在待机模式下,大部分IO引脚处于高阻态,只有复位引脚、TAMPER引脚(如果配置为防侵入或校准输出)和WKUP引脚可用作唤醒源。

进入条件:

  • 待机模式进入前,需要清除电源控制/状态寄存器中的WUF位,以确保没有未处理的唤醒标志。
  • 将SLEEPDEEP位设置为1以进入深度睡眠模式,并设置PDDS位为1来选择进入待机模式。 执行WFI或WFE指令进入待机模式。

唤醒条件:

  • 可以通过WKUP引脚的上升沿唤醒。
  • RTC闹钟也可以作为唤醒源
  • 独立看门狗(IWDG)复位和NRST引脚上的外部复位也可以唤醒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);
    }
}

实验现象:

现象

开头的概念大部分都参考了许多大佬的,只是为了辅助学习而用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

走下去-别回头

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值