第30章 电源管理-实现低功耗

第三十章 电源管理-实现低功耗

1. STM32的电源管理简介

电源对电子设备的重要性不言而喻,它是保证系统稳定运行的基础,而保证系统能稳定运行后,又有低功耗的要求。 在很多应用场合中都对电子设备的功耗要求非常苛刻,如某些传感器信息采集设备,仅靠小型的电池提供电源,要求工作长达数年之久, 且期间不需要任何维护;由于智慧穿戴设备的小型化要求,电池体积不能太大导致容量也比较小,所以也很有必要从控制功耗入手, 提高设备的续行时间。因此,STM32有专门的电源管理外设监控电源并管理设备的运行模式,确保系统正常运行,并尽量降低器件的功耗。

1.1 电源监控器

STM32芯片主要通过引脚VDD从外部获取电源,在它的内部具有电源监控器用于检测VDD的电压, 以实现复位功能及掉电紧急处理功能,保证系统可靠地运行。

1.1.1 上电复位与掉电复位(POR与PDR)

当检测到VDD的电压低于阈值VPOR及VPDR时,无需外部电路辅助,STM32芯片会自动保持在复位状态,防止因电压不足强行工作而带来严重的后果。在刚开始电压低于VPOR时(约1.92V), STM32保持在上电复位状态(POR,Power On Reset),当VDD电压持续上升至大于VPOR时,芯片开始正常运行,而在芯片正常运行的时候, 当检测到VDD电压下降至低于VPDR阈值(约1.88V),会进入掉电复位状态(PDR,Power Down Reset)。

1.1.2 可编程电压检测器PVD

上述POR、PDR功能是使用其电压阈值与外部供电电压VDD比较,当低于工作阈值时,会直接进入复位状态,这可防止电压不足导致的误操作。 除此之外,STM32还提供了可编程电压检测器PVD,它也是实时检测VDD的电压,当检测到电压低于编程的VPVD阈值时, 会向内核产生一个PVD中断(EXTI16线中断)以使内核在复位前进行紧急处理。该电压阈值可通过电源控制寄存器PWR_CSR设置。

使用PVD可配置8个等级,见表:

1.2 STM32的电源系统

为了方便进行电源管理,STM32把它的外设、内核等模块跟据功能划分了供电区域, 其内部电源区域划分见图

从框图了解到,STM32的电源系统主要分为备份域电路、内核电路以及ADC电路三部分,介绍如下:

  • ADC电源及参考电压(VDDA供电区域)

为了提高转换精度,STM32的ADC配有独立的电源接口,方便进行单独的滤波。 ADC的工作电源使用VDDA引脚输入,使用VSSA作为独立的地连接, VREF引脚则为ADC提供测量使用的参考电压。

  • 调压器供电电路(VDD/1.8V供电区域)

在STM32的电源系统中调压器供电的电路是最主要的部分,调压器为备份域及待机电路以外的所有数字电路供电,其中包括内核、 数字外设以及RAM,调压器的输出电压约为1.8V,因而使用调压器供电的这些电路区域被称为1.8V域。

调压器可以运行在“运行模式”、“停止模式”以及“待机模式”。在运行模式下,1.8V域全功率运行;在停止模式下1.8V域运行在低功耗状态, 1.8V区域的所有时钟都被关闭,相应的外设都停止了工作,但它会保留内核寄存器以及SRAM的内容;在待机模式下,整个1.8V域都断电, 该区域的内核寄存器及SRAM内容都会丢失(备份区域的寄存器不受影响)。

  • 备份域电路(后备供电区域)

STM32的LSE振荡器、RTC及备份寄存器这些器件被包含进备份域电路中,这 部分的电路可以通过STM32的VBAT引脚获取供电电源, 在实际应用中一般会使用3V的钮扣电池对该引脚供电。

在图中备份域电路的左侧有一个电源开关结构,它的功能类似双二极管结构中的双二极管, 在它的“1”处连接了VBAT电源,“2”处连接了VDD主电源(一般为3.3V), 右侧“3”处引出到备份域电路中。当VDD主电源存在时,由于VDD电压较高, 备份域电路通过VDD供电,节省钮扣电池的电源,仅当VDD掉电时, 备份域电路由钮扣电池通过VBAT供电,保证电路能持续运行,从而可利用它保留关键数据。

1.3 STM32的功耗模式

按功耗由高到低排列,STM32具有运行、睡眠、停止和待机四种工作模式。上电复位后STM32处于运行状态时,当内核不需要继续运行, 就可以选择进入后面的三种低功耗模式降低功耗,这三种模式中,电源消耗不同、唤醒时间不同、唤醒源不同,用户需要根据应用需求, 选择最佳的低功耗模式。三种低功耗的模式说明见表

从表中可以看到,这三种低功耗模式层层递进,运行的时钟或芯片功能越来越少,因而功耗越来越低。

1.3.1 睡眠模式

在睡眠模式中,仅关闭了内核时钟,内核停止运行,但其片上外设,CM3核心的外设全都还照常运行。有两种方式进入睡眠模式, 它的进入方式决定了从睡眠唤醒的方式,分别是WFI(wait for interrupt)和WFE(wait for event),即由等待“中断”唤醒和由“事件”唤醒。 睡眠模式的各种特性见表

1.3.2 停止模式

在停止模式中,进一步关闭了其它所有的时钟,于是所有的外设都停止了工作,但由于其1.8V区域的部分电源没有关闭, 还保留了内核的寄存器、内存的信息,所以从停止模式唤醒,并重新开启时钟后,还可以从上次停止处继续执行代码。 停止模式可以由任意一个外部中断(EXTI)唤醒,在停止模式中可以选择电压调节器为开模式或低功耗模式。 停止模式的各种特性见表

1.3.3 待机模式

待机模式,它除了关闭所有的时钟,还把1.8V区域的电源也完全关闭了,也就是说,从待机模式唤醒后,由于没有之前代码的运行记录, 只能对芯片复位,重新检测boot条件,从头开始执行程序。它有四种唤醒方式,分别是WKUP(PA0)引脚的上升沿,RTC闹钟事件, NRST引脚的复位和IWDG(独立看门狗)复位。

在以上讲解的睡眠模式、停止模式及待机模式中,若备份域电源正常供电, 备份域内的RTC都可以正常运行,备份域内的寄存器的数据会被保存,不受功耗模式影响。

2. 电源管理相关的库函数及命令

STM32标准库对电源管理提供了完善的函数及命令,使用它们可以方便地进行控制,本小节对这些内容进行讲解。

2.1 配置PVD监控功能

PVD可监控VDD的电压,当它低于阈值时可产生PVD中断以让系统进行紧急处理, 这个阈值可以直接使用库函数PWR_PVDLevelConfig配置成前面表中说明的阈值等级。

2.2 WFI与WFE命令

我们了解到进入各种低功耗模式时都需要调用WFI或WFE命令,它们实质上都是内核指令, 在库文件core_cm3.h中把这些指令封装成了函数

/** brief  等待中断
    等待中断 是一个暂停执行指令
    暂停至任意中断产生后被唤醒
*/
#define __WFI                             __wfi
/** brief  等待事件

    等待事件 是一个暂停执行指令
    暂停至任意事件产生后被唤醒
*/
#define __WFE                             __wfe

对于这两个指令,我们应用时一般只需要知道,调用它们都能进入低功耗模式, 需要使用函数的格式“__WFI();”和“__WFE();”来调用(因为__wfi及__wfe是编译器内置的函数,函数内部调用了相应的汇编指令)。 其中WFI指令决定了它需要用中断唤醒,而WFE则决定了它可用事件来唤醒

2.3 进入停止模式

直接调用WFI和WFE指令可以进入睡眠模式,而进入停止模式则还需要在调用指令前设置一些寄存器位, STM32标准库把这部分的操作封装到PWR_EnterSTOPMode函数中了

/**
* @brief 进入停止模式
*
* @note   在停止模式下所有I/O的会保持在停止前的状态
* @note   从停止模式唤醒后,会使用HSI作为时钟源
* @note   调压器若工作在低功耗模式,可减少功耗,但唤醒时会增加延迟
* @param  PWR_Regulator: 设置停止模式时调压器的工作模式
*            @arg PWR_MainRegulator_ON: 调压器正常运行
*            @arg PWR_Regulator_LowPower: 调压器低功耗运行
* @param  PWR_STOPEntry: 设置使用WFI还是WFE进入停止模式
*            @arg PWR_STOPEntry_WFI: WFI进入停止模式
*            @arg PWR_STOPEntry_WFE: WFE进入停止模式
* @retval None
*/
void PWR_EnterSTOPMode(uint32_t PWR_Regulator, uint8_t PWR_STOPEntry)
{
    uint32_t tmpreg = 0;
    /* 检查参数 */
    assert_param(IS_PWR_REGULATOR(PWR_Regulator));
    assert_param(IS_PWR_STOP_ENTRY(PWR_STOPEntry));

    /* 设置调压器的模式 ------------*/
    tmpreg = PWR->CR;
    /* 清除 PDDS 及 LPDS 位 */
    tmpreg &= CR_DS_MASK;
    /* 根据PWR_Regulator 的值(调压器工作模式)配置LPDS,MRLVDS及LPLVDS位*/
    tmpreg |= PWR_Regulator;
    /* 写入参数值到寄存器 */
    PWR->CR = tmpreg;
    /* 设置内核寄存器的SLEEPDEEP位 */
    SCB->SCR |= SCB_SCR_SLEEPDEEP;

    /* 设置进入停止模式的方式-----------------*/
    if (PWR_STOPEntry == PWR_STOPEntry_WFI) {
        /* 需要中断唤醒 */
        __WFI();
    } else {
        /* 需要事件唤醒 */
        __WFE();
    }

    /* 以下的程序是当重新唤醒时才执行的,清除SLEEPDEEP位的状态 */
    SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP);
}

这个函数有两个输入参数,分别用于控制调压器的模式及选择使用WFI或WFE停止,代码中先是根据调压器的模式配置PWR_CR寄存器, 再把内核寄存器的SLEEPDEEP位置1,这样再调用WFI或WFE命令时,STM32就不是睡眠,而是进入停止模式了。 函数结尾处的语句用于复位SLEEPDEEP位的状态,由于它是在WFI及WFE指令之后的,所以这部分代码是在STM32被唤醒的时候才会执行。

要注意的是进入停止模式后,STM32的所有I/O都保持在停止前的状态,而当它被唤醒时,STM32使用HSI作为系统时钟(8MHz)运行, 由于系统时钟会影响很多外设的工作状态,所以一般我们在唤醒后会重新开启HSE,把系统时钟设置回原来的状态。

2.4 进入待机模式

类似地,STM32标准库也提供了控制进入待机模式的函数

/**
* @brief 进入待机模式
* @note   待机模式时,除以下引脚,其余引脚都在高阻态:
*          -复位引脚
*          - RTC_AF1 引脚 (PC13) (需要使能侵入检测、时间戳事件或RTC闹钟事件)
*          - RTC_AF2 引脚 (PI8) (需要使能侵入检测或时间戳事件)
*          - WKUP 引脚 (PA0) (需要使能WKUP唤醒功能)
* @note  在调用本函数前还需要清除WUF寄存器位
* @param  None
* @retval None
*/
void PWR_EnterSTANDBYMode(void)
{
    /* 清除 Wake-up 标志 */
    PWR->CR |= PWR_CR_CWUF;
    /* 选择待机模式 */
    PWR->CR |= PWR_CR_PDDS;
    /* 设置内核寄存器的SLEEPDEEP位  */
    SCB->SCR |= SCB_SCR_SLEEPDEEP;
    /* 存储操作完毕时才能进入待机模式,使用以下语句确保存储操作执行完毕 */
#if defined ( __CC_ARM   )
    __force_stores();
#endif
    /* 等待中断唤醒 */
    __WFI();
}

该函数中先配置了PDDS寄存器位及SLEEPDEEP寄存器位,接着调用__force_stores函数确保存储操作完毕后再调用WFI指令, 从而进入待机模式。这里值得注意的是,待机模式也可以使用WFE指令进入的,如果您有需要可以自行修改。

在进入待机模式后,除了被使能了的用于唤醒的I/O,其余I/O都进入高阻态, 而从待机模式唤醒后,相当于复位STM32芯片,程序重新从头开始执行。

3. 三种模式之比较

3.1 睡眠模式 (Sleep Mode)

  • 功耗:较低,但仍然会消耗一些电流。
  • 特点:CPU停止运行,但外设可以继续工作。
  • 唤醒时间:快速,通常在微秒级。
  • 优点:适用于需要保持外设活动(如定时器、UART等)的场景,响应迅速。
  • 缺点:功耗相对较高,不适合需要极低功耗的应用。

3.2 停止模式 (Stop Mode)

  • 功耗:非常低,通常在微安级别。
  • 特点:CPU和大部分外设都会关闭,只有少数外设(如RTC)可以保持工作。
  • 唤醒时间:较快,通常在微秒级,但稍慢于睡眠模式。
  • 优点:在需要更低功耗的情况下非常有效。
  • 缺点:外设的可用性受限,必须使用特定的外设来唤醒MCU。

3.3 待机模式 (Standby Mode)

  • 功耗:最低,几乎为零,只有极少的电流用于保持状态。
  • 特点:所有外设关闭,只有特定的唤醒源(如GPIO或外部中断)可以唤醒MCU。
  • 唤醒时间:相对较慢,可能需要几毫秒。
  • 优点:适合长时间不需要运行的应用,能有效延长电池寿命。
  • 缺点:唤醒时间长,且在此模式下无法进行其他操作。

3.4 总结

  • 睡眠模式适合需要快速响应且部分外设仍需运行的情况。
  • 停止模式适合需要较低功耗的应用,且可以通过特定外设唤醒。
  • 待机模式适合需要极低功耗的应用,但唤醒时间较长,外设功能受限。

2024.9.25 第一次修订,后期不再维护

2025.1.29 修订部分内容

posted @ 2025-02-09 13:21  hazy1k  阅读(84)  评论(0)    收藏  举报