STM32 的 PWR(Power Control)外设 是用于管理微控制器电源模式和外设电源控制的模块。通过 PWR 外设,可以实现低功耗模式、电压调节、备份域控制等功能,从而优化系统的功耗和性能。

stm32内部电源框图

电源区域

  1. VDD 供电区(主电源)

  2. 主要用于为 CPU 核心内存数字外设 提供电力。
  3. VDD 通常是 3.3V,为单片机的所有数字部分提供电源。
  4. 该区域还包括 电压调节器,用于确保提供稳定的电源给各个模块。
  5. VSSA 和 VDDA(模拟部分电源)

  6. VSSA模拟地,用于提供模拟部分的参考电压。
  7. VDDA 用于为模拟模块供电,如 A/D 转换器温度传感器 等。
  8. 该部分通常由 外部稳压电源 提供 2.4V 至 3.6V 的电源。
  9. 1.8V 供电区

  10. 该部分为一些低功耗模块提供 1.8V 电压,主要用于 CPU 核心低功耗寄存器 和一些特定的外设。
  11. 在大多数现代微控制器中,1.8V 电源用于 低功耗操作,减少能耗。
  12. 低电压检测电路

  13. 用于监控电源电压是否过低。当电压低于一定值时,系统可能会执行复位或其他保护机制,防止因电压不稳定导致的异常操作。

时钟部分

  1. PLL(锁相环)

  2. 用于提供更高频率的时钟,支持更快的处理速度。
  3. 通常,STM32 系列单片机使用 PLL 来从较低频率的输入时钟生成更高的主时钟频率(例如从 8 MHz 外部晶振生成 72 MHz)。
  4. LSE(低速外部晶体振荡器)

  5. 提供给 RTC(实时时钟) 等低速外设一个稳定的时钟源,通常为 32.768 kHz
  6. 这个时钟源用于处理低功耗操作,如 待机模式定时器操作

备用电源

  1. V_BAT(备用电池)

  2. 用于为 RTC其他低功耗外设 提供电力,确保这些模块在主电源关闭时依然能够工作。
  3. 这通常是由 CR2032 电池 或类似电池提供的。
  4. RCC BDCR 寄存器

  5. 这个寄存器管理 时钟源,包括 LSERTC 等外设的时钟。

CPU 和存储器

  • CPU 核心:执行主要的计算和逻辑操作。
  • 存储器:包括 闪存SRAM 等存储模块,用于存储程序代码和数据。
  • I/O 电路

  • 用于 外部输入输出 信号的处理。
  • 该电路通常包括 GPIO 引脚,用于连接外部设备,如按键、LED、传感器等。
  • PWR 外设的主要功能
    1. 电源模式管理:
       – 支持多种低功耗模式,如眠模式、停止模式和待机模式。
       – 通过配置 PWR 寄存器,可以进入或退出这些模式。

    2. 电压调节:
       – 支持动态电压调节(DVS),通过调整核心电压来优化功耗和性能。

    PWR 上电复位与掉电复位

    PWR(Power)模块在 STM32 系列微控制器中主要用于管理电源相关的操作,例如上电、掉电复位、低功耗模式等。电源模块控制着系统的电源源供给,涉及到 上电复位掉电复位 两种状态。

    1. 上电复位 (Power-On Reset, POR)

    上电复位是指单片机在接通电源时,系统自动进行复位的过程。上电时复位的作用是确保芯片的状态从不确定的状态恢复到已知的初始状态。上电复位通常由内部的复位电路完成,不需要外部触发。其主要作用包括:

  • 确保系统电压稳定,避免不稳定电压引起的异常操作。
  • 恢复芯片内部的寄存器值至初始状态,避免因为未定义状态引发的错误。
  • 在 STM32 系列中,PWR模块中的 POR 机制通常由电源电压(VDD)稳定后触发复位信号。

    2. 掉电复位 (Brownout Reset, BOR)

    掉电复位用于监控电源电压的稳定性。如果电源电压跌至一个设定的阈值以下,系统将自动复位,以避免在电压不稳定时继续工作。BOR 保护功能可以防止系统在低电压下继续运行,避免导致数据错误或系统异常。掉电复位的特性:

  • 如果电压低于设定阈值(比如 2.7V),系统将触发复位。
  • 该机制可以保护设备在电源电压下降时不产生错误,防止运行在不可靠的电压下。
  • STM32 提供了一个 BOR 电压检测器,可以设置为不同的阈值,用户可以根据需要启用或禁用该功能。

    总结
  • 上电复位 (POR) 是在电源首次接通时自动触发的,确保系统从一个已知状态开始。
  • 掉电复位 (BOR) 是当电源电压低于一定阈值时触发的,保证系统不会在电压不稳定时继续运行,防止出现错误。
  • PWR 可编程电压电测器 (PVD)

    PVD(Programmable Voltage Detector,可编程电压电测器)是 STM32 微控制器中的一个重要功能,它用于监测芯片的电源电压,并在电压超出设定范围时触发中断或复位。PVD 主要用于在电压过低时保护系统,避免因电压不稳定而导致的数据丢失或系统不稳定。

    PVD 的功能和作用

    PVD 主要有以下功能:

    1. 电压监测

    2. PVD 可监测供电电压是否超出预定范围,确保设备在稳定的电压范围内运行。
    3. 监测电源电压下降到指定阈值时,进行保护操作。
    4. 可编程阈值

    5. PVD 允许用户设置电压阈值(例如 2.7V、2.8V 等),并在电压低于该阈值时触发相关操作。
    6. 保护系统

    7. 如果电源电压降到低于预设阈值,PVD 会触发复位或者中断,以保护系统不在不可靠的电压下继续工作,避免潜在的数据损坏或异常行为。
    8. 启用和禁用功能

    9. 用户可以根据需要启用或禁用 PVD 功能。
    10. 通过配置寄存器,可以设定触发电压的阈值,并选择中断方式。

    PVD(可编程电压电测器)工作原理详细解释:

    PVD 是 STM32 系列芯片中的一个重要电源管理功能,主要用于监测系统的电源电压,确保系统在稳定的电压下运行。具体来说,PVD 的工作原理如下:

    1. 电压监测

  • 电压阈值设置:PVD 允许用户设置一个电压阈值(例如 2.4V、2.7V、3.0V 等)。当系统电源电压下降到这个阈值以下时,PVD 会触发事件。
  • 电压实时监测:PVD 会实时监测 VDD 电压,一旦电压低于设置的阈值,它会做出反应。
  • 2. 触发事件(复位或中断)

    当电源电压下降到设定的阈值以下时,PVD 会触发以下两种可能的事件之一:

  • 复位:系统自动复位,以确保系统从一个已知、稳定的状态重新启动。复位后,系统会重新初始化所有外设和内存,确保没有电压不稳定导致的异常。
  • 中断:如果用户启用了中断,PVD 会触发中断,这样系统可以在中断服务程序中执行相应的处理。中断通常用于处理如进入低功耗模式、停止某些外设等操作。
  • 3. 低功耗模式控制

    在电压下降时,PVD 还可以配合 低功耗模式 使用,帮助系统尽量减少功耗。具体操作包括:

  • 进入低功耗模式:当 PVD 触发事件时,系统可以配置为自动进入低功耗模式(如 Sleep 模式)。这有助于节省电能,延长电池寿命。
  • 关闭外设:系统也可以选择关闭某些不重要的外设(如未使用的 GPIO、外设接口等),从而进一步降低功耗。
  • 4. 系统复位后恢复稳定

    PVD 可以确保在电压过低时系统能快速恢复到安全状态。具体来说:

  • 恢复电压稳定:一旦电压恢复到正常水平,PVD 会停止触发复位或中断,系统可以继续正常工作。
  • 重新启动所有功能:当 PVD 触发复位后,系统会重新启动,所有外设和数据会恢复到初始状态。这是为了避免因电压不稳定引起的系统运行错误。
  • 5. 与其他电源管理功能的配合

    PVD 通常与 STM32 的其他电源管理功能结合使用:

  • 独立看门狗(IWDG):如果系统出现异常或复位未能正常处理,IWDG 可以确保系统在一定时间内恢复正常。
  • 电压检测:系统可能配备其他电压检测电路,以确保电源电压始终在预设范围内。
  • 工作流程

    1. PVD 阈值设定:首先,用户通过编程设置电压阈值,例如 2.7V。
    2. 实时监控:PVD 会不断监测系统电源电压。
    3. 电压低于阈值:当电压低于 2.7V 时,PVD 会触发预设的操作(复位或中断)。
    4. 触发操作
    5. 如果选择了复位,芯片将重新启动,恢复到安全状态。
    6. 如果选择了中断,系统会执行中断服务程序,通常会进行电压恢复处理、进入低功耗模式或关闭非必要外设。
    7. 电压恢复正常:当电源电压恢复到正常值时,PVD 监控停止,系统继续正常运行
    PVD 的配置:

    在 STM32 微控制器中,PVD 的配置通常是通过编程寄存器来完成的。以下是 PVD 配置的几个常用步骤:

    1. 选择阈值电压:可以通过 PVDCR 寄存器配置阈值电压(如 2.4V、2.7V 等)
    2. 启用 PVD:通过设置相应的控制寄存器,启用 PVD 功能。
    3. 配置中断(可选):如果需要,可以设置 PVD 中断,使得系统在触发 PVD 时可以进行相关处理。
    PVD 配置示例:
    // 启用 PVD 功能并设置阈值为 2.7V
    PWR_PVDLevelConfig(PWR_PVDLevel_2); // 设置 PVD 阈值为 2.7V
    PWR_PVDCmd(ENABLE); // 启用 PVD
    
    总结

    PVD(可编程电压电测器)是一个非常重要的功能,它能够监测电源电压并保护系统在电压异常时采取相应措施。通过设置阈值,可以在电压降到设定值以下时触发中断或复位,从而避免电压不稳定导致的系统错误或数据丢失。

    低功耗模式:

    STM32 的低功耗模式概述

    在 STM32 微控制器中,低功耗模式主要有以下几种:

    1. 睡眠模式(Sleep Mode)
    2. 停机模式(Stop Mode)
    3. 待机模式(Standby Mode)

    1. 睡眠模式(Sleep Mode)

    睡眠模式是 STM32 的最轻功耗模式,主要用于系统处于空闲状态时,但仍然需要保持快速响应。

    工作原理
  • 核心停止:在睡眠模式下,CPU 核心停止工作,但 外设 仍然可以正常工作。
  • 时钟源选择:外设可以使用不同的时钟源(例如 HSE、HSI、PLL等),而时钟源仍然在运行,所以响应时间较短。
  • 功耗
  • 功耗较低,但不如其他模式低,因为外设时钟仍然保持运行。
  • 用于需要保持外设运行但不需要 CPU 执行计算任务的场景,如时钟信号生成、通信协议等待等。
  • 唤醒方式
  • 通过中断或外部事件唤醒,例如 GPIO 引脚状态变化、外部中断、定时器中断等。
  • 进入方式:通过设置 SLEEP-NOWSLEEP-ON-EXIT 进入。SLEEP-NOW 表示立即进入睡眠模式,SLEEP-ON-EXIT 则是在当前指令执行完后进入睡眠模式。
  • 唤醒:任何中断可以唤醒睡眠模式,唤醒事件会触发 CPU 和其他时钟恢复正常。
  • 电源影响
  • 对于 1.8V 区域:CPU 的时钟被暂停,但其他时钟和 ADC 的时钟不受影响。
  • 对于 VDD 区域:时钟保持开启,电压调节器保持开启,系统能够快速恢复。
  • 2. 停机模式(Stop Mode)

    停机模式是一种较低功耗的模式,适用于需要尽可能节省电池能量的场景。

    工作原理
  • CPU 核心停止:与睡眠模式类似,CPU 停止工作。
  • 外设关闭:停机模式下,系统时钟源停止,大部分外设停止工作。但是一些 特定外设(如 RTC)仍然可以工作。
  • 内部时钟关闭:在此模式下,主时钟源和 PLL 被关闭,系统进入极低功耗状态。
  • 功耗
  • 功耗进一步降低,但需要较长的唤醒时间,因为时钟需要重新启动。
  • 唤醒方式
  • 通过外部中断、定时器中断、RTC 中断等事件唤醒。
  • 唤醒速度相对较快,但仍然需要一些时间来重新启动时钟和外设。
  • 进入方式:通过设置 PDDSSLEEPDEEP 位进入。在此模式下,CPU 核心停止工作,整个系统停止所有活动,进入低功耗状态。
  • 唤醒:外部事件或者 WKUP 引脚触发时可以唤醒。
  • 电源影响
  • 对于 1.8V 区域:停机模式下,所有时钟都被关闭。
  • 对于 VDD 区域:关闭 HSI 和 HSE 振荡器,电压调节器关闭,系统处于低功耗状态,唤醒时需要一定时间恢复。
  • 3. 待机模式(Standby Mode)

    待机模式是 STM32 微控制器的 最低功耗模式,适用于设备长时间处于休眠状态,但需要保证某些功能(如 RTC、备份寄存器)持续工作。

    工作原理
  • CPU 和所有外设停止工作:与停机模式不同,待机模式下 CPU 和所有外设(包括内部时钟源)都停止工作,几乎所有模块都被关闭。
  • 保持最低功耗:只有一些核心模块(如 RTC、低速外部振荡器 LSE、备份寄存器)继续工作。
  • 功耗
  • 最低功耗,适合长时间待机的应用场景。
  • 唤醒时间较长,通常在 几毫秒几十毫秒
  • 唤醒方式
  • 唤醒可以通过 外部中断RTC复位 唤醒。
  • 由于需要重新启动时钟,唤醒过程相对较慢。
  • 进入方式:通过设置 PDDSSLEEPDEEP 位进入,结合 WKUP 引脚触发。
  • 唤醒:通过外部中断,WKUP 引脚或者 NRST 引脚触发时可以恢复。
  • 电源影响
  • 对于 1.8V 区域:完全关闭所有时钟。
  • 对于 VDD 区域:关闭 HSI 和 HSE 振荡器,电压调节器关闭,系统进入最低功耗状态。
  • PWR 低功耗模式的选择和配置

    在 STM32 中,可以通过 PWR 控制寄存器来配置和启用不同的低功耗模式。具体的选择取决于系统的需求:需要较低的功耗还是较短的响应时间。

    配置步骤
    1. 选择低功耗模式:根据应用需求选择睡眠模式、停机模式或待机模式。
    2. 配置外设:配置是否启用需要保留工作的外设(如 RTC、外部中断等)。
    3. 使能相应的模式:通过 PWR_CR 寄存器配置并使能所选的低功耗模式。
    4. 唤醒配置:配置唤醒条件,例如定时器中断、外部中断等。
    示例代码(进入睡眠模式)
    // 配置 STM32 进入睡眠模式
    void Enter_Sleep_Mode(void)
    {
        // 禁用不必要的外设时钟,降低功耗
        // 使能睡眠模式
        PWR_EnterSleepMode(PWR_SLEEPEntry_WFI);
    }
    
    示例代码(进入停机模式)
    // 配置 STM32 进入停机模式
    void Enter_Stop_Mode(void)
    {
        // 禁用不必要的外设时钟,进入停机模式
        PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);
    }
    
    示例代码(进入待机模式)
    // 配置 STM32 进入待机模式
    void Enter_Standby_Mode(void)
    {
        // 进入待机模式
        PWR_EnterSTANDBYMode();
    }
    

    总结

  • 睡眠模式 是最轻的低功耗模式,系统会停止 CPU 核心的工作,但其他外设时钟和 ADC 仍然工作,唤醒速度较快。
  • 停机模式 可以关闭更多的外设时钟,达到更低的功耗,但唤醒速度较慢。
  • 待机模式 是最低功耗模式,几乎所有的时钟和外设都关闭,唤醒时间最慢。
  • 3. 备份域控制:
       – 管理备份域(Backup Domain)的电源,包括备份寄存器(Backup Registers)和 RTC(实时时钟)。
       – 在 V<sub>BAT</sub> 模式下,备份域可以由电池供电。

    4. 唤醒机制:
       – 提供多种唤醒源(如外部中断、RTC 闹钟等),用于从低功耗模式唤醒。

    5. 电源电压监测:
       – 提供电源电压监测功能(PVD,Programmable Voltage Detector),用于检测电源电压是否低于设定阈值。

    PWR 外设的主要寄存器
    1. PWR_CR(Power Control Register):
       – 用于配置低功耗模式、电压调节和电源电压监测。

    2. PWR_CSR(Power Control/Status Register):
       – 用于查看电源状态(如是否处于低功耗模式)和清除唤醒标志。

    3. PWR_CR2(Power Control Register 2):
       – 用于配置动态电压调节和备份域控制。

    4. PWR_CR3(Power Control Register 3):
       – 用于配置唤醒引脚和低功耗模式下的外设行为。

    5. PWR_CR4(Power Control Register 4):

     

    1修改主频: 通过在system_stm32f10x.c文件中修改主频参数来调整时间

     OLED_Init();
    	OLED_ShowString (1,1,"sysytemclock:");
    	OLED_ShowNum (2,1,SystemCoreClock ,8);
    		while(1)
    		{
        OLED_ShowString (3,1,"ruing");
        		delay_ms (500);
      OLED_ShowString (3,1,"     ");
      delay_ms (500);			
    			
        }
    
    
    
        
    #if defined (STM32F10X_LD_VL) || (defined STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
    /* #define SYSCLK_FREQ_HSE    HSE_VALUE */
     #define SYSCLK_FREQ_24MHz  24000000
    #else
    /* #define SYSCLK_FREQ_HSE    HSE_VALUE */
    /* #define SYSCLK_FREQ_24MHz  24000000 */ 
    /*#define SYSCLK_FREQ_36MHz  36000000 */
    /* #define SYSCLK_FREQ_48MHz  48000000 */
    /* #define SYSCLK_FREQ_56MHz  56000000 */
    #define SYSCLK_FREQ_72MHz  72000000
    #endif
    

    2睡眠模式下的利用串口收发数据并唤醒睡眠模式:

    1初始化USART

    2开启接受中断使能

    3在主函数whie(1)循环里面接受上位机发送回来的数据

    4在OLDE上显示数据,循环显示"runing"

    4进入睡眠模式后再显示数据,循环显示"runing"

    uint32_t srambuff[SIZEOF];
    uint16_t  num;
    float distance;
    int main(void){
        uint8_t  Data;
    	  Usart_Init();
        OLED_Init();
    	  OLED_ShowString (1,1,"RXData:");
    
    		while(1)
    		{
    			uint16_t Datat;
         if(Check_myflag()==1){
    			  Data=USART_Return();
    			 serval_sendbyte( Data);
    			 OLED_ShowNum (1,8, Data,2);
    		 }
    			OLED_ShowString (2,1,"ruing");
    			 delay_ms(100);
    			OLED_ShowString (2,1,"   ");
    			 delay_ms(100);
    			__WFI ();
    			 
    		 }
    			
        }
    
    #define __enable_fault_irq                __enable_fiq
    #define __disable_fault_irq               __disable_fiq
    
    #define __NOP                             __nop
    #define __WFI                             __wfi
    #define __WFE                             __wfe
    #define __SEV                             __sev
    #define __ISB()                           __isb(0)
    #define __DSB()                           __dsb(0)
    #define __DMB()                           __dmb(0)
    #define __REV                             __rev
    #define __RBIT                            __rbit
    #define __LDREXB(ptr)                     ((unsigned char ) __ldrex(ptr))
    #define __LDREXH(ptr)                     ((unsigned short) __ldrex(ptr))
    #define __LDREXW(ptr)                     ((unsigned int  ) __ldrex(ptr))
    #define __STREXB(value, ptr)              __strex(value, ptr)
    #define __STREXH(value, ptr)              __strex(value, ptr)
    #define __STREXW(value, ptr)              __strex(value, ptr)
    uint16_t  GEtDatat;
    uint16_t  myflag;
    void Usart_Init()
    {
    	//配置GPIO和USART的时钟
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE );
    	  RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE );
    	 //配置关于USART的TX的GPIO结构体
    	 GPIO_InitTypeDef usartgpio_Initsturt;
    	 usartgpio_Initsturt.GPIO_Mode =GPIO_Mode_AF_PP ;
    	 usartgpio_Initsturt .GPIO_Pin =GPIO_Pin_9 ;
    	 usartgpio_Initsturt .GPIO_Speed =GPIO_Speed_50MHz;
    	 GPIO_Init(GPIOA,&usartgpio_Initsturt);
    	  //配置关于USART的RX的GPIO结构体
    	 usartgpio_Initsturt .GPIO_Mode = GPIO_Mode_IN_FLOATING;
    	 usartgpio_Initsturt .GPIO_Pin = GPIO_Pin_10 ;
    	GPIO_Init(GPIOA,&usartgpio_Initsturt);
    	 //配置usart的结构体
    	 USART_InitTypeDef usart_Initsturt;
    	 usart_Initsturt .USART_BaudRate =9600;
    	 usart_Initsturt .USART_HardwareFlowControl =USART_HardwareFlowControl_None;
    	 usart_Initsturt .USART_Mode = USART_Mode_Rx |USART_Mode_Tx  ;
    	 usart_Initsturt .USART_Parity = USART_Parity_No ;  
    	 usart_Initsturt .USART_StopBits =USART_StopBits_1;
    	 usart_Initsturt .USART_WordLength =USART_WordLength_8b ;
    	 USART_Init(USART1, &usart_Initsturt);
    	 //USART_ITConfig(USART1, USART_IT_RXNE,ENABLE );//NVIC中断输出使能
       //NVIC_Configuration();//配置NVIC中断使能函数
    	 USART_Cmd(USART1, ENABLE);//使能USART函数
    	USART_ITConfig(USART1,USART_IT_RXNE, ENABLE );
    }
    
    
       void NVIC_Configuration()
    	 {
    	  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    		 NVIC_InitTypeDef NVIC_INit;
    		 NVIC_INit.NVIC_IRQChannel =USART1_IRQn  ;
    		 NVIC_INit .NVIC_IRQChannelCmd =ENABLE ;
    		 NVIC_INit .NVIC_IRQChannelPreemptionPriority =1;
    		 NVIC_INit .NVIC_IRQChannelSubPriority =1;
    		 NVIC_Init( &NVIC_INit);//初始化NVIC
    	 }
    	 
    	 void serval_sendbyte(uint8_t Data)
    	 {
    		 USART_SendData( USART1,Data);
    		 while(USART_GetITStatus(USART1,USART_IT_TXE)==RESET );
    		 
    		 
    	 }uint16_t  USART_Return(void )
    	{
    		return  GEtDatat;
    		
    	}
    	
    	
    uint16_t  Check_myflag()
    {
    	if( myflag==1)
    	{
    		myflag=0;
    		return 1;
    	}
    	  else{
    		return 0;
    		}
    
    }
    	

    3低功耗停机模式下利用外部中断对对射式传感器进行数据采集并唤醒该模式:

    1初始化外部中断以及对应引脚的GPIO

    2编写中断服务函数,对对射式传感器进行数据采集,并返回采集的值

    3初始化PWR时钟,配置PWR进入低功耗停机模式,

    4在主函数里面进行数据采集显示在OLED屏上并唤醒低功耗模式观察现象

    float distance;
    int main(void){
        uint8_t  Data;
    	  Usart_Init();
        OLED_Init();
    	 exti_sensior_Init();
    	RCC_APB1PeriphClockCmd( RCC_APB1Periph_PWR, ENABLE);
    	  OLED_ShowString (1,1,"Count:");
    
    		while(1)
    		{
    			
    	
    		
    			 OLED_ShowNum (1,8,  Count_Set(),2);
    		 
    			OLED_ShowString (2,1,"ruing");
    			 delay_ms(100);
    			OLED_ShowString (2,1,"   ");
    			 delay_ms(100);
    			
    			 PWR_EnterSTOPMode(PWR_Regulator_ON, PWR_STOPEntry_WFI);
    		 }
    			
        }
    
    

    4利用RTC唤醒PWR低功耗待机模式:

    1. 初始化 RTC:配置 RTC 时钟源,设置时间和日期,使能 RTC 闹钟功能。
    2. 配置 PWR:使能 PWR 和 BKP 外设时钟,设置 RTC 闹钟时间,进入待机模式。
    3. RTC 闹钟中断处理:当 RTC 闹钟触发时,唤醒系统。
    4. #include "stm32f10x.h"
      
      // 函数声明
      void RTC_Configuration(void);
      void NVIC_Configuration(void);
      void PWR_Configuration(void);
      
      // 主函数
      int main(void)
      {
          // 配置NVIC
          NVIC_Configuration();
          // 配置RTC
          RTC_Configuration();
          // 配置PWR
          PWR_Configuration();
      
          while (1)
          {
              // 进入待机模式
              PWR_EnterSTANDBYMode();
          }
      }
      
      // 配置RTC
      void RTC_Configuration(void)
      {
          NVIC_InitTypeDef NVIC_InitStructure;
          RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
          PWR_BackupAccessCmd(ENABLE);
      
          // 复位备份区域
          BKP_DeInit();
      
          // 使能LSE
          RCC_LSEConfig(RCC_LSE_ON);
          while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
          {
          }
      
          // 选择RTC时钟源
          RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
          RCC_RTCCLKCmd(ENABLE);
      
          // 等待RTC寄存器同步
          RTC_WaitForSynchro();
      
          // 等待最近一次对RTC寄存器的写操作完成
          RTC_WaitForLastTask();
      
          // 设置RTC预分频值
          RTC_SetPrescaler(32767);
          RTC_WaitForLastTask();
      
          // 配置RTC闹钟中断
          NVIC_InitStructure.NVIC_IRQChannel = RTCAlarm_IRQn;
          NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
          NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
          NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
          NVIC_Init(&NVIC_InitStructure);
      
          // 使能RTC闹钟中断
          RTC_ITConfig(RTC_IT_ALR, ENABLE);
          RTC_WaitForLastTask();
      
          // 设置RTC闹钟时间(这里设置为10秒后)
          RTC_SetAlarm(RTC_GetCounter() + 10);
          RTC_WaitForLastTask();
      }
      
      // 配置NVIC
      void NVIC_Configuration(void)
      {
          NVIC_InitTypeDef NVIC_InitStructure;
      
          // 配置PVD中断
          NVIC_InitStructure.NVIC_IRQChannel = PVD_IRQn;
          NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
          NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
          NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
          NVIC_Init(&NVIC_InitStructure);
      
          // 配置RTC闹钟中断
          NVIC_InitStructure.NVIC_IRQChannel = RTCAlarm_IRQn;
          NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
          NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
          NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
          NVIC_Init(&NVIC_InitStructure);
      }
      
      // 配置PWR
      void PWR_Configuration(void)
      {
          // 使能PWR和BKP外设时钟
          RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
      
          // 允许访问备份区域
          PWR_BackupAccessCmd(ENABLE);
      }
      
      // RTC闹钟中断处理函数
      void RTCAlarm_IRQHandler(void)
      {
          if (RTC_GetITStatus(RTC_IT_ALR) != RESET)
          {
              // 清除RTC闹钟中断标志
              RTC_ClearITPendingBit(RTC_IT_ALR);
              RTC_WaitForLastTask();
      
              // 清除PWR唤醒标志
              PWR_ClearFlag(PWR_FLAG_WU);
          }
      }

    5. RTC_Configuration函数
    6. 使能 PWR 和 BKP 外设时钟,并允许访问备份区域。
    7. 复位备份区域,使能 LSE(低速外部时钟)作为 RTC 时钟源。
    8. 配置 RTC 预分频值,使 RTC 时钟频率为 1Hz。
    9. 配置 RTC 闹钟中断,设置闹钟时间为当前时间加上 10 秒。
    10. NVIC_Configuration函数
    11. 配置 PVD 和 RTC 闹钟中断的优先级,并使能这两个中断。
    12. PWR_Configuration函数
    13. 使能 PWR 和 BKP 外设时钟,允许访问备份区域。
    14. RTCAlarm_IRQHandler函数
    15. 处理 RTC 闹钟中断,清除中断标志和 PWR 唤醒标志。
    16. main函数
    17. 调用上述配置函数,然后进入待机模式,等待 RTC 闹钟中断唤醒。

    作者:想要成为糕手。

    物联沃分享整理
    物联沃-IOTWORD物联网 » STM32电源控制详解

    发表回复