[STM32 - 野火] - - - 固件库学习笔记 - - -十一.电源管理系统

一、电源管理系统简介

电源管理系统是STM32硬件设计和系统运行的基础,它不仅为芯片本身提供稳定的电源,还通过多种电源管理功能优化功耗、延长电池寿命,并确保系统的可靠性和稳定性。

二、电源监控器

作用:保证STM32芯片工作在它自己要求的一个电压范围内。

STM32芯片主要通过引脚VDD从外部获取电源,在它的内部具有电源监控器用于检测VDD的电压,以实现复位功能及掉电紧急处理功能,保证系统地运行。

2.1 上电复位(POR)与掉电复位(PDR)

POR:Power On Reset;
PDR:Power Down Reset;

上电复位和掉电复位的波形图
当VDD/VDDA低于指定的限位电压VPOR/VPDR时,系统保持为复位状态,而无需外部复位电路

  • 在刚开始上电,电压低于VPOR(约1.92V)时,系统保持在上电复位状态,当VDD电压持续上升到大于VPOR时,系统开始正常运行;

  • 在系统正常运行时,检测到VDD电压下降至低于VPDR阈值(约1.88V)时,系统会进入掉电复位状态。

VPOR与VPDR的差值大概在40mv。

2.2 可编程电压监控器(PVD)

除了POR与PDR功能,STM32还提供了PVD用于实时检测VDD电压:当检测到VDD电压低于编程的VPVD阈值时,会向内核产生一个PVD中断(EXTI16线中断,该中断不用手动设置)以使内核在复位前进行紧急处理。

当VDD下降到PVD阀值以下和(或)当VDD上升到PVD阀值之上时,根据外部中断第16线的上升/下降边沿触发设置,就会产生PVD中断。

在这里插入图片描述
使用PVD可配置8个等级。

请添加图片描述

其中,上升沿和下降沿分别表示VDD电压上升过程及下降过程的阈值。

PVD可以理解为POR与PDR的升级版,对电压值可编程,复位前通过中断通知

三、电源系统

请添加图片描述

STM32的电源系统主要分为ADC电路、调压器供电电路以及备份域电路三个部分。

3.1 ADC电路(VDDA供电区域)

ADC电路的工作电源使用VDDA引脚输入,使用VSSA作为独立的地连接,VRED引脚则为ADC提供测量使用的参考电压。

  • 为什么ADC配有单独的电源接口?

    • 为了提高转换精度,方便进行单独的滤波。

VDDA供电区域包含模数转换的一部分。

3.2 调压器供电电路(VDD/1.8V供电区域)

调压器供电电路是STM32电源系统中最主要的部分,为备份域及待机模式以外的所有数字电路供电,其中包括内核、数字外设(例如串口、GPIO口、CAN口等)以及RAM。

调压器的输出电压约为1.8V。

调压器可以工作在运行模式、停止模式以及待机模式。

  • 在运行模式下,1.8V域全功率运行;

  • 在停止模式下 1.8V 域运行在低功耗状态, 1.8V 区域的所有时钟都被关闭,相应的外设都停止了工作,但它会保留内核寄存器以及 SRAM 的内容;

  • 在待机模式下,整个 1.8V 域都断电,该区域的内核寄存器及 SRAM 内容都会丢失 (备份区域的寄存器不受影响);

除了后备供电区域外的所有数字逻辑都包含在VDD供电区域,VDD供电区只包含数字逻辑,不包含模拟。

CPU核心就是cortex m3内核,电压调节器用来调节供给cortex内核是否供电。换句话说,cortex核心由电压调节器单独供电

3.3 备份域电路

备份域电路给晶振、时钟供电。

STM32 的 LSE 振荡器、 RTC 及备份寄存器这些器件被包含进备份域电路中,这部分的电路可以通过 STM32 的 VBAT 引脚获取供电电源,在实际应用中一般会使用 3V 的钮扣电池对该引脚供电。

在这里插入图片描述

上图中的电源开关结构,类似于下图中的二极管。
在这里插入图片描述

后备供电区域由VBAT与VDD选择供电:

  • 当主电源供电时,上面是3.3V大于下面纽扣电池的输出电压,主电源供电给MCU;
  • 当主电源掉电时,就由纽扣电池给MCU供电。

BDCR寄存器:备份域寄存器,可以往这个寄存器中存储一些数据,主电掉电后不会丢失(有纽扣电池)。

四、低功耗模式

按功耗由高到低排列, STM32 具有运行、睡眠、停止和待机四种工作模式。

上电复位后 STM32处于运行状态时,当内核不需要继续运行,就可以选择进入后面的三种低功耗模式降低功耗。

这三种模式中,电源消耗不同、唤醒时间不同、唤醒源不同,用户需要根据应用需求,选择最佳的低功耗模式。

在这里插入图片描述

4.1 睡眠模式

在睡眠模式中,仅关闭了内核时钟,内核停止运行,但其片上外设, CM3 核心的外设全都还照常运行。

  • 进入睡眠模式:通过执行WFI(Wait For Interrupt)或WFE(Wait For Event)指令进入睡眠状态。

在这里插入图片描述
从睡眠模式唤醒后,程序会在进入睡眠模式的地方进行执行

  • WFI与WFE的区别:

    • WFI需要进入中断服务函数中执行;
    • WFE不需要进入中断服务函数中执行,节省一点时间;

4.2 停止模式

在停止模式中,进一步关闭了其它所有的时钟,于是所有的外设都停止了工作,但由于其 1.2V区域的部分电源没有关闭,还保留了内核的寄存器、内存的信息,所以从停止模式唤醒,并重新开启时钟后,还可以从上次停止处继续执行代码

停止模式可以由任意一个外部中断 (EXTI) 唤醒,在停止模式中可以选择电压调节器为开模式或低功耗模式。

在这里插入图片描述

  • 若调压器处于低功耗模式下,唤醒的时间要长一点。(等待调压器恢复)

  • 通过SLEEPDEEP位的设置,选择进入睡眠模式还是停止模式。(设置为0进入睡眠模式,设置为1进入停止模式)

4.3 待机模式

待机模式,它除了关闭所有的时钟,还把 1.8V 区域的电源也完全关闭了。

从待机模式唤醒,程序会从启动文件开始执行(相当于复位了)

待机模式有四种唤醒方式,分别是== WKUP(PA0) 引脚的上升沿==, RTC 闹钟事件,== NRST 引脚的复位==和 IWDG(独立看门狗) 复位

在这里插入图片描述

  • 睡眠模式、停止模式以及待机待机模式,若备份域电源正常供电,备份域内的RTC都可以正常运行,备份域内的寄存器的数据会被保存,不受功耗模式影响。

  • 在进入待机模式后,除了被使能了的用于唤醒的 I/O,其余 I/O 都进入高阻态

5、实验设计

5.1 睡眠模式

// main.c文件
#include "stm32f10x.h"
#include "bsp_key.h"
#include "bsp_exti.h"
#include "bsp_systick.h"
#include "usart.h"char str[10] = {0};int main(void)
{EXTI_KEY1_Config();EXTI_KEY2_Config();USART_Config();printf("\r\n  睡眠前 \r\n");__WFI();printf("\r\n  唤醒后 \r\n");printf("\r\n  str:%s \r\n", str);while(1){printf("\r\n  睡眠前 \r\n");__WFI();printf("\r\n  唤醒后 \r\n");printf("\r\n  str:%s \r\n", str);}}
// stm32f10x_it.c
extern char str[10];
void EXTI0_IRQHandler(void)
{if(EXTI_GetFlagStatus(EXTI_Line_KEY1) != RESET){//LED_G_TOGGLE();strcpy(str, "按键1中断");}EXTI_ClearFlag(EXTI_Line_KEY1);
}// 这里的中断名称不要写成 EXTI4_IRQHandler 
void EXTI15_10_IRQHandler(void)
{if(EXTI_GetFlagStatus(EXTI_Line_KEY2) != RESET){//LED_B_TOGGLE();strcpy(str, "按键2中断");}EXTI_ClearFlag(EXTI_Line_KEY2);
}void USART1_IRQHandler(void)
{uint8_t ucTemp;if(USART_GetFlagStatus(DEBUG_USARTx, USART_IT_RXNE) != RESET){strcpy(str, "串口中断");ucTemp = USART_ReceiveData(DEBUG_USARTx);USART_SendData(DEBUG_USARTx, ucTemp);}
}

在这里插入图片描述
注意:不建议在中断服务函数中添加打印函数,可能会影响系统的运行速度。

  • 可以在中断服务函数中把要打印的数据赋值给变量,在主函数中打印。

在 USART1_IRQHandler 中断服务函数中,如果将函数内容改为:

void USART1_IRQHandler(void)
{uint8_t ucTemp;if(USART_GetFlagStatus(DEBUG_USARTx, USART_IT_RXNE) != RESET){strcpy(str, "串口中断");}
}

在串口上无法看到打印的数据,原因:

  • 没有清除接受中断标志位,中断标志位会一直保持在置位状态,导致中断服务函数一直被反复触发,程序一直执行中断服务函数,无法正常执行主函数逻辑。

  • 执行了USART_ReceiveData函数会自动清除RXNE标志位。

5.2 停止模式

// main.c文件
#include "stm32f10x.h"
#include "bsp_key.h"
#include "bsp_exti.h"
#include "bsp_rccclkconfig.h"
#include "bsp_systick.h"
#include "usart.h"char str[10] = {0};static void SYSCLKConfig_STOP(void);int main(void)
{EXTI_KEY1_Config();EXTI_KEY2_Config();USART_Config();printf("\r\n  睡眠前 \r\n");SysTick_Delay_ms(500);PWR_EnterSTOPMode(PWR_Regulator_ON, PWR_STOPEntry_WFI);/* 恢复 HSE 时钟 */SYSCLKConfig_STOP();printf("\r\n  唤醒后 \r\n");printf("\r\n  str:%s \r\n", str);while(1){}}/*** @brief  从停止模式唤醒后配置系统时钟:启用HSE、PLL并选择PLL作为系统时钟源。* @param  无* @retval 无*/
static void SYSCLKConfig_STOP(void)
{/* After wake-up from STOP reconfigure the system clock *//* 使能 HSE */RCC_HSEConfig(RCC_HSE_ON);/* 等待 HSE 准备就绪 */while(RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET){}/* 使能 PLL */RCC_PLLCmd(ENABLE);/* 等待 PLL 准备就绪 */while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET){}/* 选择PLL作为系统时钟 */RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);/* 等待PLL被选择为系统时钟 */while(RCC_GetSYSCLKSource() != 0x08){}
}

在这里插入图片描述

  • 进入了停止模式,退出时如果没有恢复HSE时钟,系统的时钟可能会与进入停止模式的时钟不同,导致一些其他问题,如串口发送错误:

在这里插入图片描述

5.3 待机模式

// main.c文件
#include "stm32f10x.h"
#include "bsp_exti.h"
#include "bsp_rccclkconfig.h"
#include "bsp_systick.h"
#include "usart.h"char str[10] = {0};static void SYSCLKConfig_STOP(void);int main(void)
{USART_Config();printf("\r\n  睡眠前 \r\n");SysTick_Delay_ms(500);// 进入待机模式必须开启PWR时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);// 使能 PA0 引脚上升沿唤醒PWR_WakeUpPinCmd(ENABLE);PWR_EnterSTANDBYMode();printf("\r\n  唤醒后 \r\n");printf("\r\n  str:%s \r\n", str);while(1){}}

在这里插入图片描述
注意:

  • 1、进入待机模式时必须开启PWR时钟;

  • 2、使用PA0引脚上升沿唤醒,调用PWR_WakeUpPinCmd(ENABLE)即可;

  • 3、PA0 引脚上升沿唤醒与复位键唤醒效果相同,系统都会从头开始运行。

5.4 PVD检测

PVD会产生EXTI16中断。

// main.c文件
#include "stm32f10x.h"
#include "bsp_exti.h"
#include "bsp_led.h"
#include "bsp_rccclkconfig.h"
#include "bsp_systick.h"
#include "usart.h"
#include "bsp_pvd.h"int main(void)
{PVD_Config();USART_Config();while(1){}}
// bsp_pvd.c文件
#include "bsp_pvd.h"static void EXTI_PVD_NVIC_Config(void)
{NVIC_InitTypeDef NVIC_InitStruct;NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);NVIC_InitStruct.NVIC_IRQChannel = PVD_IRQn;NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStruct);
}void PVD_Config(void)
{EXTI_InitTypeDef EXTI_InitStruct;// 配置 NVIC EXTI_PVD_NVIC_Config();// 开启 PWR 时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);/* 选择EXTI的信号源 */EXTI_InitStruct.EXTI_Line = EXTI_Line16;/* EXTI为中断模式 */EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;/* 上升沿中断 */EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising;/* 使能中断 */EXTI_InitStruct.EXTI_LineCmd = ENABLE;EXTI_Init(&EXTI_InitStruct);// 3.3V 引脚 的电压低于2.6V会产生中断,其中3.3V引脚与STM32的VDD引脚相连PWR_PVDLevelConfig(PWR_PVDLevel_2V6);PWR_PVDCmd(ENABLE);
}
// bsp_pvd.h文件
#ifndef __BSP_PVD_H
#define __BSP_PVD_H#include "stm32f10x.h"void PVD_Config(void);#endif /* __BSP_PVD_H */
// stm32f10x_it.c文件
void PVD_Handler(void)
{if(PWR_GetFlagStatus(PWR_FLAG_PVDO) == SET){// 此处做电压下降的紧急处理LED_B(ON);}EXTI_ClearITPendingBit(EXTI_Line16);
}

请添加图片描述

PVD监控VDD的引脚电压,当VDD引脚电压低于设定值时产生PVD中断。


另外,

  • 进入睡眠模式、停止模式、待机模式后,不能使用调试功能。

  • 进入低功耗模式后,程序下载不进去,解决方法:

    • 1、退出低功耗模式再下载(SWD、SCK引脚没有被更改为其他模式);

    • 2、接RST复位引脚或按复位按键;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/67145.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数字图像处理:实验六

uu们!大家好,2025年的新年就要到来,咸鱼哥在这里祝大家在2025年每天开心快乐,天天挣大钱,自由自在,健健康康,万事如意!(要是咸鱼哥嘴笨的话,还望大家多多包涵…

Langchain+文心一言调用

import osfrom langchain_community.llms import QianfanLLMEndpointos.environ["QIANFAN_AK"] "" os.environ["QIANFAN_SK"] ""llm_wenxin QianfanLLMEndpoint()res llm_wenxin.invoke("中国国庆日是哪一天?") print(…

上海亚商投顾:沪指冲高回落 大金融板块全天强势 上海亚商投

上海亚商投顾前言:无惧大盘涨跌,解密龙虎榜资金,跟踪一线游资和机构资金动向,识别短期热点和强势个股。 一.市场情绪 市场全天冲高回落,深成指、创业板指午后翻绿。大金融板块全天强势,天茂集团…

农产品价格报告爬虫使用说明

农产品价格报告爬虫使用说明 # ************************************************************************** # * * # * 农产品价格报告爬虫 …

3.4 Go函数作用域(标识符)

作用域标识符 简单来说,作用域指的是标识符可以起作用的范围,即其可见范围。将标识符的可见性限制在一定范围内,这个范围就是作用域。 把标识符约束在一定的可见范围内,这个范围就是作用域。 1. 宇宙块 特点:预定义…

kaggle比赛入门 - House Prices - Advanced Regression Techniques(第二部分)

本文承接上一篇 1. 分析住宅类型(BldgType)的分布以及它们与销售价格(SalePrice)的关系 # 1. distribution of dwelling types and their relation to sale prices # BldgType: Type of dwellingdwelling_types df[BldgType].v…

使用shell命令安装virtualbox的虚拟机并导出到vagrant的Box

0. 安装virtualbox and vagrant [rootolx79vagrant ~]# cat /etc/resolv.conf #search 114.114.114.114 nameserver 180.76.76.76-- install VirtualBox yum install oraclelinux-developer-release-* wget https://yum.oracle.com/RPM-GPG-KEY-oracle-ol7 -O /etc/pki/rpm-g…

【数据结构】空间复杂度

目录 一、引入空间复杂度的原因 二、空间复杂度的分析 ❥ 2.1 程序运行时内存大小 ~ 程序本身大小 ❥ 2.2 程序运行时内存大小 ~ 算法运行时内存大小 ❥ 2.3 算法运行时内存大小 ❥ 2.4 不考虑算法全部运行空间的原因 三、空间复杂度 ❥ 3.1空间复杂度的定义 ❥ 3.2 空…

MySQL--》深度解析InnoDB引擎的存储与事务机制

目录 InnoDB架构 事务原理 MVCC InnoDB架构 从MySQL5.5版本开始默认使用InnoDB存储引擎,它擅长进行事务处理,具有崩溃恢复的特性,在日常开发中使用非常广泛,其逻辑存储结构图如下所示, 下面是InnoDB架构图&#xf…

Redis高阶5-布隆过滤器

Redis布隆过滤器 ​ 由一个初始值都为零的bit数组和多个哈希函数构成,用来快速判断集合中是否存在某个元素 目的减少内存占用方式不保存数据信息,只是在内存中做一个是否存在的标记flag 布隆过滤器(英语:Bloom Filter&#xff0…

DeepSeek学术题目选择效果怎么样?

论文选题 一篇出色的论文背后,必定有一个“智慧的选题”在撑腰。选题足够好文章就能顺利登上高水平期刊;选题不行再精彩的写作也只能“当花瓶”。然而许多宝子们常常忽视这个环节,把大量时间花在写作上,选题时却像抓阄一样随便挑一…

第五节 MATLAB命令

本节的内容将提供常用的一些MATLAB命令。 在之前的篇章中我们已经知道了MATLAB数值计算和数据可视化是一个交互式程序,在它的命令窗口中您可以在MATLAB提示符“>>”下键入命令。 MATLAB管理会话的命令 MATLAB提供管理会话的各种命令。如下表所示:…

Docker核心命令与Yocto项目的高效应用

随着软件开发逐渐向分布式和容器化方向演进,Docker 已成为主流的容器化技术之一。它通过标准化的环境配置、资源隔离和高效的部署流程,大幅提高了开发和构建效率。Yocto 项目作为嵌入式 Linux 系统构建工具,与 Docker 的结合进一步增强了开发…

Qt 5.14.2 学习记录 —— 이십 QFile和多线程

文章目录 1、QFile1、打开2、读写3、关闭4、程序5、其它功能 2、多线程1、演示2、锁 3、条件变量和信号量 1、QFile Qt有自己的一套文件体系,不过Qt也可以使用C,C,Linux的文件操作。使用Qt的文件体系和Qt自己的一些类型更好配合。 管理写入读…

【全栈】SprintBoot+vue3迷你商城-扩展:vue3项目创建及目录介绍

【全栈】SprintBootvue3迷你商城-扩展:vue3项目创建及目录介绍 往期的文章都在这里啦,大家有兴趣可以看一下 【全栈】SprintBootvue3迷你商城(1) 【全栈】SprintBootvue3迷你商城(2) 【全栈】SprintBootvu…

使用Aardio库在Python中创建桌面应用:简单指南

引言 随着软件开发需求的不断增长,开发者们需要更加灵活和高效的工具来快速构建应用程序。Python以其简洁易读的语法和强大的社区支持而闻名,但在创建图形用户界面(GUI)时,可能会遇到一些挑战。Aardio作为一种轻量级的…

多版本并发控制:MVCC的作用和基本原理

多版本并发控制:MVCC的作用和基本原理 1、MVCC简介1.1 快照读与当前读的区别1.1.1 快照读1.1.2 当前读 1.2 数据库的读写问题1.3 MVCC的作用 2、MVCC实现原理之ReadView2.1 什么是ReadView2.2 ReadView的设计思路2.3 MVCC整体操作流程 1、MVCC简介 1.1 快照读与当前…

神经网络|(二)sigmoid神经元函数

【1】引言 在前序学习进程中,我们已经了解了基本的二元分类器和神经元的构成,文章学习链接为: 神经网络|(一)加权平均法,感知机和神经元-CSDN博客 在此基础上,我们认识到神经元本身在做二元分类,是一种非…

Qt中QVariant的使用

1.使用QVariant实现不同类型数据的相加 方法:通过type函数返回数值的类型,然后通过setValue来构造一个QVariant类型的返回值。 函数: QVariant mainPage::dataPlus(QVariant a, QVariant b) {QVariant ret;if ((a.type() QVariant::Int) &a…

BAHD酰基转移酶对紫草素的手性催化-文献精读105

Two BAHD Acyltransferases Catalyze the Last Step in the Shikonin/Alkannin Biosynthetic Pathway 两个BAHD酰基转移酶催化了紫草素/左旋紫草素生物合成途径中的最后一步 一个BAHD酰基转移酶专门催化紫草素的酰基化,而另一个BAHD酰基转移酶则仅催化紫草素的对映…