STM32低功耗实验学习日记

news/2024/12/21 20:57:52/

STM32低功耗实验学习日记

写于2024/9/25晚

文章目录

  • STM32低功耗实验学习日记
    • 1. 简介
    • 2. STM32F1电源系统
      • 2.1 电源系统
      • 2.2 电源管理
        • 2.2.1 睡眠模式
        • 2.2.2 停止模式
        • 2.2.3 待机模式
      • 2.3 相关寄存器介绍
        • 2.3.1 系统控制寄存器(SCB_SCR)
        • 2.3.2 电源控制寄存器(PWR_CR)
        • 2.3.3 电源控制/状态寄存器(PWR_CSR)
        • 2.3.4 WFI与WFE指令
    • 3. 进入低功耗模式的使用步骤
    • 4. 代码解析

1. 简介

我们将介绍 STM32F103 的电源控制(PWR),并实现低功耗模式相关功能。我们将通过四个实验来学习并实现低功耗相关功能,分别是 PVD 电压监控实验、睡眠模式实验、停止模式实验和待机模式实验

2. STM32F1电源系统

电源控制部分(PWR)概述了不同电源域的电源架构以及电源配置控制器。PWR 的内容比较多,我们把它们的主要特性概括为以下 3 点:

  • 电源系统:VDDA供电区域、VDD供电区域、1.8V 供电区域、后备供电区域。

  • 电源监控:POR/PDR 监控器、PVD 监控器。

  • 电源管理:低功耗模式。

下面将分别对这 3 个特性进行简单介绍。

2.1 电源系统

image-20240925220620902

在电源概述框图中我们划分了 3 个区域①②③,分别是独立的 A/D 转换器供电和参考电压、电压调节器、电池备份区域。下面分别进行简单介绍:

① 独立的 A/D转换器供电和参考电压(VDDA供电区域)

VDDA 供电区域,主要是 ADC 电源以及参考电压,STM32 的 ADC 模块配备独立的供电方式,使用了 VDDA 引脚作为输入,使用 VSSA 引脚作为独立地连接VREF 引脚为提供给 ADC 的参考电压

② 电压调节器(VDD /1.8V供电区域)

电压调节器是 STM32 的电源系统中最核心部分,连接 VDD供电区域1.8 V供电区域。VDD供电来自于 VSS 和 VDD,给 I/O 电路以及待机电路供电,电压调节器主要为备份域以及待机电路以外的所有数字电路供电,其中包括内核、数字外设以及RAM,调节器的输出电压约为1.8V,因此由调压器供电的区域称为 1.8V 供电区域。电压调节器根据应用方式不同有三种不同的工作模式。在运行模式下,调节器以正常工作模式为内核、内存和外设提供 1.8V;在停止模式下,调节器以低功耗模式提供 1.8V 电源,以保存寄存器和 SRAM 的内容。在待机模式下,调节器停止供电,除了备用电路和备份域外,寄存器和 SRAM 的内容全部丢失。

③ 电池备份区域(后备供电区域)

电池备份区域也就是后备供电区域,使用电池或者其他电源连接到 VBAT脚上,当 VDD断电时,可以保存备份寄存器的内容维持 RTC 的功能。同时 VBAT 引脚也为 RTCLSE 振荡器供电,这保证了当主要电源被切断时,RTC 能够继续工作。切换到 VBAT 供电由复位模块中的掉电复位功能控制。

2.2 电源管理

电源管理的部分我们要关注低功耗模式,在 STM32 的正常工作中,具有四种工作模式,运行、睡眠、停止以及待机。在上电复位后,STM32 处于运行状态时,当内核不需要继续运行,就可以选择进入后面的三种模式降低功耗。

这三种低功耗模式电源消耗不同、唤醒时间不同和唤醒源不同,我们要根据自身的需要选择合适的低功耗模式。下面是低功耗模式汇总介绍,如下表所示。

image-20240925221804613

2.2.1 睡眠模式

进入睡眠模式,Cortex_M3 内核停止,所有外设包括 Cortex_M3 核心的外设,如 NVIC、系统时钟(SysTick)等仍在运行,有两种进入睡眠模式的模式 WFI 和 WFE。WFI(Wait for interrupt等待中断)和 WFE(Wait for event等待事件)是内核指令,会调用一些汇编指令,会使用即可。睡眠后唤醒的方式即由等待“中断”唤醒和“事件”唤醒。

image-20240925222025162

image-20240926215958124

2.2.2 停止模式

进入停止模式,所有的时钟都关闭,所有的外设也就停止了工作。但是 VDD电源是没有关闭的,所以内核的寄存器和内存信息都保留下来,等待重新开启时钟就可以从上次停止的地方继续执行程序。

值得注意的是:当电压调节器处于低功耗模式下,当系统从停止模式退出时,将会有一段额外的启动延时。如果在停止模式期间保持内部调节器开启,则退出启动时间会缩短,但相应的功耗会增加。

image-20240926220653052

image-20240926220842031

2.2.3 待机模式

待机模式可实现最低功耗。该模式是在 CM3 深睡眠模式时关闭电压调节器,整个 1.8V 供电区域被断电。PLL、HSI 和 HSE 振荡器也被断电。除备份域(RTC 寄存器、RTC 备份寄存器和备份 SRAM)和待机电路中的寄存器外,SRAM 和其他寄存器内容都将丢失。不过如果我们使能了备份区域(备份 SRAM、RTC、LSE),那么待机模式下的功耗,将达到 3.8uA 左右。

image-20240926220950578

image-20240926221020206

image-20240926221116457

2.3 相关寄存器介绍

2.3.1 系统控制寄存器(SCB_SCR)

image-20240926221315109

2.3.2 电源控制寄存器(PWR_CR)

image-20240926221441770

2.3.3 电源控制/状态寄存器(PWR_CSR)

image-20240926222647713

2.3.4 WFI与WFE指令

image-20240926222930635

内核指令,使用函数的格式__WFI()__WFE()来调用。__wfi__wfe是编译器内置的函数,函数内部调用了相对应的汇编指令。

驱动函数关联寄存器功能描述
HAL_PWR_EnterSLEEPMode(…)SCB_SCR进入睡眠模式
HAL_PWR_EnterSTOPMode(…)PWR_CR/SCB_SCR进入停止模式
HAL_PWR_EnterSTANDBYMode(…)PWR_CR/SCB_SCR进入待机模式
HAL_PWR_EnableWakeUpPin(…)PWR_CSR使能WKUP管脚唤醒功能
__HAL_PWR_CLEAR_FLAG(…)PWR_CR清除PWR的相关标记
__HAL_RCC_PWR_CLK_ENABLE(…)RCC_APB1ENR使能电源时钟

3. 进入低功耗模式的使用步骤

image-20240926223519705

image-20240926223555882

在退出停止模式后,需要重新设置时钟、重新选择滴答时钟源、失能systick中断

image-20240926223650224

待机模式配置步骤

  1. 初始化WKUP为中断触发源
  2. 使能电源时钟:__HAL_RCC_PWR_CLK_ENABLE
  3. 使能WKUP的唤醒功能:HAL_PWR_EnableWakeUpPin
  4. 清除唤醒标记WUF:__HAL_PWR_CLEAR_FLAG
  5. 进入待机模式:HAL_PWR_EnterSTANDBYMode

4. 代码解析

驱动函数关联寄存器功能描述
HAL_PWR_EnterSLEEPMode(…)SCB_SCR进入睡眠模式
HAL_PWR_EnterSTOPMode(…)PWR_CR/SCB_SCR进入停止模式
HAL_PWR_EnterSTANDBYMode(…)PWR_CR/SCB_SCR进入待机模式
HAL_PWR_EnableWakeUpPin(…)PWR_CSR使能WKUP管脚唤醒功能
__HAL_PWR_CLEAR_FLAG(…)PWR_CR清除PWR的相关标记
__HAL_RCC_PWR_CLK_ENABLE(…)RCC_APB1ENR使能电源时钟
#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
#include "./BSP/LED/led.h"
#include "./BSP/BEEP/beep.h"
#include "./BSP/KEY/key.h"
#include "./BSP/PWR/pwr.h"void pwr_wkup_key_init(void)
{GPIO_InitTypeDef gpio_init_struct;PWR_WKUP_GPIO_CLK_ENABLE();                             /* WKUP引脚时钟使能 */gpio_init_struct.Pin = PWR_WKUP_GPIO_PIN;               /* WKUP引脚 */gpio_init_struct.Mode = GPIO_MODE_IT_RISING;            /* 中断,上升沿 */gpio_init_struct.Pull = GPIO_PULLDOWN;                  /* 下拉 */gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;          /* 高速 */HAL_GPIO_Init(PWR_WKUP_GPIO_PORT, &gpio_init_struct);   /* WKUP引脚初始化 */HAL_NVIC_SetPriority(PWR_WKUP_INT_IRQn, 2, 2);          /* 抢占优先级2,子优先级2 */HAL_NVIC_EnableIRQ(PWR_WKUP_INT_IRQn); 
}void PWR_WKUP_INT_IRQHandler(void)
{HAL_GPIO_EXTI_IRQHandler(PWR_WKUP_GPIO_PIN);
}void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{if (GPIO_Pin == PWR_WKUP_GPIO_PIN){/* HAL_GPIO_EXTI_IRQHandler()函数已经为我们清除了中断标志位,所以我们进了回调函数可以不做任何事 */}
}int main(void)
{uint8_t key;uint8_t t = 0;HAL_Init();                             /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9);     /* 设置时钟, 72Mhz */delay_init(72);                         /* 延时初始化 */usart_init(115200);                     /* 串口初始化 */led_init();                             /* 初始化LED */key_init();                             /* 初始化按键 */pwr_wkup_key_init();                    /* WKUP引脚初始化 */pwr_pvd_init();                         /* PVD配置 */printf("Enter to LowPower Test \r\n");while(1){key = key_scan(0);                  /* 得到键值 */if (key){switch (key){/* 进入待机模式 */case KEY2_PRES:/* 使能电源时钟 */__HAL_RCC_PWR_CLK_ENABLE();/* 使能WKUP上升沿的唤醒功能 */HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN1);/* 清除唤醒标记 */__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);printf("Enter STANDBY Mode \r\n");HAL_PWR_EnterSTANDBYMode();printf("Exit STANDBY Mode \r\n");break;/* 进入停止模式 */case KEY1_PRES:LED1(0);        /* 点亮绿灯,提示进入停止模式 */printf("Enter STOP Mode \r\n");HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_SLEEPENTRY_WFI);sys_stm32_clock_init(RCC_PLL_MUL9);     /* 重新设置时钟, 72Mhz */HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK_DIV8);HAL_SuspendTick();printf("Exit STOP Mode \r\n");LED1(1);break;/* 进入睡眠模式 */case KEY0_PRES:printf("Enter SLEEP Mode \r\n");HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);printf("Exit SLEEP Mode \r\n");break;} }if ((t % 20) == 0){LED0_TOGGLE();              /* 每200ms,翻转一次LED0 */}delay_ms(10);t++;}
}

http://www.ppmy.cn/news/1533641.html

相关文章

C# C++ 笔记

第一阶段知识总结 lunix系统操作 1、基础命令 (1)cd cd /[目录名] 打开指定文件目录 cd .. 返回上一级目录 cd - 返回并显示上一次目录 cd ~ 切换到当前用户的家目录 (2)pwd pwd 查看当前所在目录路径 pwd -L 打印当前物理…

Redis: Sentinel节点管理,故障迁移一致性以及TILT模式

节点管理 节点管理指的是在我们环境正常的情况下,我们想要动态的去添加或者删除节点 1 )添加 Sentinel 添加单个 Sentinel 如果在一个环境中,我们想要去添加 Sentinel,实际上是非常简单的因为基于 Sentinel 自动发现的机制 我…

同人小游戏之斗罗大陆

前言 hello&#xff0c;大家好&#xff0c;我是文宇。 最近我好久没写文章了&#xff0c;今天写一章 文章图片没找到&#xff0c;临时拿了一张 正文 #include<iostream> #include<conio.h> #include<windows.h> #include<stdlib.h> #include<st…

Electron 使⽤ electron-builder 打包应用

electron有几种打包方式&#xff0c;我使用的是electron-builder。虽然下载依赖的时候让我暴躁&#xff0c;使用起来也很繁琐&#xff0c;但是它能进行很多自定义&#xff0c;打包完成后的体积也要小一些。 安装electron-builder&#xff1a; npm install electron-builder -…

Pytorch基本知识

model.state_dict()、model.parameters()和model.named_parameters()的区别 parameters()只包含模块的参数,即weight和bias(包括BN的)。 named_parameters()返回包含模块名和模块的参数的列表,列表的每个元素均是包含layer name和layer param的元组。layer param就是param…

在实时语音交互上超过GPT-4o,端到端语音模型Mini-Omni部署

Mini-Omni是清华大学开源的多模态大型语言模型&#xff0c;具备实时语音输入和流式音频输出的能力。 Mini-Omni模型能够一边听、一边说&#xff0c;一边思考&#xff0c;类似于ChatGPT的语言对话模式。 Mini-Omni模型的主要特点是能够直接通过音频模态进行推理&#xff0c;并…

Android——ContentObserver监听短信

概述 内容观察器ContentObserver给目标内容注册一个观察器&#xff0c;目标内容的数据一旦发生变化&#xff0c;观察器规定好的动作马上触发&#xff0c;从而执行开发者预先定义的代码。 思路 注册一个监听 getContentResolver().registerContentObserver(uri, true, mObser…

【chrome 插件】初窥

目录结构 -----manifest.json #配置文件 |----content.js #对应操纵浏览器页面 |----background.js #一直运行在后台&#xff0c;负责持久化数据, 负责与服务器交互数据 |----popup.js #自动配置到 popup.html, 有权限操纵 popup.html |----popup.html #插件页面其中 popup.j…