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

news2025/1/27 12:22:22

一、电源管理系统简介

电源管理系统是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.coloradmin.cn/o/2283146.html

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

相关文章

从 Web2 到 Web3:技术演进中的关键变革

随着互联网的快速发展,Web 技术经历了从 Web1 到 Web2,再到当前热议的 Web3 的演变。每一次技术迭代不仅仅是技术本身的升级,更代表着对社会、经济和文化的深刻影响。本文将带你走过 Web2 到 Web3 的技术演进,探讨其中的关键变革&…

Android实战经验篇-玩转Selinux(详解版)

列文章转如下链接: Android Display Graphics系列文章-汇总 Android实战经验篇-系列文章汇总 本文主要包括部分: 一、Selinux概述 1.1 SELinux是什么? 1.2 自主访问控制(DAC) 1.3 强制访问控制(MAC&…

CLOUDFLARE代理请求重定向你太多次

现象 使用CLOUDFLARE代理前请求正常,使用CLOUDFLARE代理请求后出现 原因分析 以下是我的猜测,在默认情况下 CLOUDFLARE代理,可能是直接请求我们服务器的IP,比如:http://1.1.1.1 而不是通过域名的方式(如…

U-Net - U型网络:用于图像分割的卷积神经网络

U-Net是一种专为图像分割任务设计的卷积神经网络(CNN),最初由Olaf Ronneberger等人于2015年提出。它被广泛应用于医学影像分析、遥感图像分割、自动驾驶和其他许多需要对图像进行像素级分类的任务中。U-Net具有强大的特征提取和恢复能力&…

第十五届蓝桥杯大赛软件赛省赛C/C++ 大学 B 组

第十五届的题目在规定时间内做出了前5道,还有2道找时间再磨一磨。现在把做的一些思路总结如下: 题1:握手问题 问题描述 小蓝组织了一场算法交流会议,总共有 50人参加了本次会议。在会议上,大家进行了握手交流。按照惯例…

Vue3 + TS 实现批量拖拽 文件夹和文件 组件封装

一、html 代码&#xff1a; 代码中的表格引入了 vxe-table 插件 <Tag /> 是自己封装的说明组件 表格列表这块我使用了插槽来增加扩展性&#xff0c;可根据自己需求&#xff0c;在组件外部做调整 <template><div class"dragUpload"><el-dial…

DX12 快速教程(4) —— 画钻石原矿

快速导航 新建项目 "004-DrawTexture"纹理贴图纹理采样纹理过滤邻近点采样双线性过滤Mipmap 多级渐远纹理三线性过滤各向异性过滤 纹理环绕LOD 细节层次 开始画钻石原矿吧加载纹理到内存中&#xff1a;LoadTexture什么是 WIC如何用 WIC 读取一帧图片获取图片格式并转…

LBS 开发微课堂|AI向导接口服务:重塑用户的出行体验

为了让广大开发者 更深入地了解 百度地图开放平台的 技术能力 轻松掌握满满的 技术干货 更加简单地接入 位置服务 我们特别推出了 “位置服务&#xff08;LBS&#xff09;开发微课堂” 系列技术案例 第六期的主题是 《AI向导接口服务的能力与接入方案》 随着地图应…

mysql 学习3 SQL语句--整体概述。SQL通用语法;DDL创建数据库,查看当前数据库是那个,删除数据库,使用数据库;查看当前数据库有哪些表

SQL通用语法 SQL语句分类 DDL data definition language : 用来创建数据库&#xff0c;创建表&#xff0c;创建表中的字段&#xff0c;创建索引。因此成为 数据定义语言 DML data manipulation language 有了数据库和表以及字段后&#xff0c;那么我们就需要给这个表中 添加数…

【Bug 记录】el-sub-menu 第一次进入默认不高亮

项目场景&#xff1a; 项目场景&#xff1a;el-sub-menu 第一次进入默认不高亮 问题描述 例如&#xff1a;sub-menu 的 index 后端默认传过来是 number&#xff0c;我们需要手动转为 string&#xff0c;否则会有警告&#xff0c;而且第一次进入 sub-menu 默认不高亮。 解决方…

深入探讨ncnn::Mat类——ncnn中的核心数据结构

最近在学习 ncnn 推理框架&#xff0c;下面整理了 ncnn::Mat 的使用方法。 ncnn作为一个高性能的神经网络推理框架&#xff0c;其核心数据结构ncnn::Mat在数据存储与处理上扮演了至关重要的角色。本文将从基础到高级&#xff0c;详细介绍ncnn::Mat类的各个方面&#xff0c;帮助…

npm:升级自身时报错:EBADENGINE

具体报错信息如下&#xff1a; 1.原因分析 npm和当前的node版本不兼容。 // 当前实际版本: Actual: {"npm":"10.2.4","node":"v20.11.0"}可以通过官网文档查看与自己 node 版本 兼容的是哪一版本的npm&#xff0c;相对应进行更新即可…

ipad和macbook同步zotero文献附件失败的解决办法

背景&#xff1a;我所有的文献及其附件pdf都是在台式机&#xff08;windows系统&#xff09;&#xff0c;想要把这些文献同步到云上&#xff0c;然后再从云上同步到平板和其他笔记本电脑比如macbook。文献同步虽已成功&#xff0c;但文献附件都无法打开。 平板报错如下&#xf…

【嵌入式】总结——Linux驱动开发(三)

鸽了半年&#xff0c;几乎全忘了&#xff0c;幸亏前面还有两篇总结。出于快速体验嵌入式linux的目的&#xff0c;本篇与前两篇一样&#xff0c;重点在于使用、快速体验&#xff0c;uboot、linux、根文件系统不作深入理解&#xff0c;能用就行。 重新梳理一下脉络&#xff0c;本…

15_业务系统基类

创建脚本 SystemRoot.cs 因为 业务系统基类的子类 会涉及资源加载服务层ResSvc.cs 和 音乐播放服务层AudioSvc.cs 所以在业务系统基类 提取引用资源加载服务层ResSvc.cs 和 音乐播放服务层AudioSvc.cs 并调用单例初始化 using UnityEngine; // 功能 : 业务系统基类 public c…

C语言-构造数据类型

1、构造数据类型 结构体、共用体、枚举。 2、结构体 1、结构体的定义 结构体是一个自定义的复合数据类型&#xff0c;它允许将不同类型的数据组合在一起。 struct 结构体名 {数据类型1 成员变量1;数据类型2 成员变量2;数据类型3 成员变量3;数据类型4 成员变量4; } 2、结构体变…

文档解析:PDF里的复杂表格、少线表格如何还原?

PDF中的复杂表格或少线表格还原通常需要借助专业的工具或在线服务&#xff0c;以下是一些可行的方法&#xff1a; 方法一&#xff1a;使用在线PDF转换工具 方法二&#xff1a;使用桌面PDF编辑软件 方法三&#xff1a;通过OCR技术提取表格 方法四&#xff1a;手动重建表格 …

【统计的思想】假设检验(二)

假设检验是根据人为设定的显著水平&#xff0c;对被测对象的总体质量特性进行统计推断的方法。 如果我们通过假设检验否定了零假设&#xff0c;只是说明在设定的显著水平下&#xff0c;零假设成立的概率比较小&#xff0c;并不是说零假设就肯定不成立。如果零假设事实上是成立…

汽车定速巡航

配备定速巡航功能的车型&#xff0c;一般在方向盘附近设有4~6个按键&#xff08;可能共用键位&#xff09;。 要设置定速巡航&#xff0c;不仅需要方向盘上的按键&#xff0c;还要油门配合。 设置的一般流程&#xff1a; 开关&#xff1a;类似步枪上的“保险”&#xff0c;按…

MacOS安装Docker battery-historian

文章目录 需求安装battery-historian实测配置国内源相关文章 需求 分析Android电池耗电情况、唤醒、doze状态等都要用battery-historian&#xff0c; 在 MacOS 上安装 battery-historian&#xff0c;可以使用 Docker 进行安装runcare/battery-historian:latest。装完不需要做任…