当前位置: 首页 > news >正文

【STM32笔记】低功耗模式下GPIO、外设、时钟省电配置避坑

【STM32笔记】低功耗模式下GPIO、外设、时钟省电配置避坑

前文:
blog.csdn.net/weixin_53403301/article/details/128216064
【STM32笔记】HAL库低功耗模式配置(ADC唤醒无法使用、低功耗模式无法烧录解决方案)

blog.csdn.net/weixin_53403301/article/details/129055530
【STM32笔记】低功耗模式下GPIO省电配置避坑实验(闲置引脚配置为模拟输入其实更耗电)

在这里插入图片描述
在进入低功耗模式前 可以通过降低时钟频率 关闭GPIO口(通常是配置为模拟输入 或降低GPIO时钟) 以及关闭不需要的外设来降低功耗(尤其是在SLEEP、STOP模式)

时钟的话 如果用不上 或者进入STOP等模式 则也不需要配置 进入模式时 时钟本身就会被配置

关闭外设的函数在进入低功耗的前一步执行 相关唤醒配置需要在关闭外设前执行 且要注意 不能关闭用于唤醒的外设及其GPIO口

而用不到的外设和对应的GPIO口 建议同时关闭

以我的为例:

/*!* @brief       	所有外设初始化配置,根据使用需求来写** @param 	[in]	EnableNotDisable: 使能或者关闭*								true: 进行初始化外设(不包含时钟初始化)*								false: 或者关闭所有外设,所有GPIO配置为无上拉下拉且模拟输入,仅保留系统时钟和系统所需的GPIO口复用*								该函数在进入低功耗前调用(false)*								建议在进入该函数前(false)先配置用于唤醒的外设 如指定UART或RTC作为唤醒使用 然后再调用该函数 且不能关闭有唤醒功能的外设*								若用于唤醒后的初始化,则建议先初始化时钟,再执行该函数的初始化(true)*								在休眠期间使用的外设,不要关闭,也不要关闭GPIO等;相反,外设和GPIO等建议同时关闭(避免出现bug,并且也省电)*								未关闭,但唤醒时重复初始化外设并不受影响*								若未关闭的外设在运行中改变了初始化值,则建议不在唤醒时运行该初始化(前提是外设的GPIO等也没有作改动)*								若需要在初始化后更改初始化值,则建议要么不进行初始化且不关闭(也包括GPIO等),或重新设置新值** @return				None*/
void PWR_Device_Init(bool EnableNotDisable)
{if(EnableNotDisable){//这里是系统最初的初始化值GPIO_Reset_Init(false);  //重置GPIO		MX_GPIO_Init();MX_USART2_UART_Init();MX_UART4_Init();MX_ADC1_Init();MX_ADC2_Init();MX_TIM6_Init();MX_RTC_Init();MX_ADC3_Init();//这里放初始化后还要更改的配置,若要重新初始化,建议先运行外设DeInit
//		HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8,GPIO_PIN_SET);
//		HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4,GPIO_PIN_SET);}else{HAL_ADC_DeInit(&hadc1);HAL_ADC_DeInit(&hadc2);HAL_ADC_DeInit(&hadc3);
//		HAL_UART_DeInit(&huart2);		//唤醒用的串口 最好不要关闭:若不用于唤醒 则可以关闭 GPIO等同步关闭;若用于唤醒 则不能关闭 GPIO等也不能关闭HAL_UART_DeInit(&huart4);HAL_TIM_Base_DeInit(&htim6);
//		HAL_RTC_DeInit(&hrtc);		//唤醒用的RTC 最好不要关闭		GPIO_Reset_Init(true);  //GPIO配置为复用}
}
  •  						true: 进行初始化外设(不包含时钟初始化)
    
  •  						false: 或者关闭所有外设,所有GPIO配置为无上拉下拉且模拟输入,仅保留系统时钟和系统所需的GPIO口复用
    
  •  						该函数在进入低功耗前调用(false)
    
  •  						建议在进入该函数前(false)先配置用于唤醒的外设 如指定UART或RTC作为唤醒使用 然后再调用该函数 且不能关闭有唤醒功能的外设
    
  •  						若用于唤醒后的初始化,则建议先初始化时钟,再执行该函数的初始化(true)
    
  •  						在休眠期间使用的外设,不要关闭,也不要关闭GPIO等;相反,外设和GPIO等建议同时关闭(避免出现bug,并且也省电)
    
  •  						未关闭,但唤醒时重复初始化外设并不受影响
    
  •  						若未关闭的外设在运行中改变了初始化值,则建议不在唤醒时运行该初始化(前提是外设的GPIO等也没有作改动)
    
  •  						若需要在初始化后更改初始化值,则建议要么不进行初始化且不关闭(也包括GPIO等),或重新设置新值
    

GPIO配置也是个坑
(相关配置及唤醒功能等 见前文)

/*!* @brief       	重置GPIO(都会进行),或再将除外部高低速晶振复用、SWCLK、SWDIO复用的所有GPIO配置为模拟输入(false)*								注意:用于串口唤醒等的引脚,不可配置为模拟输入,也不可关闭*								在进行GPIO初始化前,先将GPIO_DeInit,但是不做也不影响,不过还是建议跑一下*								以优先级顺序来看:*								如果这一组GPIO都没用到过 那么直接不开启时钟就最省电*								如果这一组GPIO有引脚用过了 时钟不能关 那么就将用过的引脚配置为模拟输入*								切记!!!:*								不要将没用过的引脚配置为模拟输入 耗电量其实会稍微增加一点!*								不要将没用过的GPIO时钟打开以后再配置为模拟输入 耗电量会增加很多 就算配置后再关时钟也没用!*								尽量不要勾选CubeMX中的配置闲置引脚为模拟输入的选项 没用到的时钟还开启了会增加很多耗电*								低功耗模式配置:*								在进入STOP模式时 GPIO会保留原本的状态 所以把开启后不需要再保留的GPIO配置为模拟输入确实省电 时钟的话不用的肯定关 其他的反正都会关(除了保留的时钟)*								在进入SLEEP模式时 时钟并不会关闭 所以时钟应手动关闭 且将开启后的GPIO配置为模拟输入*								待机模式和关机模式就更不用在意GPIO口耗电了*								https://blog.csdn.net/weixin_53403301/article/details/129055530** @param 	[in]	EnableNotDisable: 使所有GPIO变成模拟输入或不进行模拟配置** @return				None*/
void GPIO_Reset_Init(bool EnableNotDisable)
{
//	HAL_GPIO_DeInit(GPIOA,GPIO_PIN_2|GPIO_PIN_3);		//用于串口唤醒的引脚 不可变动HAL_GPIO_DeInit(GPIOA,GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_15);HAL_GPIO_DeInit(GPIOB,GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9);HAL_GPIO_DeInit(GPIOC,GPIO_PIN_13|GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12);HAL_GPIO_DeInit(GPIOD,GPIO_PIN_2);HAL_GPIO_DeInit(GPIOH,GPIO_PIN_3);if(EnableNotDisable){GPIO_InitTypeDef GPIO_InitStruct = {0};/* GPIO Ports Clock Enable */__HAL_RCC_GPIOC_CLK_ENABLE();__HAL_RCC_GPIOH_CLK_ENABLE();__HAL_RCC_GPIOA_CLK_ENABLE();__HAL_RCC_GPIOB_CLK_ENABLE();__HAL_RCC_GPIOD_CLK_ENABLE();/*Configure GPIO pins : PC13 PC0 PC1 PC2PC3 PC4 PC5 PC6PC7 PC8 PC9 PC10PC11 PC12 */GPIO_InitStruct.Pin = GPIO_PIN_13|GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12;GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;GPIO_InitStruct.Pull = GPIO_NOPULL;HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);/*Configure GPIO pins : PA0 PA1 PA2 PA3PA4 PA5 PA6 PA7PA8 PA9 PA10 PA11PA12 PA15 */GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_15;GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;GPIO_InitStruct.Pull = GPIO_NOPULL;HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);//		//用于串口唤醒的 不可变动
//		GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3;
//		GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
//		GPIO_InitStruct.Pull = GPIO_NOPULL;
//		HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);/*Configure GPIO pins : PB0 PB1 PB2 PB10PB11 PB12 PB13 PB14PB15 PB3 PB4 PB5PB6 PB7 PB8 PB9 */GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9;GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;GPIO_InitStruct.Pull = GPIO_NOPULL;HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);/*Configure GPIO pin : PD2 */GPIO_InitStruct.Pin = GPIO_PIN_2;GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;GPIO_InitStruct.Pull = GPIO_NOPULL;HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);/*Configure GPIO pin : PH3 */GPIO_InitStruct.Pin = GPIO_PIN_3;GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;GPIO_InitStruct.Pull = GPIO_NOPULL;HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);}
}
  •  						注意:用于串口唤醒等的引脚,不可配置为模拟输入,也不可关闭
    
  •  						在进行GPIO初始化前,先将GPIO_DeInit,但是不做也不影响,不过还是建议跑一下
    
  •  						以优先级顺序来看:
    
  •  						如果这一组GPIO都没用到过 那么直接不开启时钟就最省电
    
  •  						如果这一组GPIO有引脚用过了 时钟不能关 那么就将用过的引脚配置为模拟输入
    
  •  						切记!!!:
    
  •  						不要将没用过的引脚配置为模拟输入 耗电量其实会稍微增加一点!
    
  •  						不要将没用过的GPIO时钟打开以后再配置为模拟输入 耗电量会增加很多 就算配置后再关时钟也没用!
    
  •  						尽量不要勾选CubeMX中的配置闲置引脚为模拟输入的选项 没用到的时钟还开启了会增加很多耗电
    
  •  						低功耗模式配置:
    
  •  						在进入STOP模式时 GPIO会保留原本的状态 所以把开启后不需要再保留的GPIO配置为模拟输入确实省电 时钟的话不用的肯定关 其他的反正都会关(除了保留的时钟)
    
  •  						在进入SLEEP模式时 时钟并不会关闭 所以时钟应手动关闭 且将开启后的GPIO配置为模拟输入
    
  •  						待机模式和关机模式就更不用在意GPIO口耗电了
    

而低功耗进入则改成了:
(相关配置及唤醒功能等 见前文)

printf("[INFO] 进入停止模式\n");
delay_ms(10);  //消抖
PWR_Device_Init(false);			
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON,PWR_SLEEPENTRY_WFI);
break;

同样 在唤醒后 唤醒回调里面也得先配置时钟再进行外设初始化

void HAL_UARTEx_WakeupCallback(UART_HandleTypeDef *huart)
{if(huart==&huart2){		__HAL_RCC_PWR_CLK_ENABLE();HAL_Init();SystemClock_Config();		Ctrl_UART_StopMode_WakeUp(huart,false);PWR_Device_Init(true);}
}void HAL_RTCEx_WakeUpTimerEventCallback(RTC_HandleTypeDef *hrtc)
{__HAL_RCC_PWR_CLK_ENABLE();HAL_Init();SystemClock_Config();Ctrl_RTC_WakeUp(0,0,false);PWR_Device_Init(true);
}

不过 HAL_Init可以省略 但是为了避免出现bug 还是放在这里.

调用的时候:

	Ctrl_UART_StopMode_WakeUp(&huart2,true);Ctrl_RTC_WakeUp(20000,RTC_WAKEUPCLOCK_RTCCLK_DIV16,true);Enter_Low_PWR(2,0);

先配置唤醒用的功能 再进入低功耗

当然 唤醒用的外设也需要在最开始进行初始化配置

相关文章:

【STM32笔记】低功耗模式下GPIO、外设、时钟省电配置避坑

【STM32笔记】低功耗模式下GPIO、外设、时钟省电配置避坑 前文: blog.csdn.net/weixin_53403301/article/details/128216064 【STM32笔记】HAL库低功耗模式配置(ADC唤醒无法使用、低功耗模式无法烧录解决方案) blog.csdn.net/weixin_534033…...

Linux内存分区(swap)

目录 1、使用物理分区创建内存交换分区 2、使用文件创建内存交换文件 当硬件的设备资源充足的话,那么swap是不会被我们的系统所使用到的,所以swap会被利用到的时刻通常就是物理内存不足的情况 我们知道CPU所读取的数据都来自于内存,那么当…...

第六章——抽样分布

文章目录1、统计量的定义2、常用的统计量3、经验分布函数4、正态总体常用统计量的分布4.1、卡方分布4.1.1、卡方分布的定义4.1.2、卡方分布的性质4.2、t分布4.2.1、t分布的定义4.2.2、t分布的性质4.3、F分布4.3.1、F分布的定义4.3.2、F分布的性质5、正态总体的样本均值与样本方…...

蓝桥云课-声网编程赛(声网编程竞赛7月专场)题解

比赛题目快速链接:https://www.lanqiao.cn/contests/lqENT02/challenges/ 让时钟转起来(考点:css:transform) // index.js function main() {// 题解前理解一个东西:// 时针每过一小时,转30 原…...

Java高手速成 | Java web 实训之投票系统

01、投票系统的案例需求 在本篇中,我们将制作一个投票系统,让学生给自己喜爱的老师投票。该系统由1个界面组成,系统运行,出现投票界面,如图所示: ▍显示效果 在这个界面中,标题为:“欢迎给教师投票”;在界面上有一个表格,显示了各位教师的编号、姓名、得票数;其中…...

排序的基本概念

按数据存储介质:内部排序和外部排序按比较器个数:串行排序和并行排序按主要操作:比较排序和基数排序插入排序:基本思想:每步将一个待排序的对象,按其关键码大小,插入到前面已经排好序的一组对象…...

面试笔试资料--Java

这里写自定义目录标题1.同步和异步有何异同?在什么情况下分别使用他们?举例说明1.同步和异步有何异同?在什么情况下分别使用他们?举例说明 1.1概念 Java中交互方式分为同步和异步两种:   同步交互:指发送…...

基于TC377的MACL-ADC General配置解读

目录标题一、MACL-ADC General1.Config Variant与AdcConfigSet2. AdcGeneral3.AdcPublishedInformation二、最终对应达芬奇生成内容一、MACL-ADC General 1.Config Variant与AdcConfigSet Config Variant :变体配置,默认选择VariantPostBuild就好了&…...

error: src refspec master does not match any.处理方案

问题描述 在使用git bash指令将项目上传到github时,总是遇到一些错误无法解决。 下面是我遇到的一个问题 error: src refspec master does not match any. error: failed to push some refs to XXXX.git 原因分析: 错误:SRC ReFSPEC主控器不…...

防火墙有关iptables的知识点

基本概念 什么是防火墙 在计算中,防火墙是基于预定安全规则来监视和控制传入和传出网络流量的网络安全系统。该计算机流入流出的所有网络通信均要经过此防火墙。防火墙对流经它的网络通信进行扫描,这样能够过滤掉一些攻击,以免其在目标计算机…...

路肩石水渠机在施工公路项目中工艺特点的匹配

新建公路路肩项目在目前公路项目中的技术手段和实现方式,大多数依靠机械设备来机械来进行,还有一部分通过人工传统的预制作业和安装模式来进行,两种工艺特点的对比来说对于补充完善建设手段和效果实现有很重要的意义. 其中采用了机械设备进行一次成型制作的过程,按照设计需求匹…...

JS 动态爱心(HTML+CSS+JS)

✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。 🍎个人主页:Java Fans的博客 🍊个人信条:不迁怒,不贰过。小知识,大智慧。 💞当前专栏…...

钉钉配置事件订阅(Python)

钉钉配置事件订阅 0.需求分析 需要实现钉钉企业通讯录同步至企业微信通讯录,这就需要用到钉钉的事件与回调 1.配置应用 登陆开放平台 https://open-dev.dingtalk.com/去企业内部开发里面,先创建个应用,后面都借用这个应用来调接口 创建完…...

Linux-Udev机制

一:Udev概述 udev 是一个用户空间的设备管理器,用于为事件设置处理程序。作为守护进程, udev 接收的事件主要由 linux 内核生成,这些事件是外部设备产生的物理事件。总之, udev 探测外设和热插拔,将设备控制权传递给内核,例如加载内核模块或设备固件。udev 是一个用户空…...

ERP是什么?中小商户有必要用吗?秦丝、金蝶、管家婆哪家强?

ERP系统刚开始传入中国的时候,基本上只有超大型或大型企业有条件实施,不过最近几年随着小微企业、中小商户的信息化需求不断增长,ERP软件已慢慢被普遍使用。但是仍然有不少中小商户,还没搞清楚ERP到底是什么,看到大家都…...

pytorch离线安装

windows下离线安装pytorch,很多内网机,无法连接外网,只能下载whl文件进行离线安装下载pytorch,地址https://download.pytorch.org/whl/torch_stable.html我是windows,Python37,没有gpu,所以选择…...

数据结构-算法的时间复杂度(1.1)

目录 1. 算法效率 2. 时间复杂度 2.1 时间复杂度的概念 2.2 大O的渐进表示法 2.3 举例说明: 写在最后: 1. 算法效率 我们该如何判断一个算法的好坏? 衡量一个算法的好坏,是从时间和空间两个维度比较的, 而今天…...

Cygwin安装与Mingw

共同点:window下编译环境 区别:cygwin(gnu windows)模拟Linux编译环境, mingw模拟window编译环境,生成.exe可执行文件 目录 Cygwin安装 一、官网下载 二、双击安装 三、选择安装路径后,到连接方式如图 四、添加连…...

教育舆情监测方案有哪些,TOOM讲解教育舆情的应对与处理?

教育舆情方案是针对教育领域的舆情事件或问题而制定的应对方案。其主要目的是通过有效的信息收集、分析、处理和传播,帮助教育机构或相关组织及时掌握和应对公众舆论的发展趋势,维护良好的舆情形象和声誉,教育舆情监测方案有哪些,…...

c语言操作文件

1、文件缓冲区 文件缓冲区的目的:提高访问效率 提高磁盘使用寿命 刷新就是将当前缓冲区数据全部提交。 不刷新时,程序在崩溃时缓冲区内容无法输出(有些情形会带来错误) 文件缓冲区的四种刷新方式 行刷新(遇到换行符…...

前端倒计时误差!

提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放

简介 前面两期文章我们介绍了I2S的读取和写入,一个是通过INMP441麦克风模块采集音频,一个是通过PCM5102A模块播放音频,那如果我们将两者结合起来,将麦克风采集到的音频通过PCM5102A播放,是不是就可以做一个扩音器了呢…...

[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...

Android15默认授权浮窗权限

我们经常有那种需求,客户需要定制的apk集成在ROM中,并且默认授予其【显示在其他应用的上层】权限,也就是我们常说的浮窗权限,那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...

分布式增量爬虫实现方案

之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面,避免重复抓取,以节省资源和时间。 在分布式环境下,增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路:将增量判…...

MySQL JOIN 表过多的优化思路

当 MySQL 查询涉及大量表 JOIN 时,性能会显著下降。以下是优化思路和简易实现方法: 一、核心优化思路 减少 JOIN 数量 数据冗余:添加必要的冗余字段(如订单表直接存储用户名)合并表:将频繁关联的小表合并成…...

【JavaSE】多线程基础学习笔记

多线程基础 -线程相关概念 程序(Program) 是为完成特定任务、用某种语言编写的一组指令的集合简单的说:就是我们写的代码 进程 进程是指运行中的程序,比如我们使用QQ,就启动了一个进程,操作系统就会为该进程分配内存…...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...

苹果AI眼镜:从“工具”到“社交姿态”的范式革命——重新定义AI交互入口的未来机会

在2025年的AI硬件浪潮中,苹果AI眼镜(Apple Glasses)正在引发一场关于“人机交互形态”的深度思考。它并非简单地替代AirPods或Apple Watch,而是开辟了一个全新的、日常可接受的AI入口。其核心价值不在于功能的堆叠,而在于如何通过形态设计打破社交壁垒,成为用户“全天佩戴…...

【前端异常】JavaScript错误处理:分析 Uncaught (in promise) error

在前端开发中,JavaScript 异常是不可避免的。随着现代前端应用越来越多地使用异步操作(如 Promise、async/await 等),开发者常常会遇到 Uncaught (in promise) error 错误。这个错误是由于未正确处理 Promise 的拒绝(r…...