STM32入门笔记15_PWR电源管理模块

本文详细介绍了STM32的PWR电源控制模块,包括PVD低电压检测、可编程电压范围、低功耗模式(Sleep、Stop和Standby)及其唤醒机制。还讨论了如何通过WFI指令和中断来实现不同模式的切换,以及系统时钟的管理和外设控制以降低功耗。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

PWR和低功耗模式

PWR简介

  • PWR(Power Control) 电源控制
  • PWR负责管理STM32内部的电源供电部分,可以实现可编程电压检测器和低功耗模式的功能
  • 可编程电压检测器(PVD) 可以监控VDD电源电压,当VDD下降到PVD阈值以下或上升到PVD阈值之上时,PVD会触发中断,用于执行紧急关闭任务
  • 低功耗模式包括睡眠模式(Sleep)、停机模式(Stop)和待机模式(Standby),可在系统空闲时,降低STM32的功耗,延长设备使用时间

电源框图

在这里插入图片描述

  • V D D 、 V S S V_{DD}、V_{SS} VDDVSS给数字电路供电
  • V D D A 、 V S S A V_{DDA}、V_{SSA} VDDAVSSA给模拟电路供电
  • 低电压检测器在检测到 V D D 和 V S S V_{DD}和V_{SS} VDDVSS之间电压低于阈值后,会切换后备供电区域的供电电源为 V B A T V_{BAT} VBAT,而当 V D D 和 V S S V_{DD}和V_{SS} VDDVSS供电正常时,则由 V D D 和 V S S V_{DD}和V_{SS} VDDVSS供电
  • 芯片内部的数字电路(1.8V供电区域)供电电压为1.8V

在这里插入图片描述

  • 关于 V D D A 和 V S S A V_{DDA}和V_{SSA} VDDAVSSA的作用参考手册, 注意在STM32F103C8T6中未引出

上电复位和掉电复位

在这里插入图片描述

可编程电压检测器

在这里插入图片描述

在这里插入图片描述

低功耗模式

在这里插入图片描述

  • 一般使用WFI (wait for interrupt) 等待中断
  • 睡眠模式(Sleep Mode)下, 任一中断都可以唤醒MCU,一般省电
  • 停机模式(Stop Mode)下,仅外部中断能够唤醒MCU,同时1.8V区域的时钟全部关闭,HSI和HSE的时钟也关闭,但电压调节器仍然打开,SRAM和寄存器中的数据不会丢失
  • 待机模式(Standby Mode)下,仅特定事件能够唤醒MCU,相较于停机模式电压调节器关闭,SRAM和寄存器中数据丢失
  • Sleep ModeStop Mode唤醒后程序从进入低功耗模式的代码开始重新执行,而Standby Mode唤醒后程序从头开始执行(因为数据都丢失了)
  • 值的注意的是,Stop Mode唤醒后默认使用HSI (8MHz)作为系统时钟, 若想用HSE则需重新调用SystemInit()函数

模式选择

在这里插入图片描述

  • 对照该图和参考手册配置自己需要的模式

睡眠模式

  • 执行完WFI/WFE指令后,STM32进入睡眠模式,程序暂停运行,唤醒后程序从暂停的地方继续运行

  • SLEEPONEXIT位决定STM32执行完WFI或WFE后,是立刻进入睡眠,还是等STM32从最低优先级的中断处理程序中退出时进入睡眠 (WFI或WFE写主函数里立刻进入睡眠还是先处理中断差别不大)

  • 在睡眠模式下,所有的I/O引脚都保持它们在运行模式时的状态 (为进一步降低能耗,在执行WFI/WFE前关闭能关闭的外设)

  • WFI指令进入睡眠模式,可被任意一个NVIC响应的中断唤醒

  • WFE指令进入睡眠模式,可被唤醒事件唤醒

停止模式

  • 执行完WFI/WFE指令后,STM32进入停止模式,程序暂停运行,唤醒后程序从暂停的地方继续运行

  • 1.8V供电区域的所有时钟都被停止,PLL、HSI和HSE被禁止,SRAM和寄存器内容被保留下来

  • 在停止模式下,所有的I/ O引脚都保持它们在运行模式时的状态 (为进一步降低能耗,在执行WFI/WFE前关闭能关闭的外设)

  • 当一个中断或唤醒事件导致退出停止模式时,HSI被选为系统时钟

  • 当电压调节器处于低功耗模式下,系统从停止模式退出时,会有一段额外的启动延时

  • WFI指令进入停止模式,可被任意一个EXTI中断唤醒 (RTC和PVD可借道EXTI中断通道将MCU从停止模式唤醒)

待机模式

  • 执行完WFI/WFE指令后,STM32进入待机模式,唤醒后程序从头开始运行

  • 整个1.8V供电区域被断电,PLL、HSI和HSE也被断电,SRAM和寄存器内容丢失,只有备份的寄存器和待机电路维持供电

  • 在待机模式下,所有的I/O引脚变为高阻态(浮空输入)(不用手动关闭外设)

  • WKUP引脚的上升沿、RTC闹钟事件的上升沿、NRST引脚上外部复位、IWDG复位退出待机模式

降低系统主频和关闭APB和AHB总线上未被使用的外设时钟

  • 除了低功耗模式能降低电源消耗外,降低系统主频和关闭未使用的外设时钟也是降低电源消耗的很好的方式
  • 系统主频通过时钟树可以看出,由HSE接外部晶振提供(一般8MHz),经过PLL得到倍频,然后作为系统主频

在这里插入图片描述

  • 关于系统主频的修改,相关的文件是system_stm32f10x.c,通过宏定义可修改成以下时钟频率, 具体函数的执行流程可以自己看或看江科大的视频
    在这里插入图片描述

  • 如何取消只读文件的限制

在这里插入图片描述

打开文件属性,取消可读后确定
在这里插入图片描述

文件上的钥匙消失,现在可以修改文件中关于主频的宏定义

在这里插入图片描述

主要代码

功能为单片机运行10s即进入停止模式, 当检测到外部中断后, 退出停止模式, 运行10s后再次进入停止模式

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "MyRTC.h"
#include "key.h"
#include "LED.h"
#include "Timer.h"
#include "valve.h"

uint8_t Stop_Time;

int main(void)
{
	OLED_Init();
	MyRTC_Init(); // RTC初始化
	Key_Init();  // 按键初始化
	LED_Init();  // LED 初始化
	Timer_TIM3_Init();  // 定时器初始化
	Valve_Init();  // 电磁阀端口初始化
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);  // 打开PWR时钟 *
	OLED_ShowString(1, 1, "Date:XXXX-XX-XX");
	OLED_ShowString(2, 1, "Time:XX:XX:XX");
	Stop_Time = 0;
	while (1)
	{
		MyRTC_ReadTime();
		
		OLED_ShowNum(1, 6, MyRTC_Time[0], 4);
		OLED_ShowNum(1, 11, MyRTC_Time[1], 2);
		OLED_ShowNum(1, 14, MyRTC_Time[2], 2);
		OLED_ShowNum(2, 6, MyRTC_Time[3], 2);
		OLED_ShowNum(2, 9, MyRTC_Time[4], 2);
		OLED_ShowNum(2, 12, MyRTC_Time[5], 2);
		OLED_ShowNum(3, 1, Stop_Time, 3);
		if(Stop_Time > 100)
		{
			Stop_Time = 0;
			OLED_Clear();  // 屏幕熄灭
			RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, DISABLE);  // 关闭GPIOB时钟
			PWR_EnterSTOPMode(PWR_Regulator_ON, PWR_STOPEntry_WFI);  // 进入停止模式*
			SystemInit();  // 重新设置时钟
			OLED_Init();
			Valve_Init();  // 电磁阀端口初始化
			OLED_ShowString(1, 1, "Date:XXXX-XX-XX");
			OLED_ShowString(2, 1, "Time:XX:XX:XX");
		}
	}
}

/**
* @brief 按键中断服务函数 PA8
*/
void EXTI9_5_IRQHandler(void)
{
	if(EXTI_GetFlagStatus(EXTI_Line8))
	{
		Delay_ms(10);
		if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_8) == 0)
		{
			LED_Turn();
		}
		EXTI_ClearITPendingBit(EXTI_Line8);
	}
}

/**
* @brief 定时器中断服务函数 TIM3_UpDate
*/
void TIM3_IRQHandler(void)
{
	if(TIM_GetITStatus(TIM3, TIM_IT_Update))
	{
		Stop_Time += 1;
	}
	TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
}

  • 要进入停止模式只需通过RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); 打开PWR时钟
  • 再在需要进入停止模式的时候调用PWR_EnterSTOPMode(PWR_Regulator_ON, PWR_STOPEntry_WFI); 即可进入停止模式
  • 进入停止模式前,根据需求关闭耗电的外设
  • 从停止模式退出后,系统使用HSI时钟主频默认为8Mhz, 需重新调用SystemInit()函数重新设置时钟为HSE使主频恢复为72MHz
  • 从停止模式退出后,应重新初始化关闭的外设

效果展示

【STM32停止模式】

参考资料

模式退出后,系统使用HSI时钟主频默认为8Mhz, 需重新调用SystemInit()函数重新设置时钟为HSE使主频恢复为72MHz

  • 从停止模式退出后,应重新初始化关闭的外设
### 关于江科大 STM32 单片机学习笔记的内容概述 STM32 是一种基于 ARM Cortex-M 系列内核的高性能、低成本、低功耗32 位微控制器单元 (MCU),广泛应用于嵌入式系统开发中[^1]。对于希望深入学习 STM32 的开发者来说,江科大的 STM32 学习笔记提供了一套全面而系统的教程资源。 #### 学习笔记的主要内容结构 根据已有参考资料,江科大的 STM32 学习笔记涵盖了多个主题模块,具体如下: 1. **基础概念与入门** - STM32 微控制器的基础架构及其特点。 - 开发环境搭建及相关工具链配置方法[^2]。 2. **串口通信** - USART 数据包处理机制以及 HEX 和文本数据包的发送接收实现方式[^3]。 - 使用 FlyMcu 工具进行固件上传操作说明。 3. **IIC(Inter-Integrated Circuit)协议支持** - IIC 总线基本原理及其实现细节分析。 - 针对 MPU6050 加速度计/陀螺仪传感器设备的具体应用案例研究——包括软件模拟和硬件驱动两种模式下的交互流程设计。 4. **SPI(Serial Peripheral Interface)接口功能探索** - SPI 协议定义及其工作过程解析。 - 结合 W25Q64 NOR Flash 存储器件完成读写测试实验方案描述;同样区分了软硬兼施的不同技术路径探讨。 5. **时间管理相关特性讲解** - Unix 时间戳的概念引入及时区转换算法讨论。 - RTC 实时时钟服务配合 BKP 备份寄存器共同作用下保持断电记忆能力的功能展示。 6. **电源管理和安全防护措施规划** - PWR 模块用于降低能耗水平的技术手段阐述。 - 各类看门狗定时器的工作逻辑解释,保障程序运行稳定性的策略建议。 7. **存储子系统优化指导** - 如何高效访问内部 FLASH 并提取唯一芯片 ID 编号的信息指南。 以下是部分典型代码片段示例供参考: ```c // 初始化USART端口设置函数模板 void USART_Init(void){ GPIO_InitTypeDef GPIO_InitStruct; USART_InitTypeDef USART_InitStruct; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); // 配置GPIO引脚作为USART复用功能 GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA,&GPIO_InitStruct); // 设置波特率等参数并使能相应中断源 USART_InitStruct.USART_BaudRate=9600; USART_InitStruct.USART_WordLength=USART_WordLength_8b; USART_InitStruct.USART_StopBits=USART_StopBits_1 ; USART_InitStruct.USART_Parity=USART_Parity_No; USART_InitStruct.USART_HardwareFlowControl=USART_HardwareFlowControl_None; USART_InitStruct.USART_Mode=USART_Mode_Rx|USART_Mode_Tx; USART_Init(USART2,&USART_InitStruct); } ``` 上述代码展示了如何初始化一个简单的 USART 接口以便后续可以执行字符流传输任务。 --- ####
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值