STM32速成笔记(十三)—低功耗模式

简介: 本文介绍了三种STM32低功耗模式的进入和退出方法,针对待机唤醒给出了程序设计。


🎀 文章作者:二土电子
🐸 期待大家一起学习交流!


一、STM32低功耗模式介绍

STM32提供了一些低功耗模式。默认情况下,系统复位或上电复位后,微控制器进入运行模式。在运行模式下,HCLK 为CPU提供时钟,并执行程序代码。当 CPU 不需要继续运行(例如等待外部事件) 时,可以利用多种低功耗模式来节省功耗。

STM32 提供了 3 种低功耗模式,以达到不同层次的降低功耗的目的

  • 睡眠模式(内核停止工作,外设仍在运行)
  • 停止模式(所有时钟都停止)
  • 待机模式( 1.8 V 内核电源关闭)

这三种模式所需的功耗是逐级递减,也就是说待机模式功耗是最低的。

在睡眠模式中,仅关闭了内核时钟,内核停止运行,但其片上外设,CM3 核心的外设全都照常运行。在停止模式中,进一步关闭了其它所有的时钟,于是所有的外设都停止了工作,但由于其 1.8V 区域的部分申源没有关闭,还保留了内核的寄存器、内存的信息,所以从停止模式唤醒,并重新开启时钟后,还可以从上次停止处继续执行代码。在待机模式中,它除了关闭所有的时钟,还把 1.8V 区域的电源也完全关闭了,也就是说,从待机模式唤醒后,由于没有之前代码的运行记录,只能对芯片复位,重新检测BOOT条件,从头开始执行程序

另外,在运行模式下也可以通过降低系统时钟,关闭APB和AHB总线上未被使用的外设时钟来降低功耗。

8c8d65be8281f6f4b73094972c0bd423_850fd5a7bf9749aa89fe37f8542d542d.png

二、睡眠模式

2.1 进入睡眠模式

通过执行WFI或WFE指令进入睡眠状态。根据Cortex-M3系统控制寄存器中的SLEEPONEXIT位的值,有两种选项可用于选择睡眠模式进入机制

  • SLEEP-NOW
    如果SLEEPONEXIT位被清除,当WRI或WFE被执行时,微控制器立即进入睡眠模式。
  • SLEEP-ON-EXIT
    如果SLEEPONEXIT位被置位,系统从最低优先级的中断处理程序中退出时,微控制器就立即进入睡眠模式。

在睡眠模式下,所有的I/O引脚都保持它们在运行模式时的状态。

2.2 退出睡眠模式

如果执行WFI指令进入睡眠模式,任意一个被嵌套向量中断控制器(NVIC)响应的外设中断都能将系统从睡眠模式唤醒。也就是任意一个外部中断都可以唤醒。

如果执行WVFE指令进入睡眠模式,则一旦发生唤醒事件时,微处理器都将从睡眠模式退出。唤醒事件可以通过下述方式产生

  • 在外设控制寄存器中使能一个中断,而不是在NVIC(嵌套向量中断控制器)中使能,并且在Cortex-M3系统控制寄存器中使能SEVONPEND位。当MCU从WFE中唤醒后,外设的中断挂起位和外设的NVIC中断通道挂起位(在NVIC中断清除挂起寄存器中)必须被清除。
  • 配置一个外部或内部的EXIT线为事件模式。当MCU从WFE中唤醒后,因为与事件线对应的挂起位未被设置,不必清除外设的中断挂起位或外设的NVIC中断通道挂起位。

该模式唤醒所需的时间最短,因为没有时间损失在中断的进入或退出上。

3b016c4ed1f586fb10eeeafbaa2447b9_f79194ee97754bfe89290803bbeb3916.png

3531123022bd1896da3c9c90f016b383_98d409e36e124bc0a8bc5014c9d6aa23.png

三、停止模式

停止模式是在Cortex-M3的深睡眠模式基础上结合了外设的时钟控制机制,在停止模式下电压调节器可运行在正常或低功耗模式。此时在1.8V供电区域的的所有时钟都被停止,PLL、HSI和HSE RC振荡器的功能被禁止,SRAM和寄存器内容被保留下来。

在停止模式下,所有的I/O引脚都保持它们在运行模式时的状态。

3.1 进入停止模式

在停止模式下,通过设置电源控制寄存器(PWR CR)的LPDS位使内部调节器进入低功耗模式能够降低更多的功耗。

如果正在进行闪存编程,直到对内存访问完成,系统才进入停止模式。如果正在进行对APB的访问,直到对APB访问完成,系统才进入停止模式。在停止模式下,如果在进入该模式前ADC和DAC没有被关闭,那么这些外设仍然消耗电流。通过设置寄存器ADC CR2的ADON位和寄存器DAC CR的ENx位为0可关闭这2个外设。

3.2 退出停止模式

当一个中断或唤醒事件导致退出停止模式时,HSI RC振荡器被选为系统时钟。当电压调节器处于低功耗模式下,当系统从停止模式退出时,将会有一段额外的启动延时。如果在停止模式期间保持内部调节器开启,则退出启动时间会缩短,但相应的功耗会增加。

3cde30b0186b9abf1b6cf8ed87aeef39_d1e1aae5a6e64942b141aeacaccc6b7c.png

四、待机模式

待机模式可实现系统的最低功耗。该模式是在Corex-M3深睡眠模式时关闭电压调节器。整个1.8V供电区域被断电。PLL、HSI和HSE振荡器也被断电。SRAM和寄存器内容丢失。只有备份的寄存器和待机电路维持供电。

待机模式的进出方法如下

fa376ff87c73d8fa589a74b1c3150f6c_7a238c28945f4114b116f66d99e23864.png

五、程序设计

这里介绍一下进入待机模式并唤醒的程序设计。配置进入待机模式有以下步骤

  • 使能PWR外设时钟
  • 使能唤醒管脚
  • 进入待机模式

库函数中提供了进入待机模式的函数

/**
 * @brief  Enters STANDBY mode.
 * @param  None
 * @retval None
  */
void PWR_EnterSTANDBYMode(void)
{
   
   
  /* Clear Wake-up flag */
  PWR->CR |= PWR_CR_CWUF;
  /* Select STANDBY mode */
  PWR->CR |= PWR_CR_PDDS;
  /* Set SLEEPDEEP bit of Cortex System Control Register */
  SCB->SCR |= SCB_SCR_SLEEPDEEP;
/* This option is used to ensure that store operations are completed */
#if defined ( __CC_ARM   )
  __force_stores();
#endif
  /* Request Wait For Interrupt */
  __WFI();
}

使能唤醒管脚的函数

/**
  * @brief  Enables or disables the WakeUp Pin functionality.
  * @param  NewState: new state of the WakeUp Pin functionality.
  *   This parameter can be: ENABLE or DISABLE.
  * @retval None
  */
void PWR_WakeUpPinCmd(FunctionalState NewState)
{
   
   
  /* Check the parameters */
  assert_param(IS_FUNCTIONAL_STATE(NewState));
  *(__IO uint32_t *) CSR_EWUP_BB = (uint32_t)NewState;
}

测试代码如下

int main(void)
{
   
   
    Med_Mcu_Iint();   // 系统初始化

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);   // 使能PWR外设时钟
    PWR_WakeUpPinCmd(ENABLE);   // 使能唤醒管脚    使能或者失能唤醒管脚功能

    while(1)
  {
   
   
        printf ("Time: 5 \r\n");
        delay_ms(1000);

        printf ("Time: 4 \r\n");
        delay_ms(1000);

        printf ("Time: 3 \r\n");
        delay_ms(1000);

        printf ("Time: 2 \r\n");
        delay_ms(1000);

        printf ("Time: 1 \r\n");
        delay_ms(1000);

        printf ("进入待机模式\r\n");
        PWR_EnterSTANDBYMode();   // 进入待机模式
    }
}

测试结果如下

88d233231bf1b7c37282cda52dd68298_da1e0ccf83e84739a99d46648c57e4c7.png

串口输出完“进入待机模式”后,串口不再输出。当按下WK UP时,重新开始倒计时,进入待机模式。

值得注意的是,进入待机模式被唤醒后,程序是重新开始运行的。对于一些只需要第一次开机才显示的页面或者一些第一次开机校准参数的程序,可以通过第一次开机向Flash固定地址写入数据,下次复位读取对应地址的数据,来判断是否是第一次开机的方法,避免它们在待机唤醒后再次被执行。

相关文章
|
芯片
STM32速成笔记(二)—GPIO
本文介绍了STM32的GPIO的配置和使用方法,并且给出了应用实例。此外,针对使用时可能遇到的一些问题给出了解决办法。
362 0
STM32速成笔记(二)—GPIO
STM32速成笔记(三)—按键检测
本文介绍了如何利用STM32进行按键检测,先介绍了原理,后面给出了配置步骤和应用例程。此外,本文还叙述了如何利用一个按键单独控制一个LED亮灭,以及如何检测按键长短按。
599 0
STM32速成笔记(三)—按键检测
|
存储 物联网 芯片
STM32速成笔记(十四)—串口IAP
本文介绍了什么是IAP,IAP有什么作用,如何实现IAP。最后,给出了IAP的实现程序。
302 0
STM32速成笔记(十四)—串口IAP
|
存储 芯片 内存技术
STM32速成笔记(十二)—Flash闪存
本文简单介绍了什么是Flash。针对STM32F1的Flash做了详细介绍,介绍了操作Flash的步骤,并且给出了程序设计。最后,介绍了一些注意事项。
123 0
STM32速成笔记(十二)—Flash闪存
|
存储 芯片
STM32速成笔记(十一)—EEPROM(AT24C02)
本文详细介绍了什么是AT24C02,介绍了它的引脚,读/写时序,给出了应用实例和详细的程序设计。最后,简单介绍了AT24C02的应用场景。
422 0
STM32速成笔记(十一)—EEPROM(AT24C02)
STM32速成笔记(十)—IWDG
本文详细介绍了什么是IWDG,STM32的IWDG特性,框图和配置步骤。此外,给出了STM32的IWDG配置程序。通过一个简单的应用实例,展示了IWDG的配置和使用方法。
124 0
STM32速成笔记(十)—IWDG
|
API
STM32速成笔记(九)—RTC
本文详细介绍了RTC模块,介绍了STM32的RTC的特性,框图,配置步骤,并给出了详细的程序设计。最后,针对实际使用时可能遇到的问题给出了解决方法以及程序。
97 0
STM32速成笔记(九)—RTC
|
存储 Perl
STM32速成笔记(八)—DMA
本文介绍了DMA的概念,用途。对于STM32F103ZET6的DMA做出了详细地介绍,给出了DMA配置步骤。最后,以配置DMA搬运ADC转换结果为例,给出了DMA的配置和使用方法。
227 0
STM32速成笔记(八)—DMA
STM32速成笔记(六)—定时器
本文介绍了定时器的概念,作用。针对STM32F1的通用定时器做了详细介绍。此外,介绍了PWM的概念,用途以及STM32F1的PWM,给出了PWM频率的计算方法。最后通过介绍利用定时器的更新中断和PWM这两种方法实现呼吸灯,展示了定时器和PWM的配置步骤,并给出了详细的程序设计。另外,介绍了利用定时器实现按键长短按的检测方法。
187 0
STM32速成笔记(六)—定时器
|
芯片
STM32速成笔记(五)—串口通信
本文介绍了串口通信的概念,用途以及一些相关概念。介绍了如何进行printf重定向,如何根据接收到的特定信息,执行特定操作。此外,本文以通过上位机发送特殊指令控制LED亮灭的小项目,给出了详细的配置方法和程序设计。
202 0
STM32速成笔记(五)—串口通信