Skip to content

电源管理

image-20231225230337003

image-20231225230519884

电源监控器

stm32主要是从VDD获取电压, 电压监控器会对他进行监控, 电压低的时候会进行处理, 保证系统正常的运行

主要是VDD: 芯片供电引脚, VDDA: 模拟电源, VBAT: 电池电压 进行检测

POR/PDR监控器, PVD监控器, BOR监控器, AVD监控器, VBAT阈值, 温度阈值

  • POR/PDR监控器: 上电复位以及掉电复位

检测到电压低于阈值VPOR以及VPDR的时候, stm32会自动复位, 防止由于电压不足导致严重的后果, 在电压开始低于VPOR的时候(1.92V)stm32会进入上电复位, 当VDD电压持续上升至大于VPOR的时候, 芯片开始运行, 当电压低于VPDR的时候(1.88V)进入掉电

image-20231227204310355

  • 可编程电压监测器PVD

也是一直在检测VDD, 可以自己设置两个电压阈值, 在低于阈值的时候发生一个中断, 之后进入复位状态, 进行紧急处理, 发生的中断时EXTI16中断

image-20231227204505648

image-20231227204539444

寄存器

image-20231227210015946

image-20231227210031133

image-20231227210129499

通过这一个位查询判断电压的情况

  • BOR 欠压复位

  • AVD: 监控VDDA

  • VBAT阈值: 检测VBAT电池电压

  • 温度阈值: 检测结温

  • stm32电源系统

V~REF~提供的是A/D转换器的电压, 这里可以提供一个比较稳定的电压

V~DD~, 除了后备之外的供电, 供电电压是1.8V, 内部会进行降压

V~BAT~, 电路板上面的电池, 可以由V~DD~选择是否供电, V~DD~断电之后会使用V~BAT~供电给实时时钟

stm32的功耗模式

低功耗为的是降低集成电路的功能消耗, 对于电池供电的产品更加重要, 降低电池的体积, 延长电池的寿命, 更小的电磁干扰, 设计更简单(散热)

image-20231225230835944

stm32具有运行,睡眠,停止,待机四种状态, 上电复位之后会进入运行状态, 内核不需要运行的时候可以选择使用后面的状态

image-20231225231538271

image-20231225231600649

image-20230725184046023

在停止之后需要重新设置时钟, 应为会默认使用HSI作为时钟

待机模式相当于重启, 所以不需要

  • 睡眠: 关闭内核时钟, 内核停止运行, 其他外设正常运行, CM3的核心外设正常运行, 进入有两种模式, WFI(wait for interrupt), WFE(wait for event)

image-20231225230935432

image-20230725201944602

所有的事件都可以引起中断, 也可以设置为不引起中断

可以设置直接进入中断或者是退出时进入中断, 设置的是SLEEPONEXIT=0就是立即睡眠, 在中断中需要退出时进入中断

  • 停止模式

外设停止工作, 但是1.8V工作区电源没有关闭, 保留内核的寄存器信息, 停止模式唤醒需要重新开启时钟, 从断电的地方开始执行函数, 进入停止之后所有的I/O处于停止前的状态

image-20231225231043807

image-20230726211026038

  • 待机模式

关闭所有的时钟, 不保存代码之前运行的信息, 有四种唤醒的方式, 唤醒可以通过KEY1唤醒, 所有的GPIO都处于高阻态

image-20231225231131814

image-20230726212205693

寄存器

image-20231226203850631

image-20231226204022008

image-20231226204138873

image-20231226204313371

image-20231226204333687

库函数

c
void PWR_BackupAccessCmd(FunctionalState NewState);

有的RTC的寄存器需要先使能才可以访问

c
void PWR_EnterSTOPMode(uint32_t PWR_Regulator, uint8_t PWR_STOPEntry);

停止

c
void PWR_EnterSTANDBYMode(void);

待机

c
void PWR_PVDLevelConfig(uint32_t PWR_PVDLevel);

设置可编程电源控制器

c
void PWR_WakeUpPinCmd(FunctionalState NewState);

使能WAKEUP引脚

c
#define __NOP                             __nop
#define __WFI                             __wfi
#define __WFE                             __wfe

这里是编译器指令

c
void PWR_EnterSTOPMode(uint32_t PWR_Regulator, uint8_t PWR_STOPEntry)
{
  uint32_t tmpreg = 0;
  /* Check the parameters */
  assert_param(IS_PWR_REGULATOR(PWR_Regulator));
  assert_param(IS_PWR_STOP_ENTRY(PWR_STOPEntry));
  //设置寄存器的模式
  /* Select the regulator state in STOP mode ---------------------------------*/
  tmpreg = PWR->CR;
  /* Clear PDDS and LPDS bits */
  tmpreg &= CR_DS_MASK;
  /* Set LPDS bit according to PWR_Regulator value */
  tmpreg |= PWR_Regulator;
  /* Store the new value */
  PWR->CR = tmpreg;
  /* Set SLEEPDEEP bit of Cortex System Control Register */
  SCB->SCR |= SCB_SCR_SLEEPDEEP;
  //设置唤醒的模式
  /* Select STOP mode entry --------------------------------------------------*/
  if(PWR_STOPEntry == PWR_STOPEntry_WFI)
  {   
    /* Request Wait For Interrupt */
    __WFI();
  }
  else
  {
    /* Request Wait For Event */
    __WFE();
  }
  //复位寄存器, 防止进入睡眠的时候进入待机
  /* Reset SLEEPDEEP bit of Cortex System Control Register */
  SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP);  
}
c
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();
}

调用之前需要调用函数

c
void PWR_WakeUpPinCmd(FunctionalState NewState)
{
  /* Check the parameters */
  assert_param(IS_FUNCTIONAL_STATE(NewState));
    //设置这个引脚
  *(__IO uint32_t *) CSR_EWUP_BB = (uint32_t)NewState;
}

实际使用

  • 睡眠模式: 直接调动__WFI

在睡眠的时候不能进行下载以及调试

  • 待机模式

调用void PWR_EnterSTANDBYMode(void)

  • 停止模式

void PWR_EnterSTOPMode(uint32_t PWR_Regulator, uint8_t PWR_STOPEntry)

注意

待机模式必须开启PWR时钟

PVD

image-20230727123248915

输入的5V转换为3.3V, PVD实际上监控的是VDD引脚

c
void PVD_Config(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;
  EXTI_InitTypeDef EXTI_InitStructure;

  /*使能 PWR 时钟 */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);

  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
  
  /* 使能 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);
      
  /* 配置 EXTI16线(PVD 输出) 来产生上升下降沿中断*/
  EXTI_ClearITPendingBit(EXTI_Line16);
  EXTI_InitStructure.EXTI_Line = EXTI_Line16;
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  EXTI_Init(&EXTI_InitStructure);

  /* 配置PVD级别PWR_PVDLevel_2V6 (PVD检测电压的阈值为2.6V,VDD电压低于2.6V时产生PVD中断) */
	/*具体级别根据自己的实际应用要求配置*/
  PWR_PVDLevelConfig(PWR_PVDLevel_2V6);

  /* 使能PVD输出 */
  PWR_PVDCmd(ENABLE);
}
c
void PVD_IRQHandler(void)
{
		/*检测是否产生了PVD警告信号*/
		if(PWR_GetFlagStatus (PWR_FLAG_PVDO)==SET)			
		{
			/* 亮红灯,实际应用中应进入紧急状态处理 */
			LED_RED; 
			
		}
    /* 清除中断信号*/
    EXTI_ClearITPendingBit(EXTI_Line16);

}

H7

image-20231226214223358

image-20231227193039788

image-20231227193217348

image-20231227193424450

image-20231227193544240

image-20231227193705806

image-20231227193733880

image-20231227193837017

想要使用最大的主频需要进行切换电压等级

image-20231227193926249

相关寄存器

image-20231227194034918

image-20231227194123386

image-20231227194209184

image-20231227194243601

image-20231227194328373

image-20231227194400514

image-20231227194433249

image-20231227194644794

首先在这个寄存器设置为VOS1

image-20231227194730360

在这里激活为VOS0

image-20231227194843450