细说STM32F407单片机电源低功耗StopMode模式及应用示例

目录

一、停止模式基础知识

1、进入停止模式

2、停止模式的状态

3、退出停止模式

4、SysTick定时器的影响

二、停止模式应用示例

1、示例功能和CubeMX项目配置

(1)时钟

(2)RTC

(3)ADC1

(4) NVIC

(5)DEBUG、LED1、USART6、CodeGenerator

2、软件设计

(1)KEYLED 

(2)main.h

(3)main.c

3、运行并调试


一、停止模式基础知识

1、进入停止模式

        用户可以通过执行WFI指令或WFE指令进入停止模式。进入停止模式之前,用户需要将Cortex-M4F系统控制寄存器SCR的SLEEPDEEP位置1,内部调压器可以设置为正常运行或低功耗模式。函数HAL_PWR_EnterSTOPMode()用于进入停止模式,其源代码如下:

        函数HAL_PWR_EnterSTOPMode()用于进入停止模式,其源代码如下:

void HAL_PWR_EnterSTOPMode(uint32_t Regulator,uint8_t STOPEntry)
{/*Check the parameters */assert_param(IS_PWR_REGULATOR(Regulator));assert_param(IS_PWR_STOP_ENTRY(STOPEntry));/*设置调压器的模式:根据参数Regulator设置PDDS位和LPDS位*/MODIFY_REG(PWR->CR,(PWR_CR_PDDS I PWR_CR_LPDS),Regulator);/*将Cortex系统控制寄存器SCR的SLEEPDEEP位置1*/SET_BIT(SCB->SCR,((uint32_t)SCB_SCR_SLEEPDEEP_Msk));/*Select Stop mode entry*/if(STOPEntry == PWR_STOPENTRY_WFI){/*Request Wait For Interrupt */__WFI();}else{/*Request Wait For Event */__SEV();__WFE();__WFE();}/*唤醒后,将SLEEPDEEP位清零*/CLEAR_BIT(SCB->SCR,((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
}

        参数Regulator用于表示调压器在停止模式下的工作方式,取值为宏定义常量PWR_MAINREGULATOR_ON(调压器正常运行)或PWR_LOWPOWERREGULATOR_ON(调压器处于低功耗模式)。

        参数SLEEPEntry表示用何种指令进入睡眠模式,WFI或WFE指令。其取值为宏定义常量PWR_SLEEPENTRY_WFI或PWR_SLEEPENTRY_WFE。

        函数HAL_PWR_EnterSTOPMode()在进入停止模式之前,将Cortex-M4F系统控制寄存器SCR的SLEEPDEEP位置1,被唤醒后再将SLEEPDEEP位清零。

        特别地,要进入停止模式,所有EXTI线的中断挂起标志都必须清零,否则,将忽略进入停止模式的操作,而继续执行程序

        在停止模式下,可以保持或关闭Flash的电源,在进入停止模式之前,可以使用以下两个函数进行设置。

HAL_PWREX_EnableFlashPowerDown();  //关闭Flash的电源
HAL_PWREx_DisableFlashPowerDown(); //不关闭Flash的电源

2、停止模式的状态

        进入停止模式后,系统的状态如下。

  • CPU的时钟关闭,CPU停止运行,也就是程序暂停。
  • 所有1.2V域外设的时钟停止,外设停止工作。
  • ADC和DAC不会自动停止工作,需要编程使其停止。
  • 1.2V调压器开启或处于低功耗状态,所有寄存器、SRAM的内容保留。
  • Flash处于正常模式或掉电模式。
  • HSI振荡器和HSE振荡器关闭。

3、退出停止模式

        如果使用WFI指令进入停止模式,所有配置为中断模式的EXTI线都可以唤醒系统。由中断唤醒后,先执行中断的ISR,然后执行WFI指令后面的程序。

        如果使用WFE指令进入停止模式,所有配置为事件模式的EXTI线都可以唤醒系统,唤醒后执行WFE后面的程序。

        EXTI线共23根,EXTI线0:15对应于外部引脚中断,EXTI线16:22对应一些内部事件,如RTC闹钟事件、RTC周期唤醒事件等。

        从停止模式唤醒时,系统有一定的唤醒延迟时间,包括以下几个时间。

  • HSI振荡器的启动时间。系统将重新启动HSI振荡器,并且将HSI作为HCLK的时钟源。对STM32F407来说,HSI频率为16MHz,使用HSI作为时钟源的HCLK最高频率为16MHz。如果需要系统从停止模式唤醒后使用更高频率的HCLK,需要重新配置系统时钟。
  • 如果调压器处于低功耗模式,需要从低功耗模式恢复到正常模式的时间。
  • 若Flash处于掉电模式,需要从掉电模式恢复到正常模式的时间。

        在停止模式下,如果调压器处于低功耗模式、Flash处于掉电模式,则可以降低停止模式的功耗,但这同时也会增加唤醒延迟。

4、SysTick定时器的影响

        MCU进入停止模式后,将只会由EXTI中断或事件唤醒,而不受SysTick定时器的影响。此外,在进入停止模式后,所有的1.2V域外设都会停止工作,SysTick定时器其实也停止了。

二、停止模式应用示例

        本文将创建一个示例项目,测试系统的STOP模式。继续使用旺宝红龙开发板STM32F407ZGT6 KIT V1.0。一些设置参考本文作者的其他文章。

        参考文章:细说STM32F407单片机电源低功耗SleepMode模式及应用示例-CSDN博客  https://wenchm.blog.csdn.net/article/details/145226004

1、示例功能和CubeMX项目配置

        本文演示MCU的停止模式。示例的功能和操作流程如下。

  • 在主程序的while循环里,让MCU进入停止模式。
  • 使用RTC的周期唤醒中断,使MCU从停止模式唤醒,RTC唤醒周期为5s。
  • MCU从停止模式唤醒后,进行一次轮询方式ADC转换。

(1)时钟

        禁用HSE,这样做很重要,因为不这样做,依旧设置外部时钟的话,系统将不能清空EXTI的中断线标志位。将HSI直接作为HCLK时钟源,HCLK设置为16MHz。因为MCU从停止模式唤醒后,自动使用HSI作为SYSCLK时钟源,所以,如果要使用HSE或更高频率的HCLK,需要重新配置系统时钟。本示例在系统唤醒后,不再配置HCLK时钟频率,故正常运行时也使用HSI作为HCLK时钟源。

(2)RTC

        并使用LSE作为RTC的时钟源。开启RTC的周期唤醒功能,

        并设置唤醒时钟为1Hz信号,唤醒计数值为4。RTC的周期唤醒使用的是EXTI线22中断,在NVIC中开启RTC周期唤醒中断,设置其抢占优先级为1。这样设置后,每5s发生一次EXTI线22中断。

(3)ADC1

        启用ADC1的内部参考电压通道,设置为12位精度、右对齐、软件触发转换。ADC1的参数设置结果如图。

 

(4) NVIC

 

(5)DEBUG、LED1、USART6、CodeGenerator

        同参考文章。 

2、软件设计

(1)KEYLED 

        本示例工程继续引用KEYLED文件夹中的keyled.h,详见参考文章。

(2)main.h

        声明一个函数,用于EXTI线清零。 

/* USER CODE BEGIN Private defines */
void EXTI_ClearITPendingBit();
/* USER CODE END Private defines */

(3)main.c

/* USER CODE BEGIN Includes */
#include "keyled.h"
#include <stdio.h>	//用到函数sprintf()
#include <string.h>	//用到函数strlen()
/* USER CODE END Includes */
/* USER CODE BEGIN 2 */printf("Demo22_2_StopMode:Test Stop Mode.\r\n");printf("Wake up by RTC every 5s.\r\n");//如果配置了FSMC//HAL_PWREx_EnableFlashPowerDown();	//在停止模式下关闭Flash电源//HAL_PWREx_DisableFlashPowerDown();	//不关闭Flash电源/* USER CODE END 2 */
 /* USER CODE BEGIN 3 */LED1_OFF();								//LED1熄灭//以下3种清零除EXTI线pending位的方法都是正确的,确保能进入STOP模式//EXTI->PR = 0; 						//将EXTI线的pending位清零EXTI->PR = EXTI_PR_PR0 << 22; 		    //将EXTI线22的pending位清零//EXTI_ClearITPendingBit(EXTI_PR_PR22);	//将EXTI线22的pending位清零//进入停止模式, WFI指令进入HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON,PWR_SLEEPENTRY_WFI);//RTC周期唤醒中断(EXTI22)唤醒系统LED1_ON();HAL_ADC_Start(&hadc1);		//使能ADC1并开始转换,内部通道参考电压if (HAL_ADC_PollForConversion(&hadc1,200) == HAL_OK){uint32_t val = HAL_ADC_GetValue(&hadc1) & 0x0000FFFF;	//12位数uint32_t Volt = 3300*val;	//单位:mVVolt = Volt>>12;			//除以2^12printf("ADC Voltage(mV) = %ld\r\n",Volt);}HAL_ADC_Stop(&hadc1);		//停止ADC1HAL_Delay(500);				//消除按键抖动影响,并且使LED1亮500ms}/* USER CODE END 3 */

        在进入while循环之前,调用了函数HAL_PWREx_EnableFlashPowerDown(),这可以在MCU进入停止模式后,关闭Flash存储器的电源,进一步降低功耗。也可以不关闭Flash存储器电源,也就是调用函数HAL_PWREx_DisableFlashPowerDown()(可选)。

        在while循环里,调用函数HAL PWR EnterSTOPMode()使系统进入停止模式。必须在所有EXTI线中断的挂起标志位清零的情况下,才能进入停止模式。为此,直接将外部中断挂起标志寄存器PR的内容清零,即执行语句:

EXTI->PR =0;

        进入停止模式后,CPU停止运行,程序暂停,所有外设停止工作,但RTC仍能正常工作。停止模式可以由任意EXTI线的中断或事件唤醒,RTC的周期唤醒中断是EXTI线22。本示例中设置的RTC唤醒周期是5s,所以,在发生RTC周期唤醒中断时系统会被唤醒,但是会先执行RTC中断的ISR,也就是会执行RTC周期唤醒回调函数HAL_RTCEx_WakeUpTimerEventCallback(),这个回调函数里读取RTC当前时间并显示在串口助手上。RTC中断的ISR退出后,再继续执行WFI指令后面的程序。后面的程序用轮询方式进行一次ADC转换,将结果显示在串口助手上。ADC转换结束后停止,然后MCU又进入停止模式。

/* USER CODE BEGIN 4 */
// RTC 周期唤醒中断回调函数
void HAL_RTCEx_WakeUpTimerEventCallback(RTC_HandleTypeDef *hrtc)
{RTC_TimeTypeDef sTime;RTC_DateTypeDef sDate;if (HAL_RTC_GetTime(hrtc,&sTime,RTC_FORMAT_BIN) == HAL_OK){HAL_RTC_GetDate(hrtc,&sDate,RTC_FORMAT_BIN);uint8_t	str[30];sprintf((char *)str,"%2d:%2d:%2d",sTime.Hours,sTime.Minutes,sTime.Seconds);//HAL_UART_Transmit(&huart6,str,strlen ((const char *)(str)),200);printf("RTC current time: %s\r\n",str);}
}//清除EXTI线[0:22]的Pending register
void EXTI_ClearITPendingBit(uint32_t EXTI_Line)
{/* Check the parameters */assert_param(IS_EXTI_LINE(EXTI_Line));EXTI->PR = EXTI_Line;
}int __io_putchar(int ch)
{HAL_UART_Transmit(&huart6,(uint8_t*)&ch,1,0xFFFF);return ch;
}
/* USER CODE END 4 */

3、运行并调试

        运行时会发现:每隔5s串口助手上刷新显示一次RTC时间和ADC转换结果,LED1点亮500ms后熄灭。

        停止模式比较适合于需要周期性唤醒,执行完一些操作后又进入低功耗模式的应用。例如,网络化的温度监测,可能每隔60s才需要测量一次数据并通过网络发送出去,使用周期唤醒的停止模式就可以大大降低功耗。 

        在CubeMX里可以对本示例进行功耗计算。因为使用了16MHz的HCLK,RUN模式下的耗电流是8.78mA,STOP模式下的耗电流是280μA。如果还选用3400mAh的锂电池供电,如果一个序列中RUN模式持续10ms,STOP模式持续100ms,电池可以用4月1210小时;若修改为STOP模式持续1000ms,其他参数不变,电池可以用1年28,可见降低功耗的效果是非常明显的。

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

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

相关文章

JavaScript学习笔记(1)

html 完成了架子&#xff0c; css 做了美化&#xff0c;但是网页是死的&#xff0c;我们需要给他注入灵魂&#xff0c;所以接下来我们需要学习 JavaScript&#xff0c;这门语言会让我们的页面能够和用户进行交互。 一、引入方式 1.内部脚本 将 JS 代码定义在 HTML 页面中 Jav…

【三维分割】Gaga:通过3D感知的 Memory Bank 分组任意高斯

文章目录 摘要一、引言二、主要方法2.1 3D-aware Memory Bank2.2 三维分割的渲染与下游应用 三、实验消融实验应用: Scene Manipulation 地址&#xff1a;https://www.gaga.gallery 标题&#xff1a;Gaga: Group Any Gaussians via 3D-aware Memory Bank 来源&#xff1a;加利福…

Day 14 卡玛笔记

这是基于代码随想录的每日打卡 226. 翻转二叉树 给你一棵二叉树的根节点 root &#xff0c;翻转这棵二叉树&#xff0c;并返回其根节点。 示例 1&#xff1a; 输入&#xff1a;root [4,2,7,1,3,6,9] 输出&#xff1a;[4,7,2,9,6,3,1]示例 2&#xff1a; 输入&#xff1a;r…

|Python新手小白中级教程|第三十章:日期与时间(入门)

文章目录 前言一、日期与时间的基本概念二、时间戳1.概念2.形成过程 三、Python的时间格式化符号四、时间元组1.时间元组&#xff1a;2.struct_time元组的属性 五、time库可以干什么总结 前言 大家好呀&#xff0c;BOBO仔回来啦。 说实话&#xff0c;这几天我们学习面向对象的…

代码随想录刷题day13|(链表篇)24.两两交换链表中的结点

目录 一、链表理论基础 二、思路及易错点 易错点 三、相关算法题目 四、错误代码分析 一、链表理论基础 代码随想录 (programmercarl.com) 二、思路及易错点 该题使用虚拟头结点正常进行模拟即可&#xff0c;有两个关键点&#xff0c;一是循环何时终止&#xff1f;终止…

PIC单片机设置bootloader程序和app程序地址方法

在调试bootloader和app程序的时候通常都需要设置程序的偏移地址&#xff0c;下面就总结一下使用MPLAB X IDE 设置程序地址的方法。 打开bootloader工程 工程上单击鼠标右键&#xff0c;选择Properties,打工工程属性窗口。 此时会打开项目属性对话框 左边类别选择XC8 Line…

51c大模型~合集105

我自己的原文哦~ https://blog.51cto.com/whaosoft/13101924 #刚刚&#xff0c;ChatGPT开始有了执行力&#xff01; 现在 AI 智能体可以 24*7 小时为你打工。 2025 刚过去了半个月&#xff0c;OpenAI 在智能体领域「开大」了。 今天&#xff0c;OpenAI 正在为 ChatGPT 推出…

迅为龙芯2K1000开发板/核心板流畅运行Busybox、Buildroot、Loognix、QT5.12系统

硬件配置 国产龙芯处理器&#xff0c;双核64位系统&#xff0c;板载2G DDR3内存&#xff0c;流畅运行Busybox、Buildroot、Loognix、QT5.12 系统! 接口全板载4路USB HOST、2路千兆以太网、2路UART、2路CAN总线、Mini PCIE、SATA固态盘接口、4G接口、GPS接口WIF1、蓝牙、Mini H…

StarRocks强大的实时数据分析

代码仓库&#xff1a;https://github.com/StarRocks/starrocks?tabreadme-ov-file StarRocks | A High-Performance Analytical Database 快速开始&#xff1a;StarRocks | StarRocks StarRocks 是一款高性能分析型数据仓库&#xff0c;使用向量化、MPP 架构、CBO、智能物化…

web前端1--基础

&#xff08;时隔数月我又来写笔记啦~&#xff09; 1、下载vscode 1、官网下载&#xff1a;Visual Studio Code - Code Editing. Redefined 2、步骤&#xff1a; 1、点击同意 一直下一步 勾一个创建桌面快捷方式 在一直下一步 2、在桌面新建文件夹 拖到vscode图标上 打开v…

基于tldextract提取URL里的子域名、主域名、顶级域

TLD是TopLevel Domain的缩写。‌tldextract‌ 是一个用于从URL中提取子域、主域名和顶级域&#xff08;TLD&#xff09;的Python库。它利用公共后缀列表&#xff08;Public Suffix List&#xff09;来确保即使是复杂或不常见的URL结构也能被正确解析。tldextract能够处理包括IC…

音频入门(一):音频基础知识与分类的基本流程

音频信号和图像信号在做分类时的基本流程类似&#xff0c;区别就在于预处理部分存在不同&#xff1b;本文简单介绍了下音频处理的方法&#xff0c;以及利用深度学习模型分类的基本流程。 目录 一、音频信号简介 1. 什么是音频信号 2. 音频信号长什么样 二、音频的深度学习分…

数据结构之堆排序

文章目录 堆排序版本一图文理解 版本二向下调整建堆向上调整建堆 排升/降序升序 堆排序 版本一 基于已有数组建堆取堆顶元素并删除堆顶元素重新建大根堆&#xff0c;完成排序版本。 图文理解 版本二 前提&#xff1a;必须提供有现成的数据结构堆 数组建堆&#xff0c;首尾…

小菜鸟系统学习Python第三天

1.优先级问题: 结论: 幂运算>正负号>加减乘除和整除>比较运算符>逻辑运算符 2.三元运算符 3.assert断言:抛出AssertionError异常 4.for循环 4. 5.break和continue

常用排序算法之插入排序

目录 前言 一、基本原理 1.算法步骤 2.动画演示 3.插入排序的实现代码 二、插入排序的时间复杂度 1. 时间复杂度 1.最优时间复杂度 2.最差时间复杂度 3.平均时间复杂度 2. 空间复杂度 三、插入排序的优缺点 1.优点 2.缺点 四、插入排序的改进与变种 五、插入排…

数据分析及应用:经营分析中的综合指标解析与应用

目录 1. 市场份额(Market Share) 2. 客户获取成本(Customer Acquisition Cost, CAC) 3. 客户生命周期价值(Customer Lifetime Value, CLV) 4. 客户留存率(Customer Retention Rate, CRR) 5. 净推荐值(Net Promoter Score, NPS) 6. 转化率(Conversion Rate) …

工业相机 SDK 二次开发-Halcon 插件

本文介绍了 Halcon 连接相机时插件的使用。通过本套插件可连接海康 的工业相机。 一. 环境配置 1. 拷贝动态库 在 用 户 安 装 MVS 目 录 下 按 照 如 下 路 径 Development\ThirdPartyPlatformAdapter 找到目录为 HalconHDevelop 的文 件夹&#xff0c;根据 Halcon 版本找到对…

【Vim Masterclass 笔记25】S10L45:Vim 多窗口的常用操作方法及相关注意事项

文章目录 S10L45 Working with Multiple Windows1 水平分割窗口2 在水平分割的新窗口中显示其它文件内容3 垂直分割窗口4 窗口的关闭5 在同一窗口水平拆分出多个窗口6 关闭其余窗口7 让四个文件呈田字形排列8 光标在多窗口中的定位9 调节子窗口的尺寸大小10 变换子窗口的位置11…

Linux TCP 之 RTT 采集与 RTO 计算

我们来看看 Linux TCP 采集 RTT 的函数 tcp_rtt_estimator&#xff0c;看注释&#xff0c;充满了胶着。 但在那个谨慎的年代&#xff0c;这些意味着什么&#xff1f; RTT 最初仅用于 RTO 的计算而不是用于调速&#xff0c;RTO 的计算存在两个问题&#xff0c;如果过估&#x…

如何使用CRM数据分析优化销售和客户关系?

嘿&#xff0c;大家好&#xff01;你有没有想过为什么有些公司在市场上如鱼得水&#xff0c;而另一些却在苦苦挣扎&#xff1f;答案可能就藏在他们的销售策略和客户关系管理&#xff08;CRM&#xff09;系统里。今天我们要聊的就是如何通过有效的 CRM 数据分析来提升你的销售额…