【正点原子STM32】LOW POWER(PWR)低功耗(电源系统结构、低功耗模式(睡眠、停止、待机)、稳压器、WFI任意中断和WFE唤醒事件命令、低功耗相关寄存器和HAL库驱动、低功耗模式配置步骤)

一、STM32 电源系统结构介绍

二、低功耗模式介绍

三、低功耗相关寄存器介绍

四、低功耗相关HAL库驱动介绍

五、低功耗模式的使用步骤

六、编程实战
七、总结

一、STM32 电源系统结构介绍

低功耗是什么?

在这里插入图片描述
低功耗(Low Power) 是指在特定功能或操作下,设备或系统消耗的能量较少的特性。在集成电路中,低功耗设计旨在降低电路的能耗,以实现以下目标:

  1. 延长电池寿命: 对于依赖电池供电的产品,低功耗设计可以显著延长电池的使用寿命,从而减少更换电池的频率,降低维护成本,并提高产品的可靠性和便利性。

  2. 减小电池体积: 低功耗设计可以使设备在相同的电池容量下运行更长时间,因此可以采用更小容量的电池,从而减小电池的体积和重量,使产品更加轻便、便携和易于携带。

  3. 减少电磁干扰: 低功耗设计通常伴随着电路操作频率的降低,从而减少了高频率时产生的电磁辐射和干扰,有助于提高无线通信系统的质量和稳定性。

  4. 简化电源设计: 低功耗设计通常意味着电路在操作时消耗的能量较少,因此可以采用更简单、更低成本的电源设计,减少对散热和电源管理的要求,降低产品的整体成本和复杂度。

总的来说,低功耗设计不仅可以提高设备的能效和可靠性,还可以降低产品成本并改善用户体验,因此在许多电子设备和系统中都是非常重要的设计考虑因素。
在这里插入图片描述

1.1、STM32 电源系统结构(F1)

在这里插入图片描述
STM32 F1系列的电源系统结构如下:

主要电源电压(VDD): STM32 F1系列的工作电压范围为2.0V至3.6V。这是器件的主要工作电压,提供给大多数数字和模拟电路。

  1. 模拟外设独立供电: 为了提高模拟外设的转换精度,通常会给模拟外设提供独立的电源供应。这样可以减少数字电路对模拟电路的干扰,提高模拟信号的精确度和稳定性。

  2. 电压调节器: 电压调节器用于提供1.8V的供电电压。1.8V供电区域是电源系统中最主要的部分,因为许多核心电路和外设需要这个特定的工作电压来保证正常运行。

  3. 两种供电方式:

    • VBAT: VBAT是备用电池供电模式,用于提供备份电源。在主要电源被切断的情况下,VBAT可以保持某些功能模块的工作,例如实时时钟(RTC)和备份存储器。
    • VDD: VDD是主要的电源供电模式,提供主要的工作电压给器件的大部分功能模块。当主要电源可用时,器件会以VDD为主要供电方式。

综上所述,STM32 F1系列的电源系统结构通过提供主要电源电压和模拟外设独立供电来保证系统的稳定性和精确度,同时还提供备用电源模式以保障关键功能在主要电源失效时的正常工作。

1.2、STM32 电源系统结构(F4 / F7)

在这里插入图片描述
STM32 F4和F7系列的电源系统结构如下所示:

  1. 备份域电路:

    • 包含LSE振荡器(Low-Speed External oscillator)、RTC(Real-Time Clock)、备份寄存器和备份SRAM(Static Random Access Memory)等组件。
    • 电源开关能够自动切换供电来源,可以从VDD(主要电源)或者VBAT(备份电池)中选择供电。
  2. 调压器电路(1.2V域):

    • 该电路为备份域以外的所有数字电路提供供电,包括内核、数字外设和RAM等。
    • 这个调压器电路负责将主要的工作电源 VDD 转换为所需的稳定电压,通常为1.2V。
  3. ADC电路和参考电压:

    • ADC(Analog-to-Digital Converter)的工作电源使用 VDDA 引脚输入。
    • 为了提供稳定的参考电压给ADC,通常会使用 VREF 引脚来连接外部参考电压源。这个参考电压源可以是外部提供的电压信号,也可以是芯片内部的某些参考电路提供的电压。

综上所述,STM32 F4和F7系列的电源系统结构通过备份域电路和调压器电路来为不同部分提供不同的电源供应,确保各个功能模块能够正常、稳定地工作。ADC电路和参考电压的设计则能够保证模数转换的准确性和稳定性。

1.3、STM32 电源系统结构(H7)

在这里插入图片描述
STM32 H7系列的电源系统结构如下所示:

  1. USB稳压器域:

    • V S S V_{SS} VSS 是所有电源和模拟稳压器的公共地。
    • V D D 50 U S B V_{DD50USB} VDD50USB 是外部电源为 USB 稳压器提供的电压。
    • V D D 33 U S B V_{DD33USB} VDD33USB 是 USB 接口供电的 USB 稳压器的输出。
  2. 内核域:

    • V D D L D O V_{DDLDO} VDDLDO 是外部电源为稳压器提供的电压,用于供电内核域。
    • V C A P V_{CAP} VCAP 是数字内核域的电源,与其他电源独立。
    • V C O R E V_{CORE} VCORE 可通过稳压器或外部电源( V C A P V_{CAP} VCAP)供电。
      • 除备份域和待机电路外的所有数字电路都由 V C O R E V_{CORE} VCORE 供电。
  3. VDD域:

    • V D D V_{DD} VDD 为I/O 和系统模拟模块(复位/电源管理/时钟)提供外部电源。
    • V B A T V_{BAT} VBAT 是备份电源。
  4. 备份域:

    • 备份域的电源来自 V S W V_{SW} VSW,而 V S W V_{SW} VSW 则来自 V D D V_{DD} VDD 域的 V D D V_{DD} VDD V B A T V_{BAT} VBAT
  5. 模拟域:

    • V D D A V_{DDA} VDDA 是独立于其他电源的外部模拟电源。
    • V S S A V_{SSA} VSSA 是独立的模拟和参考电压地。
    • V R E F V_{REF} VREF 是用于 ADC 和 DAC 的外部参考电压。

综上所述,STM32 H7系列的电源系统通过不同的域和稳压器来为不同的模块和功能提供稳定的电源供应,确保系统的正常运行和性能稳定性。
在这里插入图片描述
STM32 H7 系列的 内核域 划分为三个部分:

  1. D1 高性能域:

    • CPU(CM7)和相关外设。
    • 用于执行紧急、重要或高优先级的程序。
    • 在 480MHz 主频下执行,以实现最快速的响应。
    • 从 TCM(Tightly-Coupled Memory,紧密耦合存储器)和 L1 缓存中提取紧急或高优先级的用户程序。
  2. D2 通信接口域:

    • 主要用于数据通信工作,以减轻 CPU 的负担。
    • 执行外部程序,例如通过以太网、USB 或其他串口进行通信。
    • 与外部设备和通信接口相关的外设和功能可能位于此域。
  3. D3 数据批处理域:

    • 用于在系统进入睡眠模式时继续工作,以处理数据批处理任务。
    • 当系统处于睡眠模式时,某些应用可能仍需要处理数据,因此此域用于在唤醒时立即处理数据。
    • 在需要批量处理数据的情况下,该域负责抓取和处理数据。

这种功能域的划分有助于优化系统的性能和功耗管理,使系统能够更有效地处理不同类型的任务,并在需要时实现快速响应。

二、低功耗模式介绍

在这里插入图片描述
对于 STM32(包括 F1、F4、F7 等系列),低功耗模式包括睡眠模式、停止模式和待机模式。以下是这些模式的主要特点:

  1. 睡眠模式:

    • 电源消耗较低,CPU 处于停止运行状态,但时钟和外设仍在运行。
    • 唤醒时间较短,CPU 可以快速唤醒。
    • 常用于对功耗要求不是很严格的场合,需要快速响应外部事件的情况下。
  2. 停止模式:

    • 电源消耗更低,CPU 和所有外设都停止工作,时钟被关闭,唯一工作的是备份寄存器、RTC 和外部中断线。
    • 唤醒时间相对较长,因为需要重新初始化系统。
    • 适用于需要长时间保持低功耗,但对唤醒速度要求不是很高的场合。
  3. 待机模式:

    • 电源消耗最低,CPU、系统时钟和外设都停止工作,唯一工作的是备份寄存器和RTC。
    • 唤醒时间较长,因为需要重新初始化整个系统。
    • 适用于对功耗要求非常严格的场合,例如需要长时间运行电池供电的设备,在不需要时最大程度地降低功耗。

这些低功耗模式的选择取决于具体的应用需求和对功耗、唤醒时间的要求。通常,更低功耗的模式会导致唤醒时间的增加,因此需要根据具体的应用场景进行权衡和选择。

2.1、睡眠模式

在这里插入图片描述
睡眠模式是一种低功耗模式,主要特点是 CPU 内核停止运行,但外设和时钟系统仍然工作。以下是睡眠模式的主要特点和优缺点:

特点:

  1. 内核时钟关闭: 在睡眠模式下,CPU 内核时钟被关闭,CPU 内核停止运行,以降低功耗。
  2. 时钟系统提供时钟信号: 时钟系统(如 HSI 或 HSE)仍为总线提供时钟信号,以确保外设和存储器继续正常工作。
  3. 电压调节器为总线供电: 电压调节器仍为总线提供供电,以确保外设和存储器能够继续正常工作。
  4. 总线提供时钟信号和供电: 总线(包括外设、IO、SPI、TIM、存储器等)仍然能够继续接收时钟信号和供电,以保持其正常工作状态。

优点:

  • 对系统影响小: 睡眠模式下,虽然 CPU 内核停止运行,但外设和存储器仍然可以继续正常工作,因此对系统的影响较小。

缺点:

  • 节能效果最差: 虽然睡眠模式下 CPU 内核时钟被关闭,但其他部分仍然在工作,因此功耗相对较高,节能效果最差。

综上所述,睡眠模式适用于对系统影响要求较低、且对功耗要求不是特别严格的应用场景。

2.2、停止模式

在这里插入图片描述
停止模式是一种更低功耗的模式,相比睡眠模式,它对功耗的降低更为明显。以下是停止模式的主要特点和优缺点:

特点:

  1. 内核时钟关闭: 在停止模式下,CPU 内核时钟被关闭,CPU 内核停止运行,以降低功耗。
  2. 关闭内核逻辑电路的所有时钟: 内核的逻辑电路的所有时钟被关闭,确保内核不执行任何指令。
  3. 关闭时钟系统: 时钟系统(如 HSI 或 HSE)停止为总线提供时钟信号,以降低功耗。
  4. 只有电压调节器为总线供电: 电压调节器仍为总线提供供电,以确保外设和存储器能够继续工作。

总线再为外设、内核、存储器提供供电:

  • 外设 IO/SPI/TIM: 外设仍然可以正常供电,保持其工作状态。
  • 内核: 虽然内核时钟关闭,但内核仍然接收供电,以保持其状态。
  • 存储器 SRAM/FLASH: 存储器仍然能够接收供电,以保持数据的存储。

优点:

  • 节能效果好: 停止模式下,系统大部分功能都被关闭,功耗较低,节能效果好。
  • 程序不会复位: 在停止模式下,系统处于较低功耗状态,但不会导致程序复位,因此可以保持程序的执行状态。

缺点:

  • 恢复时间较长: 当系统需要从停止模式恢复时,由于需要重新启动各种时钟和逻辑电路,恢复时间相对较长,可能会影响系统的实时性。

综上所述,停止模式适用于要求较低功耗且可以接受恢复时间较长的应用场景,可以有效延长电池寿命,但需要注意恢复时间可能会影响系统的实时性。

2.3、待机模式

在这里插入图片描述
待机模式是 STM32 中最低功耗的模式之一,具有以下特点和优缺点:

特点:

  1. 内核时钟关闭: 在待机模式下,CPU 内核时钟被关闭,CPU 内核停止运行,以进一步降低功耗。
  2. 关闭内核逻辑电路的所有时钟: 除了关闭 CPU 内核时钟外,待机模式还会关闭内核逻辑电路的所有时钟信号,以减少功耗。
  3. 关闭时钟系统: 时钟系统(如 HSI 或 HSE)也会被关闭,进一步降低功耗。
  4. 关闭电压调节器: 电压调节器也会被关闭,以减少功耗。这会导致外部电源被切断,但备份电源仍然可用。
  5. 少数条件唤醒: 在待机模式下,系统会进入一种极低功耗状态,只有少数特定的条件(如外部中断、RTC 中断等)发生时,才能唤醒系统。

优点:

  • 节能效果最好: 待机模式下功耗最低,对于要求极低功耗的应用场景非常合适。

缺点:

  • 程序会复位: 在待机模式下,CPU 内核停止运行,系统状态丢失,待机模式唤醒后系统将重新启动,程序会复位。
  • 少数条件唤醒: 待机模式下只有少数特定的条件能够唤醒系统,因此对于一些需要定期唤醒或响应外部事件的应用可能不太适用。

综上所述,待机模式适用于对功耗要求极高,且可以容忍系统状态丢失和需要极少的唤醒条件的应用场景。
在这里插入图片描述
在这里插入图片描述

2.4、STM32H750 (H7)6种低功耗模式

在这里插入图片描述
在STM32H750 (H7)中,有以下六种低功耗模式,每种模式都有不同的影响和功耗水平,可以根据具体需求选择合适的模式来降低功耗:

  1. CSleep模式:

    • 主要影响:CPU时钟停止,CPU停止工作,但外设仍可以运行。
    • 这个模式适用于需要降低CPU功耗但仍需要保持外设运行的场景,例如在某些情况下可以暂停CPU运算而保持外设的数据传输或处理。
  2. CStop模式:

    • 主要影响:CPU与其子系统时钟停止,CPU停止工作,大部分外设也停止工作。
    • 在这种模式下,CPU及其子系统的时钟停止,大部分外设也进入停止状态,可以显著降低系统功耗。
  3. DStop模式:

    • 主要影响:CPU停止工作,域总线矩阵时钟停止,D1,D2域进入停止模式。
    • 这个模式下,CPU停止工作,域总线矩阵时钟停止,D1和D2域进入停止模式,对于一些需要进一步降低功耗的应用场景可以采用此模式。
  4. Stop模式:

    • 主要影响:CPU停止工作,D3域进入停止模式,D1/D2域进入停止/待机模式。
    • 这个模式下,CPU停止工作,D3域进入停止模式,D1和D2域可以进入停止或待机模式,适用于一些对功耗要求较高的应用。
  5. DStandby模式:

    • 主要影响:CPU停止工作,域掉电,D1/D2/D3域进入待机模式。
    • 在这种模式下,CPU停止工作,所有域都掉电,D1、D2和D3域进入待机模式,功耗进一步降低,但唤醒时恢复时间较长。
  6. Standby模式:

    • 主要影响:系统掉电,达到最低功耗。
    • 这是最低功耗的模式,系统完全掉电,只有一些特定的唤醒源可以唤醒系统,但恢复时间最长。

在运行模式下,还可以通过降低系统时钟频率或关闭无需用到的外设时钟来进一步降低功耗。

稳压器

稳压器是一种电子元件或电路,用于将输入电压调节为稳定的输出电压。它的作用是通过控制输出电压,以确保在输入电压发生变化或负载变化时,输出电压保持稳定。稳压器通常用于电源管理中,为各种电子设备提供稳定的电压供应。

在STM32微控制器中,稳压器通常被用于为内核、外设和其他电路提供稳定的电压。不同系列的STM32微控制器可能采用不同类型的稳压器,例如线性稳压器(LDO)或开关稳压器(如DC-DC转换器)。这些稳压器可以提供不同的输出电压,并且具有不同的性能特性,以满足不同应用场景的需求。

稳压器的主要功能包括:

  1. 稳定输出电压: 稳压器会监测输出电压,并根据需要调整其输出,以保持输出电压稳定在设定的水平。
  2. 过载保护: 稳压器通常具有过载保护功能,可以在输出电流超过额定值时自动断开输出,保护电路不受损坏。
  3. 短路保护: 稳压器还可以检测并响应输出短路情况,以防止短路电流对电路造成损坏。
  4. 温度保护: 一些稳压器还具有过热保护功能,可以在温度超过安全范围时自动降低输出电压或断开输出,以防止器件过热。
  5. 低压降: 高效的稳压器可以实现较低的输出电压降,从而减少功耗和发热,提高系统效率。

在STM32微控制器中,稳压器是电源管理系统中的关键组件,对于确保系统的稳定性、可靠性和低功耗运行至关重要。通过合理选择和配置稳压器,可以满足不同应用场景对电源稳定性和效率的要求。
在这里插入图片描述
在STM32微控制器中,稳压器通常具有不同的工作模式,以适应不同的系统需求和功耗优化要求。这些工作模式包括主工作模式(MR)、低功耗模式(LP)和关闭模式。下面是对这些模式的简要介绍:

  1. 主工作模式(MR):

    • 在主工作模式下,稳压器以最高性能和最低延迟的方式工作,为系统提供稳定的输出电压。
    • 这种模式适用于系统处于活动状态、需要快速响应和最大性能的情况。
  2. 低功耗模式(LP):

    • 低功耗模式旨在降低系统功耗,通过减少稳压器的工作频率或切换到更低功耗的工作模式来实现。
    • 这种模式通常用于系统处于低负载或待机状态、对功耗要求严格的情况。
    • 在低功耗模式下,稳压器仍然提供稳定的输出电压,但可能在响应时间和性能上有所牺牲。
  3. 关闭模式:

    • 在关闭模式下,稳压器完全关闭,停止为系统提供输出电压。
    • 这种模式用于系统不需要电源或需要完全断电的情况,以最大程度地降低功耗。
    • 在关闭模式下,稳压器的功耗通常非常低,接近于零。

根据系统的工作状态和功耗要求,可以在这些模式之间进行切换,以实现最佳的功耗和性能平衡。通常,系统在活动状态下使用主工作模式以获得最佳的性能,而在待机或低负载状态下切换到低功耗模式或关闭模式以实现功耗优化。
在这里插入图片描述
在系统的运行模式(MR模式)下,各个域(D1、D2、D3域)的工作情况如下:

  1. D1域(CPU、外设、RAM、FLASH):

    • 在MR模式下,D1域中的CPU、外设、RAM和FLASH都处于活动状态,能够实时执行任务并访问存储器。
    • 这个域通常用于执行实时性要求高、对性能要求较高的任务。
  2. D2域(外设、RAM):

    • D2域中的外设和RAM也处于活动状态,但相比于D1域,可能是一些性能要求较低或不需要实时响应的外设。
    • 这个域通常用于执行一些辅助性任务或需要较少资源的任务。
  3. D3域(系统逻辑、EXTI、外设、RAM、IO逻辑):

    • 在MR模式下,D3域中的系统逻辑、外设、RAM和IO逻辑也处于活动状态,但可能是一些非关键任务或低功耗外设。
    • 这个域通常用于执行一些后台任务、中断服务程序或需要较少资源且功耗要求不高的任务。

在运行模式下,系统可以通过软件调节为不同的电压级别,以实现功耗的优化。通过降低系统时钟频率、调节外设工作频率、关闭未使用的外设等方式,可以有效降低系统的功耗,延长电池寿命或降低整体系统的能耗。
在这里插入图片描述
在系统的停止模式下,各个域(D1、D2、D3域)的工作情况如下:

  1. D1域(CPU、外设、RAM、FLASH):

    • 在停止模式下,D1域中的CPU、外设、RAM和FLASH都处于停止状态,停止工作并进入低功耗状态。
    • 这个域通常是系统的核心部分,暂时停止工作以降低功耗,但可以快速唤醒以响应外部事件。
  2. D2域(外设、RAM):

    • D2域中的外设和RAM也处于停止状态,类似于D1域,进入低功耗状态但能够快速唤醒。
    • 这个域通常包含一些次要的外设或用于临时存储数据的RAM,同样可以快速恢复工作状态。
  3. D3域(系统逻辑、EXTI、外设、RAM、IO逻辑):

    • 在停止模式下,D3域中的系统逻辑、外设、RAM和IO逻辑也处于停止状态,进入低功耗状态。
    • 这个域通常包含一些后台任务、中断服务程序或低功耗外设,需要通过外部事件或中断来唤醒。

在停止模式下,如果稳压器设置为MR模式,系统可以快速唤醒,因为VCORE电源电压级别较高。然而,如果稳压器设置为LP模式,系统将获得较低的VCORE电压级别,这会增加唤醒时间,但可以实现更低的功耗。
在这里插入图片描述
在系统的待机模式下,主要特点包括:

  1. 稳压器关闭: 在待机模式下,稳压器停止工作,不再为系统提供电源。这导致整个系统的电源都被关闭,从而降低功耗到最低水平。

  2. VCORE域掉电: VCORE域也失去了电源供应,在待机模式下处于掉电状态。这意味着CPU核心及其相关外设、RAM和闪存等都停止工作,并且其电源电压被切断,以进一步降低功耗。

  3. 寄存器和存储器内容保持: 在待机模式下,为了保持系统状态的一致性,除了待机电路和备份域外,寄存器和存储器的内容通常是保持不变的。这意味着系统在退出待机模式时能够恢复到先前的状态,不会丢失任何重要数据。

  4. 功耗达到最低水平: 待机模式是功耗最低的低功耗模式之一,因为整个系统的电源都被关闭,只有必要的待机电路和备份域保持运行。这使得待机模式在需要极低功耗但又需要快速唤醒时非常有用。

综上所述,系统在待机模式下可以实现极低的功耗,适用于需要长时间待机并且需要快速唤醒以响应外部事件的应用场景。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

三、低功耗相关寄存器介绍

3.1、低功耗相关寄存器(F1)

在这里插入图片描述
在STM32F1系列中,以下是与低功耗相关的寄存器及其作用:

  1. SCB_SCR(系统控制寄存器):

    • 作用:用于选择休眠和深度休眠模式,以及控制其他低功耗特性。这个寄存器允许配置处理器在进入休眠模式时的行为,如使能休眠模式、使能唤醒中断等。
  2. PWR_CR(电源控制寄存器):

    • 作用:用于设置低功耗相关的控制参数,如清除标志位、选择系统进入的低功耗模式等。通过配置这个寄存器,可以使系统进入不同的低功耗模式,比如待机模式或者停止模式。
  3. PWR_CSR(电源控制/状态寄存器):

    • 作用:用于查看系统的当前状态,例如检查系统是否处于待机模式、是否发生了唤醒事件等。这个寄存器还可以用于使能唤醒引脚,以便外部事件能够唤醒系统。

这些寄存器提供了对STM32F1系列微控制器低功耗特性的控制和监测功能,能够帮助开发者有效管理系统的功耗,从而实现节能的目的。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

WFI命令任意中断和WFE命令唤醒事件

在这里插入图片描述
WFI(Wait for Interrupt)指令和 WFE(Wait for Event)指令是用于处理器进入低功耗状态的指令。

  • WFI指令使处理器进入睡眠状态,等待任意中断事件的发生,此时处理器的时钟停止,直到有中断请求到来才会唤醒并继续执行。
  • WFE指令也使处理器进入睡眠状态,但是它是等待特定事件的发生,而不是等待任意中断。只有当有与WFE关联的事件发生时,处理器才会被唤醒。

在ARM Cortex-M系列处理器中,这两个指令通常由编译器提供的内联函数 __WFI()__WFE() 来调用,这些函数会将相应的汇编指令插入到代码中。通过调用这些函数,处理器可以方便地进入低功耗状态,并等待中断或事件的发生来唤醒。详细的使用方法和功能特性可以参考相关的技术手册,如《Cortex-M3权威指南》。

3.2、低功耗相关寄存器(H7)

在这里插入图片描述
低功耗相关寄存器对于 STM32H7 系列主要包括以下寄存器:

  1. SCB_SCR(系统控制寄存器):用于设置系统控制的各种参数,包括选择休眠和深度休眠模式等。

  2. PWR_CR1(PWR 控制寄存器1):用于配置进入深度睡眠后的 VCORE 电压级别以及电源监控相关的设置。

  3. PWR_CPUCR(PWR CPU 控制寄存器):用于设置处理器核心 (CPU) 域的低功耗模式,以及查询当前相关的标志位。

  4. PWR_WKUPEPR(PWR 唤醒使能和极性寄存器):用于设置唤醒源的使能、极性,以及控制上拉/下拉等配置。

  5. PWR_WKUPCR(PWR 唤醒清除寄存器):用于清除唤醒源的标志位,以便在唤醒后重置相应的标志位。

  6. EXTI_CPUIMR1(中断屏蔽寄存器):用于设置事件的 CPU 中断屏蔽,控制是否允许特定的中断请求唤醒处理器。

  7. EXTI_CPUPR1(可配置事件挂起请求寄存器):用于设置管理 EXTI0 到 EXTI21 线的中断标志位,即处理器是否挂起对应的外部中断请求。

  8. EXTI_(R/F)TSR1((上/下)升沿触发选择寄存器):用于设置输入线的触发极性,即配置是上升沿触发还是下降沿触发等。

这些寄存器的配置和使用可以实现 STM32H7 系列芯片在不同的低功耗模式下的操作和管理。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

WFI命令和WFE命令

在这里插入图片描述
WFI(Wait For Interrupt)和WFE(Wait For Event)是 ARM Cortex-M 处理器中的指令,用于实现低功耗模式下的等待和唤醒操作。

  • WFI(Wait For Interrupt):该指令使处理器进入睡眠状态,直到接收到一个中断请求时才会被唤醒。在低功耗模式下,当没有其他任务需要执行时,可以使用WFI指令来暂时挂起处理器,降低功耗。

  • WFE(Wait For Event):该指令使处理器进入睡眠状态,直到接收到一个事件时才会被唤醒。与WFI不同的是,WFE允许处理器在等待期间响应一些特定的事件,而不仅仅是中断请求。这些事件可以是来自外部设备的信号、软件触发的事件等。

这两个指令通常通过内置函数的形式调用,如__WFI()__WFE()。在低功耗模式下,通过使用这些指令,处理器可以在等待外部事件或中断时进入睡眠状态,从而有效地降低功耗。

四、低功耗相关HAL库驱动介绍

4.1、低功耗相关HAL库驱动(F1)

在这里插入图片描述
以下是针对STM32 F1系列的低功耗相关HAL库驱动函数及其关联寄存器的功能描述:

  1. HAL_PWR_EnterSLEEPMode(…)

    • 关联寄存器:SCB_SCR
    • 功能描述:使MCU进入睡眠模式。在睡眠模式下,CPU停止工作,但系统时钟和大多数外设继续运行。
  2. HAL_PWR_EnterSTOPMode(…)

    • 关联寄存器:PWR_CR/SCB_SCR
    • 功能描述:使MCU进入停止模式。在停止模式下,CPU和大多数外设的时钟都停止了,但外设的状态和寄存器内容被保持。
  3. HAL_PWR_EnterSTANDBYMode(…)

    • 关联寄存器:PWR_CR/SCB_SCR
    • 功能描述:使MCU进入待机模式。在待机模式下,除了备份寄存器和待机唤醒引脚之外,所有的内部设备和外设都被关闭。
  4. HAL_PWR_EnableWakeUpPin(…)

    • 关联寄存器:PWR_CSR
    • 功能描述:使能待机唤醒引脚的功能。这个函数允许配置一个引脚,用于唤醒MCU从待机模式中唤醒。
  5. __HAL_PWR_CLEAR_FLAG(…)

    • 关联寄存器:PWR_CR
    • 功能描述:清除与电源管理相关的标志位。可以用于清除标记,例如唤醒标志。
  6. __HAL_RCC_PWR_CLK_ENABLE(…)

    • 关联寄存器:RCC_APB1ENR
    • 功能描述:使能电源时钟。这个函数用于使能电源控制器(PWR)时钟,以便使用电源控制器的相关功能。

这些函数和相关的寄存器允许在STM32F1系列中有效地控制低功耗模式的进入和退出,从而实现功耗的优化。

4.2、低功耗相关HAL库驱动(H7)

在这里插入图片描述
以下是针对STM32 H7 系列的低功耗相关HAL库驱动函数及其关联寄存器的功能描述:

  1. HAL_PWR_EnterSLEEPMode(…)

    • 关联寄存器:SCB_SCR
    • 功能描述:使MCU进入睡眠模式。在睡眠模式下,CPU停止工作,但系统时钟和大多数外设继续运行。
  2. HAL_PWR_EnterSTOPMode(…)

    • 关联寄存器:PWR_CR1/PWR_CPUCR/SCB_SCR
    • 功能描述:使MCU进入停止模式。在停止模式下,CPU和大多数外设的时钟都停止了,但外设的状态和寄存器内容被保持。
  3. HAL_PWR_EnterSTANDBYMode(…)

    • 关联寄存器:PWR_CPUCR/SCB_SCR
    • 功能描述:使MCU进入待机模式。在待机模式下,除了备份域和待机唤醒引脚之外,所有的内部设备和外设都被关闭。
  4. HAL_PWR_EnableWakeUpPin(…)

    • 关联寄存器:PWR_WKUPEPR
    • 功能描述:使能待机唤醒引脚的功能。这个函数允许配置一个引脚,用于唤醒MCU从待机模式中唤醒。

这些函数和相关的寄存器允许在STM32 H7系列中有效地控制低功耗模式的进入和退出,从而实现功耗的优化。

五、低功耗模式的使用步骤

5.1、睡眠模式配置步骤

在这里插入图片描述
在这里插入图片描述
你提供的睡眠模式配置步骤已经很完整了,这里再详细解释一下:

  1. 初始化WKUP为中断触发源

    • 首先,需要将WKUP引脚配置为外部中断触发源,以便外部事件(比如按键按下)可以唤醒MCU。
    • 这一步通常通过配置GPIO外部中断来实现。具体的配置方法可以参考外部中断引脚的初始化过程。
  2. 外设低功耗处理

    • 在进入睡眠模式之前,你可以选择将不需要工作的外设进入低功耗状态,以进一步降低功耗。
    • 外设的低功耗处理通常涉及到外设的停止、休眠或其他低功耗模式的配置。具体的处理方法需要根据外设类型和要求进行相应配置。
  3. 进入睡眠模式

    • 一切准备就绪后,调用HAL_PWR_EnterSLEEPMode函数将MCU置于睡眠模式。
    • 进入睡眠模式后,CPU会停止工作,但是系统的时钟和大多数外设仍然会继续工作,以便于WKUP引脚的外部中断能够唤醒MCU。
  4. 等待WKUP外部中断唤醒

    • 此时,MCU处于睡眠状态,等待外部事件(如按键按下)触发WKUP引脚的外部中断。
    • 当WKUP引脚产生外部中断时,MCU会被唤醒,从睡眠模式中恢复到运行模式,程序将继续执行。

5.2、停止模式配置步骤

在这里插入图片描述
在这里插入图片描述
停止模式(Stop Mode)是一种低功耗模式,适用于要求低功耗但仍需要快速唤醒的场景。以下是停止模式配置的一般步骤:

  1. 初始化WKUP为唤醒源

    • 与睡眠模式类似,首先需要将WKUP引脚配置为外部唤醒源,以便外部事件(例如按键按下)可以唤醒MCU。
    • 这一步通常通过配置GPIO外部中断来实现。
  2. 选择停止模式的唤醒源

    • 在进入停止模式之前,需要选择哪些外部事件可以唤醒MCU。这些事件可以是WKUP引脚的外部中断、RTC闹钟中断等。
    • 在HAL库中,通常可以使用相关函数来使能或禁用这些唤醒源。
  3. 设置停止模式的电压级别

    • 在停止模式下,可以选择不同的电压级别以进一步降低功耗。较低的电压级别通常会增加唤醒时间,但也会减少功耗。
    • 这一设置通常涉及到PWR控制寄存器的配置。
  4. 进入停止模式

    • 当所有准备工作完成后,调用HAL_PWR_EnterSTOPMode函数将MCU置于停止模式。
    • 进入停止模式后,MCU的CPU和大多数外设都会停止工作,只有少数必要的部分保持运行以便快速唤醒。
  5. 等待唤醒事件

    • 在停止模式下,MCU会进入休眠状态,等待唤醒事件的发生。
    • 当WKUP引脚产生外部中断或其他唤醒源触发时,MCU会被唤醒,并从停止模式中恢复。
  6. 处理唤醒事件

    • 一旦MCU被唤醒,需要相应地处理唤醒事件。这可能涉及到清除中断标志、重新配置外设等操作,以便系统正常运行。

5.3、待机模式配置步骤

在这里插入图片描述
在这里插入图片描述
您提供的待机模式配置步骤已经很完整了,以下是对每个步骤的简要解释:

  1. 初始化WKUP为中断触发源

    • 如果需要使用WKUP引脚作为唤醒源,则需要将其配置为外部中断引脚,并初始化外部中断功能。这允许外部事件(例如按键按下)唤醒MCU。
  2. 外设低功耗处理

    • 在进入待机模式之前,您可以选择将某些外设置于低功耗状态,以进一步降低功耗。这是一个可选步骤,根据系统需求和优化考虑而定。
  3. 使能电源时钟

    • 在使用HAL库时,需要确保已经使能了电源时钟,以便能够配置和控制电源相关的功能。您可以使用 __HAL_RCC_PWR_CLK_ENABLE() 函数来实现。
  4. 使能WKUP的唤醒功能

    • 使用 HAL_PWR_EnableWakeUpPin() 函数来使能WKUP引脚的唤醒功能。这一步确保WKUP引脚可以正确地唤醒MCU。
  5. 清除唤醒标记WUF

    • 在进入待机模式之前,通常需要清除WKUP引脚的唤醒标记,以确保不会因为之前的唤醒事件导致误唤醒。您可以使用 __HAL_PWR_CLEAR_FLAG() 函数来清除唤醒标记。
  6. 进入待机模式

    • 最后一步是调用 HAL_PWR_EnterSTANDBYMode() 函数,将MCU置于待机模式。在待机模式下,MCU的主要部分将关闭,只有少数必要的电路保持运行,以便在WKUP引脚触发唤醒时快速恢复。

六、编程实战

在这里插入图片描述
在这里插入图片描述

F1按键输入

pwr.c

#include "./BSP/PWR/pwr.h"
#include "./SYSTEM/usart/usart.h"
#include "./BSP/LED/led.h"

/* 初始化WKUP按键 */
void pwr_wkup_key_init(void)
{
    GPIO_InitTypeDef gpio_init_struct;
    
    PWR_WKUP_GPIO_CLK_ENABLE();                             /* 使能WKUP引脚时钟 */

    gpio_init_struct.Pin = PWR_WKUP_GPIO_PIN;               /* 配置WKUP引脚 */
    gpio_init_struct.Mode = GPIO_MODE_IT_RISING;            /* 中断,上升沿触发 */
    gpio_init_struct.Pull = GPIO_PULLDOWN;                  /* 下拉 */
    gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;          /* 高速 */
    HAL_GPIO_Init(PWR_WKUP_GPIO_PORT, &gpio_init_struct);   /* 初始化WKUP引脚 */

    HAL_NVIC_SetPriority(PWR_WKUP_INT_IRQn, 2, 2);          /* 设置WKUP中断优先级 */
    HAL_NVIC_EnableIRQ(PWR_WKUP_INT_IRQn); 
}

/* WKUP中断处理函数 */
void PWR_WKUP_INT_IRQHandler(void)
{
    HAL_GPIO_EXTI_IRQHandler(PWR_WKUP_GPIO_PIN);  /* 处理WKUP引脚中断 */
}

/* 外部中断回调函数 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    if (GPIO_Pin == PWR_WKUP_GPIO_PIN)
    {
        /* 在此处执行WKUP中断回调的相关操作 */
    }
}

/* 初始化电压监测功能 */
void pwr_pvd_init(void)
{
    PWR_PVDTypeDef pwr_pvd_init_struct;
    
    /* 1. 使能PWR时钟 */
    __HAL_RCC_PWR_CLK_ENABLE();
    
    /* 2. 配置PVD */
    pwr_pvd_init_struct.PVDLevel = PWR_PVDLEVEL_7;                   /* 设置PVD触发电压等级 */
    pwr_pvd_init_struct.Mode = PWR_PVD_MODE_IT_RISING_FALLING;      /* 设置PVD触发模式 */
    HAL_PWR_ConfigPVD(&pwr_pvd_init_struct);                        /* 配置PVD功能 */
    
    /* 3. 使能PVD */
    HAL_PWR_EnablePVD();
    
    /* 4. 设置PVD中断优先级 */
    HAL_NVIC_SetPriority(PVD_IRQn, 2, 2);
    HAL_NVIC_EnableIRQ(PVD_IRQn); 
}

/* PVD中断处理函数 */
void PVD_IRQHandler(void)
{
    HAL_PWR_PVD_IRQHandler();  /* 处理PVD中断 */
}

/* PVD中断回调函数 */
void HAL_PWR_PVDCallback(void)
{
    if (__HAL_PWR_GET_FLAG(PWR_FLAG_PVDO))  /* 电压比PLS设置的还低 */
    {
        printf("PVD Low Voltage \r\n");
        LED1(0);  /* 关闭LED1指示灯 */
    }
    else
    {
        printf("PVD Voltage OK\r\n");
        LED1(1);  /* 打开LED1指示灯 */
    }
}

pwr.h

#ifndef __PWR_H
#define __PWR_H

#include "./SYSTEM/sys/sys.h"

#define PWR_WKUP_GPIO_PORT              GPIOA
#define PWR_WKUP_GPIO_PIN               GPIO_PIN_0
#define PWR_WKUP_GPIO_CLK_ENABLE()      do { __HAL_RCC_GPIOA_CLK_ENABLE(); } while (0)

#define PWR_WKUP_INT_IRQn               EXTI0_IRQn
#define PWR_WKUP_INT_IRQHandler         EXTI0_IRQHandler

void pwr_wkup_key_init(void);  /* 初始化WKUP按键 */
void pwr_pvd_init(void);        /* 初始化电压监测功能 */

#endif

main.c

#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
#include "./BSP/LED/led.h"
#include "./BSP/BEEP/beep.h"
#include "./BSP/KEY/key.h"
#include "./BSP/PWR/pwr.h"

int main(void)
{
    uint8_t key;
    uint8_t t = 0;
    
    HAL_Init();                             /* 初始化HAL库 */
    sys_stm32_clock_init(RCC_PLL_MUL9);     /* 设置时钟, 72Mhz */
    delay_init(72);                         /* 延时初始化 */
    usart_init(115200);                     /* 串口初始化 */
    led_init();                             /* 初始化LED */
    key_init();                             /* 初始化按键 */
    pwr_wkup_key_init();                    /* WKUP引脚初始化 */
    pwr_pvd_init();                         /* PVD配置 */
    
    printf("Enter to LowPower Test \r\n");
    
    while(1)
    {
        key = key_scan(0);                  /* 得到键值 */

        if (key)
        {
            switch (key)
            {
                /* 进入待机模式 */
                case KEY2_PRES:
                
                    /* 使能电源时钟 */
                    __HAL_RCC_PWR_CLK_ENABLE();
                
                    /* 使能WKUP上升沿的唤醒功能 */
                    HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN1);
                
                    /* 清除唤醒标记 */
                    __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
                
                    printf("Enter STANDBY Mode \r\n");
                    
                    HAL_PWR_EnterSTANDBYMode();
                
                    printf("Exit STANDBY Mode \r\n");

                    break;

                /* 进入停止模式 */
                case KEY1_PRES:
                    
                    LED1(0);        /* 点亮绿灯,提示进入停止模式 */
                    
                    printf("Enter STOP Mode \r\n");
                    HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_SLEEPENTRY_WFI);
                    
                    sys_stm32_clock_init(RCC_PLL_MUL9);     /* 重新设置时钟, 72Mhz */
                    HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK_DIV8);
                    HAL_SuspendTick();
                
                    printf("Exit STOP Mode \r\n");
                
                    LED1(1);
                    break;
                
                /* 进入睡眠模式 */
                case KEY0_PRES:
                    
                    printf("Enter SLEEP Mode \r\n");
                    HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
                    printf("Exit SLEEP Mode \r\n");
                
                    break;
            } 
        }
        
        if ((t % 20) == 0)
        {
            LED0_TOGGLE();              /* 每200ms,翻转一次LED0 */
        }

        delay_ms(10);
        t++;   
    }
}

在这里插入图片描述

H750_lowpower_mode源码

pwr.c

#include "./BSP/PWR/pwr.h"
#include "./BSP/LED/led.h"
#include "./BSP/LCD/lcd.h"
#include "./BSP/RTC/rtc.h"


/**
 * @brief       初始化PVD电压监视器
 * @param       pls: 电压等级
 *   @arg       PWR_PVDLEVEL_0,1.95V;  PWR_PVDLEVEL_1,2.1V
 *   @arg       PWR_PVDLEVEL_2,2.25V;  PWR_PVDLEVEL_3,2.4V;
 *   @arg       PWR_PVDLEVEL_4,2.55V;  PWR_PVDLEVEL_5,2.7V;
 *   @arg       PWR_PVDLEVEL_6,2.85V;  PWR_PVDLEVEL_7,使用PVD_IN脚上的电压(与Vrefint比较)
 * @retval      无
 */
void pwr_pvd_init(uint32_t pls)
{
    PWR_PVDTypeDef pvd_handle = {0};

    HAL_PWR_EnablePVD();                                /* 使能PVD时钟 */

    pvd_handle.PVDLevel = pls;                          /* 检测电压级别 */
    pvd_handle.Mode = PWR_PVD_MODE_IT_RISING_FALLING;   /* 使用中断线的上升沿和下降沿双边缘触发 */
    HAL_PWR_ConfigPVD(&pvd_handle);

    HAL_NVIC_SetPriority(PVD_AVD_IRQn, 3 ,3);
    HAL_NVIC_EnableIRQ(PVD_AVD_IRQn);
    HAL_PWR_EnablePVD();                                /* 使能PVD检测 */
}

/**
 * @brief       PVD/AVD中断服务函数
 * @param       无
 * @retval      无
 */
void PVD_AVD_IRQHandler(void)
{
    HAL_PWR_PVD_IRQHandler();
}

/**
 * @brief       PVD/AVD中断服务回调函数
 * @param       无
 * @retval      无
 */
void HAL_PWR_PVDCallback(void)
{
    if (__HAL_PWR_GET_FLAG(PWR_FLAG_PVDO))   /* 电压比PLS所选电压还低 */
    {
        lcd_show_string(30, 130, 200, 16, 16, "PVD Low Voltage!", RED); /* LCD显示电压低 */
        LED1(0);    /* 点亮绿灯, 表明电压低了 */
    }
    else
    {
        lcd_show_string(30, 130, 200, 16, 16, "PVD Voltage OK! ", BLUE);/* LCD显示电压正常 */
        LED1(1);    /* 灭掉绿灯 */
    }
}

/***********************************睡眠模式实验程序*******************************************/

/**
 * @brief       低功耗模式下的按键初始化(用于唤醒睡眠模式/停止模式/待机模式)
 * @param       无
 * @retval      无
 */
void pwr_wkup_key_init(void)
{
    GPIO_InitTypeDef gpio_init_struct;
    
    PWR_WKUP_GPIO_CLK_ENABLE();     /* WKUP时钟使能 */

    gpio_init_struct.Pin = PWR_WKUP_GPIO_PIN;               /* WKUP引脚 */
    gpio_init_struct.Mode = GPIO_MODE_IT_RISING;            /* 中断,上升沿 */
    gpio_init_struct.Pull = GPIO_PULLDOWN;                  /* 下拉 */
    gpio_init_struct.Speed = GPIO_SPEED_FREQ_MEDIUM;        /* 中速 */
    HAL_GPIO_Init(PWR_WKUP_GPIO_PORT, &gpio_init_struct);   /* WKUP引脚初始化 */

    HAL_NVIC_SetPriority(PWR_WKUP_INT_IRQn, 1, 0);          /* 抢占优先级2,子优先级2 */
    HAL_NVIC_EnableIRQ(PWR_WKUP_INT_IRQn); 
}

/**
 * @brief       WK_UP按键 外部中断服务程序
 * @param       无
 * @retval      无
 */
void PWR_WKUP_INT_IRQHandler(void)
{
    HAL_GPIO_EXTI_IRQHandler(PWR_WKUP_GPIO_PIN);
}

/**
 * @brief       进入CPU睡眠模式
 * @param       无
 * @retval      无
 */
void pwr_enter_sleep(void)
{
    HAL_SuspendTick();  /* 暂停滴答时钟,防止通过滴答时钟中断唤醒 */

    HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI); /* 进入睡眠模式 */
}

/**
 * @brief       外部中断回调函数
 * @param       GPIO_Pin:中断线引脚
 * @note        此函数会被PWR_WKUP_INT_IRQHandler()调用
 * @retval      无
 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    if (GPIO_Pin == PWR_WKUP_GPIO_PIN)
    {
        /* HAL_GPIO_EXTI_IRQHandler()函数已经为我们清除了中断标志位,所以我们进了回调函数可以不做任何事 */
    }
}

/***********************************停止模式实验程序*******************************************/

/**
 * @brief       进入停止模式
 * @param       无
 * @retval      无
 */
void pwr_enter_stop(void)
{
    sys_stm32_clock_init(200, 2, 2, 4); /* 设置时钟,400Mhz,降频 */

    /* 当SVOS3进入停止模式时,设置稳压器为低功耗模式,等待中断唤醒 */
    HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
}

/***********************************待机模式实验程序*******************************************/

/**
 * @brief       进入待机模式
 * @param       无
 * @retval      无
 */
void pwr_enter_standby(void)
{
    __HAL_GPIO_EXTI_CLEAR_IT(PWR_WKUP_GPIO_PIN);    /* 清除WKUP上的中断标志位 */

    HAL_PWR_DisableWakeUpPin(PWR_WAKEUP_PIN1_HIGH); /* 禁止唤醒 */

    __HAL_RCC_BACKUPRESET_FORCE();                  /* 复位备份区域 */
    HAL_PWR_EnableBkUpAccess();                     /* 后备区域访问使能 */

    __HAL_PWR_CLEAR_FLAG(PWR_FLAG_SB);
    __HAL_RTC_WRITEPROTECTION_DISABLE(&g_rtc_handle);/* 关闭RTC写保护 */

    /* 关闭RTC相关中断,可能在RTC实验打开了 */
    __HAL_RTC_WAKEUPTIMER_DISABLE_IT(&g_rtc_handle, RTC_IT_WUT);
    __HAL_RTC_TIMESTAMP_DISABLE_IT(&g_rtc_handle, RTC_IT_TS);
    __HAL_RTC_ALARM_DISABLE_IT(&g_rtc_handle, RTC_IT_ALRA | RTC_IT_ALRB);

    /* 清除RTC相关中断标志位 */
    __HAL_RTC_ALARM_CLEAR_FLAG(&g_rtc_handle, RTC_FLAG_ALRAF | RTC_FLAG_ALRBF);
    __HAL_RTC_TIMESTAMP_CLEAR_FLAG(&g_rtc_handle, RTC_FLAG_TSF); 
    __HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(&g_rtc_handle, RTC_FLAG_WUTF);

    __HAL_RCC_BACKUPRESET_RELEASE();                 /* 备份区域复位结束 */
    __HAL_RTC_WRITEPROTECTION_ENABLE(&g_rtc_handle); /* 使能RTC写保护 */

    HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN1_HIGH);   /* 使能KEY_UP引脚的唤醒功能 */
    HAL_PWR_EnterSTANDBYMode();                      /* 进入待机模式 */
}

pwr.h

#ifndef __PWR_H
#define __PWR_H

#include "./SYSTEM/sys/sys.h"


/******************************************************************************************/
/* PWR WKUP 按键 引脚和中断 定义 
 * 我们通过WK_UP按键唤醒 MCU,  因此必须定义这个按键及其对应的中断服务函数 
 */

#define PWR_WKUP_GPIO_PORT              GPIOA
#define PWR_WKUP_GPIO_PIN               GPIO_PIN_0
#define PWR_WKUP_GPIO_CLK_ENABLE()      do{ __HAL_RCC_GPIOA_CLK_ENABLE(); }while(0)   /* PA口时钟使能 */
  
#define PWR_WKUP_INT_IRQn               EXTI0_IRQn
#define PWR_WKUP_INT_IRQHandler         EXTI0_IRQHandler

/******************************************************************************************/



void pwr_pvd_init(uint32_t pls);    /* PVD电压检测初始化函数 */
void pwr_wkup_key_init(void);       /* 唤醒按键初始化 */
void pwr_enter_sleep(void);         /* 进入睡眠模式 */
void pwr_enter_stop(void);          /* 进入停止模式 */
void pwr_enter_standby(void);       /* 进入待机模式 */

#endif

main.c

#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
#include "./USMART/usmart.h"
#include "./BSP/MPU/mpu.h"
#include "./BSP/LED/led.h"
#include "./BSP/LCD/lcd.h"
#include "./BSP/PWR/pwr.h"
#include "./BSP/KEY/key.h"


int main(void)
{
    uint8_t t = 0;
    uint8_t key = 0;

    sys_cache_enable();                 /* 打开L1-Cache */
    HAL_Init();                         /* 初始化HAL库 */
    sys_stm32_clock_init(240, 2, 2, 4); /* 设置时钟, 480Mhz */
    delay_init(480);                    /* 延时初始化 */
    usart_init(115200);                 /* 串口初始化为115200 */
    mpu_memory_protection();            /* 保护相关存储区域 */
    led_init();                         /* 初始化LED */
    lcd_init();                         /* 初始化LCD */
    key_init();                         /* 初始化按键 */
    pwr_wkup_key_init();                /* 唤醒按键初始化 */
    
    lcd_show_string(30, 50, 200, 16, 16, "STM32", RED);
    lcd_show_string(30, 70, 200, 16, 16, "STANDBY TEST", RED);
    lcd_show_string(30, 90, 200, 16, 16, "ATOM@ALIENTEK", RED);
    lcd_show_string(30, 110, 200, 16, 16, "KEY0:Enter STOP MODE", RED);
    lcd_show_string(30, 130, 200, 16, 16, "KEY1:Enter STANDBY MODE", RED);
    lcd_show_string(30, 150, 200, 16, 16, "KEY_UP:Exit LOW MODE", RED);
    
    printf("Enter to LowPower Test \r\n");
    
    while (1)
    {
        key = key_scan(0);      /* 得到键值 */
        
        if (key)
        {
            switch (key)
            {
                case KEY1_PRES:     /* 进入待机模式 */
                    printf("Enter STANDBY Mode \r\n");
                    pwr_enter_standby();
                    /* 从待机模式唤醒相当于系统重启(复位), 因此不会执行到这里 */
                    printf("Exit STANDBY Mode \r\n");
                    break;
                
                case KEY0_PRES:     /* 进入停止模式 */
                    LED1(0);        /* 点亮绿灯,提示进入停止模式 */ 
                    printf("Enter STOP Mode\r\n");
                    pwr_enter_stop();
                    /* 从停止模式唤醒, 需要重新设置系统时钟, 480Mhz */
                    sys_stm32_clock_init(240, 2, 2, 4);
                    printf("Exit STOP Mode \r\n");
                    LED1(1);        /* 关闭绿灯,提示退出停止模式 */
                    break;
            }
        }

        if ((t % 20) == 0)
        {
            LED0_TOGGLE();         /* 每200ms,翻转一次LED0 */
        }

        delay_ms(10);
        t++;
    }
}

在这里插入图片描述

七、总结

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 24
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
物联网的发展越来越迅速,低功耗电源管理是其非常重要的一部分。基于STM32低功耗电源管理方案可以有效延长设备的待机时间,提升用户体验。 首先,我们需要在STM32的代码程序实现低功耗电源管理stop睡眠模式的测试。具体流程如下: 1. 配置低功耗模式 首先在main函数配置功耗模式为stop模式,如下所示: RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI); 2. 配置外部唤醒配置低功耗模式后,我们需要配置外部唤醒,以便在接收到信号后唤醒设备。配置外部唤醒的代码如下: void EXTI_Configuration(void) { EXTI_InitTypeDef EXTI_InitStructure; /* Connect EXTI Line14 to PC14 pin */ GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource14); /* Configure EXTI Line14 */ EXTI_InitStructure.EXTI_Line = EXTI_Line14; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStructure); } 3. 进入低功耗模式 配置完外部唤醒后,我们进入低功耗模式,等待外部唤醒信号。进入低功耗模式的代码如下: void System_Enter_Stop(void) { /*!< System Clock is HSI = 16 MHz */ /* Disable USB clock */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_USB, DISABLE); /* Disable all used peripherals */ RCC_AHBPeriphClockCmd(0, DISABLE); RCC_APB2PeriphClockCmd(0, DISABLE); RCC_APB1PeriphClockCmd(0, DISABLE); /* Disable systick and set it to the lowest priority */ SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk; NVIC_SetPriority(SysTick_IRQn, 0x0F); /* Enter Stop Mode */ PWR_WakeUpPinCmd(ENABLE); PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI); } 通过以上代码实现,我们就可以对基于STM32低功耗电源管理stop睡眠模式进行测试,从而验证其实际效果。除此之外,还需要注意一些代码规范和文档书写,以确保项目开发的顺利进行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

咖喱年糕

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

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

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

打赏作者

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

抵扣说明:

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

余额充值