当前位置: 首页 > ops >正文

STM32——PWR

一、PWR

1.1PWR简介

  • PWRPower Control)电源控制

  • PWR负责管理STM32内部的电源供电部分,可以实现可编程电压监测器和低功耗模式的功能

  • 可编程电压监测器(PVD)可以监控VDD电源电压,当VDD下降到PVD阀值以下或上升到PVD阀值之上时,PVD会触发中断,用于执行紧急关闭任务

  • 低功耗模式包括睡眠模式(Sleep)、停机模式(Stop)和待机模式(Standby)(功耗逐级降低,唤醒时间逐级变长),可在系统空闲时,降低STM32的功耗,延长设备使用时间

1.2电源框图

1. VDDA供电区 (模拟电源域)

  • 功能:为芯片内部所有模拟模块供电的独立电源区域。

  • 供电引脚:由独立的 VDDA 和 VSSA 引脚供电。

  • 主要负载

    • 模数转换器 (ADC)

    • 数模转换器 (DAC)(如果支持)

    • 内部RC振荡器 (HSI, LSI)锁相环 (PLL)

    • 电压参考缓冲 (VREF+ / VREF-)(在某些型号上由VDDA引出)

  • 设计要点

    • 必须连接:即使不使用任何模拟功能,VDDA也必须连接到VDD(通常通过一个磁珠或低阻值电阻隔离),否则芯片无法正常工作。

    • 去耦和滤波:为了获得最佳的ADC性能,VDDA和VSSA必须并联高频和低频去耦电容(例如100nF + 1uF),并尽可能靠近芯片引脚,以滤除来自数字电路的噪声。

    • 电源质量:ADC的转换精度直接依赖于VDDA的电压稳定性和纯净度。如果VDDA上有噪声,ADC的读数也会产生波动。

2. VDD供电区

  • 来源:直接从芯片的 VDD/VSS 引脚接入。

  • 供电目标

    • I/O 引脚:所有数字I/O口的驱动电源。

    • 部分模拟电路:虽然模拟部分主要由VDDA供电,但一些与I/O相关的模拟逻辑(如输入保护二极管)也可能连接到VDD。

    • 待机电路(唤醒逻辑,IWDG)

    • 电压调节器:连接1.8V供电区域

  • 特点:这是芯片的主电源入口。在设计PCB时,必须在每个 VDD 引脚附近放置一个去耦电容(通常100nF),以滤除高频噪声,提供稳定电流。

3. 1.8V供电区域 (数字电源域)

  • 功能:芯片数字核心逻辑的供电区域,是芯片运行的主要动力源。

  • 供电来源

    • 在大多数STM32(除某些超低功耗型号外)中,VDD电压(如3.3V)并不直接供给内核

    • 而是通过一个内部电压调节器(稳压器)将VDD降压到一个稳定的1.8V(或1.2V,取决于产品系列和工作频率),再为这个区域供电。

  • 主要负载

    • CPU内核 (Cortex-M系列核心)

    • 数字外设 (如GPIO、SPI, I2C, USART, Timers等)

    • 内部SRAM和Flash存储器

  • 设计要点

    • VDD引脚:为整个数字部分供电,包括I/O口和内部稳压器。需要良好的去耦。

    • 低功耗模式:在停止等模式下,PWR可以关闭或降低该稳压器的输出,以大幅降低静态功耗。

    • 此1.8V区域在芯片内部产生,用户无法直接从外部测量或供电。

4. 后备供电区 (Backup Domain)

  • 功能:一个独立的供电区域,用于在主电源(VDD/VBAT)丢失时,保存最关键的数据和维持最基本的时基功能。

  • 供电来源:由一个特殊的电源选择电路控制,其电源来自:

    • VDD(当主电源存在时)

    • VBAT(当低电压检测器检测到主电源VDD断开时,自动切换到VBAT引脚)

  • 主要负载

    • 实时时钟 (RTC):即使主MCU断电,RTC也可以继续走时。

    • 备份寄存器 (Backup Registers):一小块由VBAT维持的SRAM,通常为16-32字节,用于存储关键数据(如设备序列号、校准参数、运行状态等)。

    • 唤醒逻辑:用于从待机模式通过RTC闹钟或WKUP引脚唤醒整个系统。

  • 设计要点

    • VBAT引脚:必须连接。如果应用中没有备用电池(如纽扣电池),强烈建议将VBAT引脚通过一个100nF电容连接到VSS,并同时通过一个二极管(如1N4148)连接到VDD。这样可以确保主电源存在时由VDD为备份域供电,主电源断开时则由电容短暂维持(时间很短,仅用于安全关机)。

    • 写保护:要修改备份域中的寄存器(RTC配置、备份寄存器),必须先取消其写保护。

    • 域隔离:备份域与其他域通过特殊的开关隔离,只有在特定条件下才能被访问,这进一步保证了其数据安全。

5. 总结与关键注意事项

供电区域来源供电目标设计要点
VDD外部电源I/O引脚,部分内部逻辑充分去耦,每个VDD引脚一个100nF电容
VDDA独立清洁电源ADC, DAC, VREF+必须通过磁珠/电感与VDD隔离,加强滤波
1.8V域内部LDO(来自VDD)CPU, 内存, 数字外设低功耗模式的控制核心
VBAT外部电池RTC, 备份寄存器, LSE保证主电源掉电后关键功能不丢失

1.3上电复位(POR)和掉电复位(PDR)

基本概念

  • 上电复位(Power-On Reset, POR):在芯片从无电到上电的过程中,当供电电压VDD从0V开始上升,达到一个特定的触发阈值(VPOR) 时,芯片会产生一个复位信号,将整个系统保持在复位状态,直到电源电压稳定到一个可靠的水平。

  • 掉电复位(Power-Down Reset, PDR):在芯片正常工作后,如果因为某种原因(如电源干扰、电池耗尽)导致VDD电压下降,当电压低于一个特定的触发阈值(VPDR) 时,芯片会产生一个复位信号,防止CPU和外设在电压不足的情况下执行错误操作。

在STM32中,POR和PDR电路通常被集成在一起,统称为POR/PDR电路。它们是一个完全由模拟硬件实现的功能,不需要任何软件配置,只要接了VDD电源就会自动工作。


POR的40mV迟滞(确保电源稳定和等待时钟稳定)

  • 是什么:迟滞是一种经典的电路设计技术,用于防止比较器在阈值点附近因噪声或微小波动而产生反复翻转(振荡)。

  • 如何工作

    • VPOR_up (上升阈值):当VDD电压从0V开始上升时,必须达到VPOR(例如,约1.8V)这个阈值点,POR电路才会解除复位信号。

    • VPOR_down (下降阈值):当VDD电压从正常值下降时,必须降到比VPOR40mV(例如,约1.76V)的点,POR电路才会重新断言(Assert)复位信号。

1.4可编程电压监测器(预警)

基本概念

可编程电压监测器(Programmable Voltage Detector, PVD) 是一个可以由软件配置的电源电压监测模块。它持续将VDD电压与一个由软件设定的阈值(PLS[2:0])进行比较。


 PVD阈值

  • 是什么:PVD的阈值不是固定的,而是由软件通过配置PWR_CR寄存器的PLS[2:0]位来动态选择的。

  • 阈值等级:STM32提供了多个可选的阈值,覆盖了一个常见的电压范围(例如,从2.0V到2.9V,具体范围和步进因产品系列而异)。这允许开发者根据实际供电电压(如3.3V系统或2.5V系统)来设置一个合理的预警点。


PVD的100mV迟滞(防止振荡,缓冲区)

  • 是什么:与POR类似,PVD的比较器也内置了迟滞功能,但其迟滞电压典型值为100mV

  • 如何工作

    • 假设软件设置的PVD阈值是 2.8V

    • 下降沿:当VDD电压从高处下降2.8V时,PVD输出触发,标志位置位,并可产生中断。

    • 上升沿:之后,如果VDD电压又从低处回升,它必须达到 2.8V + 100mV = 2.9V 时,PVD输出才会解除,标志位清零,并可再次产生中断。


POR/PDR 与 PVD 的对比总结

特性POR/PDRPVD
本质硬件自动保护机制软件可配置预警机制
功能保证可靠上电和防止欠压运行监测电压变化,提供早期预警
控制完全由模拟硬件实现,无需配置(固定1.9V)需要通过软件配置阈值和外部中断(2.2V~2.9V)
响应产生复位信号,触发系统复位,强制MCU重启触发中断事件,由软件决定如何处理
速度响应极快,是最后防线响应较快,但需软件处理时间
关系“最后的安全卫士”“哨兵”,为卫士提供预警
迟滞典型40mV,防止电源噪声导致反复复位典型100mV,防止电压波动导致中断风暴

1.5低功耗模式

功耗从高到低,唤醒速度从快到慢:睡眠→停止→待机

1.睡眠模式 (Sleep Mode)

  • 实现机制:执行WFI(Wait for Interrupt)WFE(Wait for Event)指令后,内核停止执行,CPU时钟关闭。但所有外设的时钟仍然正常运行,NVIC保持工作。

  • 功耗:功耗降低主要来自CPU核心本身。整体功耗相对较高。

  • 唤醒

    • 任何外设中断(如果使用WFI)或事件(如果使用WFE)都可唤醒。

    • 唤醒时间极短,几乎无延迟,因为时钟系统仍在运行,CPU恢复时钟后即可继续执行下一条指令。

  • 适用场景:处理完任务后,短暂等待下一次中断,且对唤醒延迟要求极高的场合。

睡眠模式注意点:
  • 执行完WFI/WFE指令后,STM32进入睡眠模式,程序暂停运行,唤醒后程序从暂停的地方继续运行
  • SLEEPONEXIT决定STM32执行完WFIWFE后,是立刻进入睡眠,还是等STM32从最低优先级的中断处理程序中退出时进入睡眠
  • 在睡眠模式下,所有的I/O引脚都保持它们在运行模式时的状态
  • WFI指令进入睡眠模式,可被任意一个NVIC响应的中断唤醒
  • WFE指令进入睡眠模式,可被唤醒事件唤醒

2. 停止模式 (Stop Mode)

  • 实现机制

    • PDDS位=0,停止模式

    • SLEEPDEEP=1

    • 关闭整个1.8V供电区域的时钟,包括CPU和所有外设的时钟。

    • 可选择关闭内部主稳压器(LPDS位=0,电压调节器开启,LPDS位=1,调压器进入低功耗模式),以进一步省电。

    • 可选是否保留IO口状态。

    • 所有寄存器和SRAM的内容保持不变

  • 功耗:功耗显著降低,可达微安(µA)级别。

  • 唤醒

    • 外部复位(NRST引脚)RTC闹钟/事件RTC入侵事件RTC唤醒事件多个EXTI线外部中断,对应特定引脚)唤醒。

    • 唤醒后,系统时钟默认切换为HSI(内部多速RC振荡器),需要软件重新配置时钟树到想要的速度。程序从停止指令后的下一条指令开始执行。

  • 适用场景:需要长时间休眠、定期唤醒采样、且需保持当前程序上下文(变量值)的场合。是平衡功耗和灵活性的最佳选择。

停止模式注意点:
  • 执行完WFI/WFE指令后,STM32进入停止模式,程序暂停运行,唤醒后程序从暂停的地方继续运行
  • 1.8V供电区域的所有时钟都被停止,PLLHSIHSE被禁止,SRAM和寄存器内容被保留下来
  • 在停止模式下,所有的I/O引脚都保持它们在运行模式时的状态
  • 当一个中断或唤醒事件导致退出停止模式时,HSI被选为系统时钟
  • 当电压调节器处于低功耗模式下,系统从停止模式退出时,会有一段额外的启动延时
  • WFI指令进入停止模式,可被任意一个EXTI中断唤醒

3. 待机模式 (Standby Mode)

  • 实现机制

    • PDDS位=1,待机模式

    • SLEEPDEEP=1

    • 最彻底的模式。关闭1.8V供电区域(整个数字电路域)。

    • 除了备份域(RTC、备份寄存器)和唤醒逻辑,其他部分全部断电。

    • SRAM和寄存器内容全部丢失(备份寄存器除外)。

  • 功耗:功耗最低,可达微安(µA)甚至纳安(nA)级别。

  • 唤醒

    • 外部复位(NRST引脚)RTC闹钟/事件RTC入侵事件WKUP引脚(PA0)的上升沿独立看门狗(IWDG)复位唤醒。

    • 唤醒后相当于一次软复位,芯片从头开始执行程序(复位向量地址0x0000_0000)。可以通过检查PWR_CSR寄存器的SBF(Standby Flag)标志位来判断是否由待机模式唤醒。

  • 适用场景:需要极低功耗、长时间休眠,且每次唤醒都作为一次全新启动的场合。例如,每天只上报一次数据的远程传感器。

待机模式注意点:
  • 执行完WFI/WFE指令后,STM32进入待机模式,唤醒后程序从头开始运行
  • 整个1.8V供电区域被断电,PLLHSIHSE也被断电,SRAM和寄存器内容丢失,只有备份的寄存器和待机电路维持供电
  • 在待机模式下,所有的I/O引脚变为高阻态(浮空输入)
  • WKUP引脚的上升沿、RTC闹钟事件的上升沿、NRST引脚上外部复位、IWDG复位退出待机模式

4. 模式选择

执行WFI(Wait For Interrupt)或者WFE(Wait For Event)指令后,STM32进入低功耗模式

5. 模式对比总结表

特性睡眠模式 (Sleep)停止模式 (Stop)待机模式 (Standby)
功耗极低
唤醒时间极短 (仅CPU恢复时钟)短 (需时钟重启)长 (完全复位)
程序执行上下文保持 (从下条指令继续)保持 (从下条指令继续)丢失 (从头开始执行)
SRAM/寄存器内容保持保持丢失 (备份域除外)
时钟状态仅CPU时钟停所有1.8V域时钟停1.8V域断电
主要唤醒源任意中断/事件EXTI线、RTC事件WKUP引脚、RTC事件、NRST
应用场景短暂空闲,快速响应定期采样,保持状态超长待机,复位启动

6. 重要设计注意事项

  1. GPIO配置:在进入Stop/Standby模式前,必须将所有不用的GPIO设置为模拟输入模式。悬空的IO引脚如果被配置为浮空输入,会因漏电流而显著增加功耗。

  2. 未使用外设:关闭所有不需要的外设时钟。

  3. 调试接口:低功耗模式可能会禁用调试器(如ST-Link)的连接。通常唤醒后才能重新连接。有些模式支持“调试驻留”功能,允许在低功耗下保持调试连接,但会略微增加功耗。

  4. 测量功耗:精确测量功耗时,需将调试器断开,仅通过电源供电进行测量。

二、修改主频频率代码

文件system_stm32f10.c中

此文件是只读文件,若要修改,需要打开工程文件夹,打开文件所在位置,右键——属性——只读选项去除

#if defined (STM32F10X_LD_VL) || (defined STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)#if是预编译,用来兼容不同型号的设备
若define后面有效,就else上面有效
否则#else,即下面代码有效我的设备时F10F3C8T6 中容量,非超值系列,因此查看else下方代码,由此来修改主频频率
此时主频频率时72MHz/* #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主程序代码int main(void)
{	OLED_Init();OLED_ShowString(1,1,"SYSCLK:");OLED_ShowNum(1,8,SystemCoreClock,8);while(1){OLED_ShowString(2,1,"running");Delay_ms(500);OLED_ShowString(2,1,"       ");Delay_ms(500);}
}

配置时钟的流程:

①system_Init()函数→启动HSI+各种缺省配置——调用SetSysClock()分配函数

②SetSysClock()分配函数→选择解除不同的宏定义,从而执行不同的配置参数SerSysClockTo72等函数——进行配置主频频率(例:To72——HSE锁相环输入——HSE9倍频——HSE锁相环输出位主频——主频72M)

三、睡眠模式+串口发送接收

(再次运行需要按住复位键俩秒+点击运行+松手)

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "serial.h"
#include "stdio.h"
uint16_t Rxdata;在此工程基础上,加一个低功耗的代码假设用STM32做一个下位机
下位机接收电脑串口发送过来的指令,后执行相应的功能
电脑随时都可能通过串口发送指令靠中断触发,没有中断就无用的代码,可以加入一个低功耗模式——睡眠模式,其他模式都不行int main(void)
{	OLED_Init();serial_init();OLED_ShowString(1,1,"RXdata:");while(1){if(serial_getRxfalg()==1){Rxdata=serial_getRXdata();serial_sendbyte(Rxdata);}OLED_ShowHexNum(1,8,Rxdata,2);OLED_ShowString(2,1,"Running");Delay_ms(500);OLED_ShowString(2,1,"           ");Delay_ms(500);--------------------------------------------------------------------------------SCB->SCR=0x………………//此种寄存器方式配置
__WFI();//中断唤醒}
}

仅需加入__WFI即可进入睡眠模式

若想要配置深度睡眠模式还是睡眠模式,可以查看手册STM32F10XXX.Cortex-M3编程手册——4.4.6System control register(SCB_SCR),在程序中,用操作寄存器的方式实现

SEVEONPEND=0,事件唤醒睡眠模式需要配置的位

SLEEPDEEP=0,睡眠模式;=1,深度睡眠模式

SLEEPONEXIT=0,立刻睡眠;=1,等中断结束睡眠

程序执行流程:

①初始化,串口配置好,进入主循环,检查标志位,Running闪烁一次,在主循环最后执行__WFI(),执行WFI,CPU立刻睡眠

②CPU睡眠,各个外设运行状态,等到串口发送数据,USART接收到数据,产生中断,唤醒CPU,睡眠模式唤醒后,程序在暂停的地方继续运行

③因此,程序运行到WFI之后,但唤醒之后,终端立刻申请,所以程序在条回到while循环开头之前,先进入USART中断函数,读取数据,置R下Flag,清除RXNE,回到主循环开头,此时RxFlag刚置1,if成立,执行数据回传和显示功能

④唤醒功能执行完,Running闪烁一次,程序再次来到WFI位置,CPU再次进入睡眠……

四、停止模式+对射式红外传感器计次

4.1PWR外设库函数:

1.恢复缺省配置
void PWR_DeInit(void);
2.使能后备区域的访问
void PWR_BackupAccessCmd(FunctionalState NewState);
3.与PVD相关的函数,PVD使能
void PWR_PVDCmd(FunctionalState NewState);
4.与PVD相关的函数,配置PVD的阈值电压
void PWR_PVDLevelConfig(uint32_t PWR_PVDLevel);
5.使能位于PA0位置的WakeUp引脚(待机模式用Wakeup上升沿唤醒)
void PWR_WakeUpPinCmd(FunctionalState NewState);
6.进入停止模式
void PWR_EnterSTOPMode(uint32_t PWR_Regulator, uint8_t PWR_STOPEntry);
7.进入待机模式
void PWR_EnterSTANDBYMode(void);
8.获取标志位
FlagStatus PWR_GetFlagStatus(uint32_t PWR_FLAG);
9.清除标志位
void PWR_ClearFlag(uint32_t PWR_FLAG);

4.2代码书写

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "countSensor.h"外部中断不需要时钟
在硬件层面没有EXTI,只有内部中断和外部中断,
外部中断可用停机模式,内部中断只能用睡眠模式
在代码里无EXTI时钟参数,这就是EXTI能在时钟关闭的情况下工作的原因int main(void)
{	OLED_Init();CountSensor_Init();
--------------------------------------------------------------------------------------RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);OLED_ShowString(1,1,"count");while(1){	OLED_ShowSignedNum(1,7,count,5);OLED_ShowString(2,1,"Running");Delay_ms(500);OLED_ShowString(2,1,"           ");Delay_ms(500);---------------------------------------------------------------------------------------PWR_EnterSTOPMode(PWR_Regulator_ON,PWR_STOPEntry_WFI);/*复位后第一个Running很快,后面就变慢了是因为推出停止模式后,HSI被选为系统时钟SystemInit函数里配置的是72M主频,后续的HSI是8M,因此运行时间变慢只需要在后面重新调用SystemInit函数,重新启动HSE,配置72M主频即可*/SystemInit();}}

五、待机模式+实时时钟

任务一、设定闹钟
在while上设定,每次复位后设定闹钟值

任务二、加入待机模式
使用PWR外设之前,开启时钟,确保代码独立性

任务三、
wakeup引脚唤醒功能,随时用GPIO引脚,但不需要GPIO初始化

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "My_RTC.h"int main(void)
{	OLED_Init();MyRTC_Init();RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);OLED_ShowString(1, 1, "CNT:");//秒计数器OLED_ShowString(2, 1, "ALR:");//闹钟值OLED_ShowString(3, 1, "ALRF:");//闹钟标志位/*使能WKUP引脚*/PWR_WakeUpPinCmd(ENABLE);//使能位于PA0的WKUP引脚,WKUP引脚上升沿唤醒待机模式uint32_t Alarm=RTC_GetCounter()+10;RTC_SetAlarm(Alarm);//只写寄存器OLED_ShowNum(2,6,Alarm,10);while(1){OLED_ShowNum(1, 6, RTC_GetCounter(), 10);	//显示32位的秒计数器/*闹钟标志位是否置1*/OLED_ShowNum(3,6,RTC_GetFlagStatus(RTC_FLAG_ALR),1);OLED_ShowString(4,1,"Running");Delay_ms(500);OLED_ShowString(4,1,"           ");Delay_ms(500);OLED_ShowString(4, 9, "STANDBY");//OLED闪烁STANDBY,指示即将进入待机模式Delay_ms(1000);OLED_ShowString(4, 9, "       ");Delay_ms(100);OLED_Clear();//OLED清屏,模拟关闭外部所有的耗电设备,以达到极度省电//STM32进入待机模式之前,要把外部接入的模块能停的都停掉,能断电的都断掉,以最大化的省电PWR_EnterSTANDBYMode();//程序从头开始执行//注意:复位+下载+松手}
}

http://www.xdnf.cn/news/18937.html

相关文章:

  • 机器视觉学习-day06-图像旋转
  • KafKa学习笔记
  • 【Day 35】Linux-Mysql错误总结
  • DA14531(Cortex-M0+)之Wake-up Interrupt Controller (WIC)
  • React学习教程,从入门到精通, ReactJS - 安装:初学者指南(3)
  • linux 网络:并发服务器及IO多路复用
  • 如何将yolo训练图像数据库的某个分类的图像取出来
  • element-plus的el-scrollbar显示横向滚动条
  • 使用华为 USG6000防火墙配置安全策略
  • 传输层协议介绍
  • 企业通讯软件以安全为基,搭建高效的通讯办公平台
  • Python篇---返回类型
  • 【论文阅读】PEPNet
  • amis上传组件导入文件接口参数为base64格式的使用示例
  • 计算机三级嵌入式填空题——真题库(22)原题附答案速记
  • 强化学习与注意力机制的AlignSAM框架解析
  • 微算法科技(NASDAQ:MLGO)推出创新型混合区块链共识算法,助力物联网多接入边缘计算
  • [n8n] 工作流数据库管理SQLite | 数据访问层-REST API服务
  • Paimon——官网阅读:Flink 引擎
  • 前端javascript在线生成excel,word模板-通用场景(免费)
  • AbMole小课堂丨详解野百合碱在动物肺动脉高压、急性肺损伤、静脉闭塞肝病造模中的原理及应用
  • Go 语言常用命令使用与总结
  • 微信小程序对接EdgeX Foundry详细指南
  • 云计算学习100天-第31天
  • 从零开始的云计算生活——第五十三天,发愤图强,kubernetes模块之Prometheus和发布
  • 【SpringAI】快速上手,详解项目快速集成主流大模型DeepSeek,ChatGPT
  • 【TEC045-KIT】基于复旦微 FMQL45T900 的全国产化 ARM 开发套件
  • Uniapp中自定义导航栏
  • 如何将iPhone上的隐藏照片传输到电脑
  • Flask测试平台开发实战-第二篇