Appearance
电源管理
电源监控器
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)进入掉电
- 可编程电压监测器PVD
也是一直在检测VDD, 可以自己设置两个电压阈值, 在低于阈值的时候发生一个中断, 之后进入复位状态, 进行紧急处理, 发生的中断时EXTI16中断
寄存器
通过这一个位查询判断电压的情况
BOR 欠压复位
AVD: 监控VDDA
VBAT阈值: 检测VBAT电池电压
温度阈值: 检测结温
stm32电源系统
V~REF~提供的是A/D转换器的电压, 这里可以提供一个比较稳定的电压
V~DD~, 除了后备之外的供电, 供电电压是1.8V, 内部会进行降压
V~BAT~, 电路板上面的电池, 可以由V~DD~选择是否供电, V~DD~断电之后会使用V~BAT~供电给实时时钟
stm32的功耗模式
低功耗为的是降低集成电路的功能消耗, 对于电池供电的产品更加重要, 降低电池的体积, 延长电池的寿命, 更小的电磁干扰, 设计更简单(散热)
stm32具有运行,睡眠,停止,待机四种状态, 上电复位之后会进入运行状态, 内核不需要运行的时候可以选择使用后面的状态
在停止之后需要重新设置时钟, 应为会默认使用HSI作为时钟
待机模式相当于重启, 所以不需要
- 睡眠: 关闭内核时钟, 内核停止运行, 其他外设正常运行, CM3的核心外设正常运行, 进入有两种模式, WFI(wait for interrupt), WFE(wait for event)
所有的事件都可以引起中断, 也可以设置为不引起中断
可以设置直接进入中断或者是退出时进入中断, 设置的是SLEEPONEXIT=0就是立即睡眠, 在中断中需要退出时进入中断
- 停止模式
外设停止工作, 但是1.8V工作区电源没有关闭, 保留内核的寄存器信息, 停止模式唤醒需要重新开启时钟, 从断电的地方开始执行函数, 进入停止之后所有的I/O处于停止前的状态
- 待机模式
关闭所有的时钟, 不保存代码之前运行的信息, 有四种唤醒的方式, 唤醒可以通过KEY1唤醒, 所有的GPIO都处于高阻态
寄存器
库函数
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();
}
调用之前需要调用函数
cvoid 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
输入的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
想要使用最大的主频需要进行切换电压等级
相关寄存器
首先在这个寄存器设置为VOS1
在这里激活为VOS0