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

news2025/1/19 17:56:28

目录

一、STM32F4的低功耗模式

1、睡眠(Sleep)模式

2、停止(Stop)模式

3、待机(Standby)模式

二、睡眠模式

1、进入睡眠模式

2、睡眠模式的状态

3、退出睡眠模式

4、SysTick的影响

三、应用示例

1、工程配置

(1) 时钟、DEBUG、GPIO、CodeGenerator

(2) USART6

(3) NVIC

2、软件设计

(1) main.h

(2)main.c

四、下载并调试


        电池供电的嵌入式系统一般非常注意功耗控制,尽量使系统的功耗最低。STM32F4系列MCU提供了多种运行模式,CubeMX也提供了功耗分析的功能。本文介绍STM32F4的SleepMode功耗模式,以及如何通过该功耗模式的控制实现系统的低功耗。

一、STM32F4的低功耗模式

        系统复位后,MCU处于正常运行模式。在正常运行模式下,CPU由HCLK时钟信号驱动连续执行程序指令。用户可以采取一些措施降低系统正常运行时的功耗,例如,可以降低HCLK时钟频率,或者将不使用的外设的时钟信号关闭。

        从main()函数的代码可以看出,在执行完各种初始化后,最后都是执行一个while()死循环。在while()循环里,通过轮询方式处理各种事务,或通过中断响应处理各种事务。在正常运行模式下,while()循环里的程序代码是一直执行的,即使一行代码都没有。所以在正常运行模式下,一般的嵌入式系统的CPU计算时间都是浪费的。

        除了正常运行模式,STM32F4系列MCU还有3种低功耗模式

1、睡眠(Sleep)模式

        Cortex-M4内核时钟停止,1.2V调压器正常工作,外设保持运行。通过WFI(wait for interrupt)或WFE(wait for event)指令进入睡眠模式。进入睡眠模式后,CPU不再执行新的代码。CPU可以被中断或事件唤醒,唤醒后继续执行进入睡眠点之后的代码。

2、停止(Stop)模式

        1.2V域所有时钟都停止,所有外设停止工作,内部调压器可以处于运行或低功耗模式,内部SRAM和寄存器的内容被保留,HSI和HSE振荡器关闭。通过EXTI中断或EXTI事件唤醒,CPU从停止处继续执行代码。

3、待机(Standby)模式

        调压器停止,1.2V域断电,内部SRAM和寄存器的内容丢失。只能通过SYS_WKUP引脚的上升沿、RTC闹钟事件、RTC唤醒事件、RTC入侵事件、NRST引脚外部复位等唤醒。从待机模式唤醒相当于系统复位,程序从头开始执行。

        在这3种低功耗模式中,待机模式功耗最低,但是从待机模式唤醒相当于系统复位,程序从头开始执行。睡眠模式和停止模式都能停止CPU的程序执行,被唤醒后,从程序停止处继续执行。应根据系统的实际功能需求选择合适的低功耗模式。

二、睡眠模式

1、进入睡眠模式

        通过执行Cortex-M4内核的WFI(Wait For Interrupt)指令或WFE(Wait For Event)指令可以进入睡眠模式。根据Cortex-M4F系统控制寄存器(System Control Register,SCR)的SLEEPONEXIT位的设置,有两种进入睡眠模式的方式

  • 立即睡眠:如果SLEEPONEXIT位是0,MCU在执行WFI指令或WFE指令时,立即进入睡眠模式。
  • 退出时睡眠:如果SLEEPONEXIT位是1,MCU在退出优先级最低的中断ISR后,立即进入睡眠模式。

        在进入睡眠模式之前,可以调用HAL的驱动函数设置SLEEPONEXIT的值,这两个函数原型如下:

void HAL_PWR_EnableSleepOnExit(void)	//将SLEEPONEXIT位置1
void HAL_PWR_DisableSleepOnExit(void)	//将SLEEPONEXIT位清零

        进入睡眠模式的HAL函数是HAL_PWR_EnterSLEEPMode(),其源代码如下:

void HAL_PWR_EnterSLEEPMode(uint32_t Regulator, uint8_t SLEEPEntry)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(Regulator);

  /* Check the parameters */
  assert_param(IS_PWR_REGULATOR(Regulator));
  assert_param(IS_PWR_SLEEP_ENTRY(SLEEPEntry));

  /* Clear SLEEPDEEP bit of Cortex System Control Register */
  CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));

  /* Select SLEEP mode entry -------------------------------------------------*/
  if(SLEEPEntry == PWR_SLEEPENTRY_WFI)
  {   
    /* Request Wait For Interrupt */
    __WFI();
  }
  else
  {
    if(SLEEPEntry != PWR_SLEEPENTRY_WFE_NO_EVT_CLEAR)
    {
      /* Clear all pending event */
      __SEV();
      __WFE();
    }

    /* Request Wait For Event */
    __WFE();
  }
}

         其中,参数Regulator表示调压器在睡眠模式下的状态。其取值使用如下宏定义常量。

PWR_MAINREGULATOR_ON,调压器正常运行。
PWR_LOWPOWERREGULATOR_ON,调压器处于低功耗模式。

        但是参数Regulator的取值在这个函数中并没有意义,因为STM32F4系列MCU在睡眠模式下,调压器总是处于运行状态,而不能是低功耗状态。这个参数是为了与低功耗系列的STM32F MCU的驱动函数相兼容。

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

PWR_SLEEPENTRY_WFI,使用WFI指令进入睡眠模式。
PWR_SLEEPENTRY_WFE,使用WFE指令进入睡眠模式。

        函数HAL_PWR_EnterSLEEPMode()内部会首先将系统控制寄存器SCR的SLEEPDEEP位清零,这个位如果置1就是深度睡眠模式,在进入停止模式时才将SLEEPDEEP位置1。

2、睡眠模式的状态

        进入睡眠模式后,系统的状态如下:

  • CPU的时钟关闭,CPU停止运行,也就是程序暂停。
  • 所有外设的时钟不停止,外设正常运行,所有I/O引脚的状态与运行时相同。
  • 调压器正常运行。

3、退出睡眠模式

        如果使用WFI指令进入睡眠模式,则NVIC确认的任何外设中断都可以将MCU唤醒。由中断唤醒后,先执行中断的ISR,然后执行WFI指令后面的程序。

        如果使用WFE指令进入睡眠模式,MCU将在有事件发生时立即退出睡眠模式,并执行WFE后的程序。唤醒事件可以通过以下方式产生。

  • 在外设的控制寄存器中使能一个中断事件,但是不在NVIC中使能其全局中断,同时使能系统控制寄存器SCR中的SEVONPEND(Send Event on Pending bit)位。当MCU从WFE恢复时,需要清除相应外设的事件中断标志位和外设NVIC中断挂起位。
  • 配置一个外部或内部EXTI线为事件模式。当CPU从WFE中恢复时,因为对应事件线的挂起位没有被置位,不必清除相应外设的中断标志位或NVIC中断通道挂起位。HAL库中有两个函数用于设置系统控制寄存器SCR中的SEVONPEND位的值。
void HAL_PWR_EnableSEVOnPend(void)	//SEVONPEND位置1
void HAL_PWR_DisableSEVOnPend(void)	//SEVONPEND位清零

        从睡眠模式唤醒的响应没有任何延迟,是3种低功耗模式中唤醒响应最快的。

4、SysTick的影响

        由于睡眠模式可以由任意中断或事件唤醒,而MCU在HAL初始化时就开启了Cortex-M内核的SysTick定时器,这个定时器每隔1ms中断一次。如果MCU处于睡眠状态,SysTick定时器的中断会将MCU从睡眠模式唤醒。

        如果要使睡眠模式不受SysTick中断的影响,需要在进入睡眠状态之前停止SysTick定时器,从睡眠状态恢复后又立即开启SysTick定时器,因为延时函数HAL_Delay()需要用到SysTick定时器。文件stmf4xx_hal.h定义了两个控制SysTick定时器的函数,两个函数原型定义如下:

void HAL_SuspendTick(void);	//暂停SysTick定时器的运行
void HAL_ResumeTick(void);	//恢复SysTick定时器的运行

三、应用示例

本文将创建一个示例项目,测试系统的睡眠模式。继续使用旺宝红龙开发板STM32F407ZGT6 KIT V1.0。示例功能和操作流程如下。

  • 将连接KeyRight键的PF6引脚配置为外部中断EXTI6。
  • 在主程序的while循环里,使系统进入睡眠状态后,按下KeyRight键把系统从睡眠状态唤醒。

        本示例要用到USART6、LED1(PA6)和KeyRight键,但是需要将连接KeyRight键的PF6引脚重新设置为外部中断线EXTI6,并设置上拉和下跳沿触发中断。本示例中KeyRight和LED1的引脚GPIO设置结果如图所示。用户还需要在NVIC中开启EXTI6的中断。

        本文引用KEYLED文件夹里的文件,其使用方法和管脚配置请看参考文章。

        参考文章:细说STM32F407单片机以DMA方式读写外部SRAM的方法_片外sram访问熟读-CSDN博客  细说STM32F407单片机以DMA方式读写外部SRAM的方法_片外sram访问熟读-CSDN博客

1、工程配置

(1) 时钟、DEBUG、GPIO、CodeGenerator

        外部时钟,25MHz,设置到HCLK=168MHz,PCLK1=42MHz,PCLK2=84MHz,其它,都设置成168MHz。

        DEBUG,选择serial wire,CodeGenerator的设置同参考文章。

 

(2) USART6

        使用管脚PG9、PG14,默认其它参数。

(3) NVIC

2、软件设计

(1) main.h

        即使PF6管脚被定义多重功能, IDE也自动生成如下驱动。

/* Private defines -----------------------------------------------------------*/
#define KeyRight_Pin GPIO_PIN_6
#define KeyRight_GPIO_Port GPIOF
#define KeyRight_EXTI_IRQn EXTI9_5_IRQn
#define LED1_Pin GPIO_PIN_6
#define LED1_GPIO_Port GPIOA

(2)main.c

/* USER CODE BEGIN 2 */
  printf("Demo22_1_SleepMode:Test Sleep Mode.\r\n\r\n");
  LED1_ON();
  HAL_Delay(1000);	//系统复位后,LED1 1秒后进入睡眠状态
  /* USER CODE END 2 */
  /* USER CODE BEGIN 3 */
	printf("Press KeyRight[S5] to wake up.\r\n");
	printf("After entering SleepMode,");
	printf("the LED1 flashes until the MCU wakes up.\r\n\r\n");
	LED1_OFF();
	HAL_SuspendTick();	//使SysTick定时器暂停

	/* 进入睡眠状态,对于正常的中断,WFI和WFE两种参数都可以唤醒,因为中断肯定是事件 */
	HAL_PWR_EnterSLEEPMode(PWR_LOWPOWERREGULATOR_ON, PWR_SLEEPENTRY_WFI);

	/* 按键的EXTI中断唤醒后执行下面的代码 */
	HAL_ResumeTick();	//恢复SysTick定时器
	printf("Resumed from SleepMode.\r\n\r\n");
	for(uint8_t i=0; i<9;i++)	//使LED1 闪烁,延时也可消除按键抖动影响
	{
	  	LED1_Toggle();
	  	HAL_Delay(500);
	}
  }
  /* USER CODE END 3 */

        本示没有为外部中断EXTI6编写回调函数代码,所有用户代码都在main()函数里。

        在while循环里,在使系统进入睡眠状态之前先熄灭LED1,调用函数HAL_SuspendTick()使SysTick定时器暂停,然后调用HAL_PWR_EnterSLEEPMode()函数,用WFI指令进入睡眠模式。在进入睡眠模式后,CPU时钟停止,程序就暂停了。

        在用户按下KeyRight[S5]键时产生EXTI中断,系统被唤醒,继续执行后面的代码。程序先调用函数HAL_ResumeTick()恢复SysTick定时器的运行,因为后面的代码里需要使用HAL_Delay()函数,要用到SysTick定时器。

        本示例在执行函数HAL_PWR_EnterSLEEPMode()进入睡眠模式时,使用WFI方式或WFE方式的效果是一样的,因为中断必然是事件引起的,而事件不一定产生中断

/* USER CODE BEGIN 4 */
// 唤醒SleepMode也可以在这里通过调用回调函数实现

int __io_putchar(int ch)
{
	HAL_UART_Transmit(&huart6,(uint8_t*)&ch,1,0xFFFF);
	return ch;
}
/* USER CODE END 4 */

四、下载并调试

        运行时可以看到示例程序是按期望运行的。系统提示进入睡眠模式后,按KeyRight键可唤醒系统,唤醒后显示提示信息,并且使LED1闪烁几次,然后又进入睡眠状态。要唤醒系统,需要再按KeyRight键。

        如果将程序中调用函数HAL_SuspendTick()的那行语句注释掉,也就是不暂停SysTick定时器,会发现运行时LED1一直闪烁。这是因为在进入睡眠状态后,SysTick定时器中断就将系统唤醒了,而SysTick定时器中断的触发周期是1ms,所以系统睡眠不超过1ms就被唤醒了。在这个程序中,while循环里的代码不会被CPU一直高速循环执行,进入睡眠模式会使CPU暂停执行程序,被唤醒后才继续执行睡眠点之后的代码。本示例为了演示的需要,在系统被唤醒后,用for循环执行了约4000ms的程序(也起到消除按键抖动影响的作用)。在实际的系统中,程序可能大部分时间处于睡眠状态,执行程序的时间可能很短,例如,睡眠1000ms,执行程序才1ms,这样可以大大降低系统的功耗。

        在CubeMX中,为本项目进行功耗计算,只设置了RUN和SLEEP两种步骤,步骤设置中只开启系统实际用到的外设。运行模式下的耗电流是47.18mA,而睡眠模式下的电流是13.18mA。

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

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

相关文章

【竞技宝】LOL:ning直播再次锐评

北京时间1月18日,目前英雄联盟LPL2025正在如火如荼的进行之中,很多队伍都已经打完了新赛季的首场比赛,其中就包括AL战队,AL在休赛期进行了大幅度的人员调整,整体实力相比之前增强了不少,在16日的比赛中,AL3-0轻松击败LGD拿下了赛季开门红,而AL的打野选手tarzan在本场比赛中表现…

构建安全防线:基于视频AI的煤矿管理系统架构创新成果展示

前言 本文我将介绍一款AI产品的成果展示——“基于视频AI识别技术的煤矿安全生产管理系统”。这款产品是目前我在创业阶段和几位矿业大学的博士共同从架构设计、开发到交付的全过程中首次在博客频道发布, 我之前一直想写但没有机会来整理这套系统的架构, 因此我也特别感谢CSDN平…

QT笔记- Qt6.8.1 Android编程 添加AndroidManifest.xml文件以支持修改权限

1. 切换项目选项卡&#xff0c;找到构建的步骤下的最后一项构建安卓APK&#xff0c;展开后找到应用程序栏&#xff0c;点击安卓自定义中的创建模板. 2. 弹出对话框勾选图中选项后点完成 3. 回到项目&#xff0c;查看.pro文件&#xff0c;里面多了很多内容不管&#xff0c;在下…

STM32-笔记43-低功耗

一、什么是低功耗&#xff1f; 低功耗‌是指通过优化设计和采用特定的技术手段&#xff0c;降低电子设备在运行过程中消耗的能量&#xff0c;从而延长电池寿命、提高性能和减少发热。低功耗设计主要从芯片设计和系统设计两个方面进行&#xff0c;旨在减少所有器件的功率损耗&am…

重温STM32之环境安装

缩写 CMSIS&#xff1a;common microcontroller software interface standard 1&#xff0c;keil mdk安装 链接 Keil Product Downloads 安装好后&#xff0c;开始安装平台软件支持包&#xff08;keil 5后不在默认支持所有的平台软件开发包&#xff0c;需要自行下载&#…

【三国游戏——贪心、排序】

题目 代码 #include <bits/stdc.h> using namespace std; using ll long long; const int N 1e510; int a[N], b[N], c[N]; int w[4][N]; int main() {int n;cin >> n;for(int i 1; i < n; i)cin >> a[i];for(int i 1; i < n; i)cin >> b[i…

想品客老师的第一天:值类型使用

前面两章的摘要 ECMAscript&#xff08;也就是ES&#xff09;是JavaScript的一个标准&#xff0c;就像c的c11和c99一样&#xff0c;几把的一年出一套标准 freeze()是一个对象方法&#xff0c;表示锁定、固定一个对象不可改变&#xff08;因为const对于标量不可变&#xff0c;…

leetcode刷题记录(六十七)——21. 合并两个有序链表

&#xff08;一&#xff09;问题描述 21. 合并两个有序链表 - 力扣&#xff08;LeetCode&#xff09;21. 合并两个有序链表 - 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 1&#xff1a;[https://assets.leetcode…

学习微信小程序的下拉列表控件-picker

1、创建一个空白工程 2、index.wxml中写上picker布局&#xff1a; <!--index.wxml--> <view class"container"><picker mode"selector" range"{{array}}" bindchange"bindPickerChange"><view class"pick…

大象机器人发布首款穿戴式数据采集器myController S570,助力具身智能数据收集!

myController S570 具有较高的数据采集速度和远程控制能力&#xff0c;大大简化了人形机器人的编程。 myController S570 是一款可移动的轻量级外骨骼&#xff0c;具有 14 个关节、2 个操纵杆和 2 个按钮&#xff0c;它提供高数据采集速度&#xff0c;出色的兼容性&#xff0c…

【氮化镓】香港科技大学陈Kevin-单片集成GaN比较器

一、引言(Introduction) GaN HEMT的重要性 文章开篇便强调了氮化镓(GaN)高电子迁移率晶体管(HEMT)在下一代功率转换系统中的巨大潜力。GaN HEMT具备高开关频率、低导通电阻、高击穿电压以及宽工作温度范围等优势,使其成为功率电子领域的热门研究对象。这些特性使得GaN…

ComfyUI-PromptOptimizer:文生图提示优化节点

ComfyUI-PromptOptimizer 是 ComfyUI 的一个自定义节点&#xff0c;旨在优化文本转图像模型的提示。它将用户输入的提示转换为更详细、更多样化、更生动的描述&#xff0c;使其更适合生成高质量的图像。无需本地模型。 1、功能 提示优化&#xff1a;优化用户输入的提示以生成…

Linux-day08

第17章 大数据定制篇-shell编程 shell编程快速入门 shell变量 设置环境变量 把行号打开 set nu 位置参数变量 预定义变量 在一个脚本中执行了另外一个脚本所以卡住了 CTRLC退出 运算符 operator运算符 条件判断 流程控制 单分支多分支 case语句 for循环 反复的把取出来的i值…

ExpGCN:深度解析可解释推荐系统中的图卷积网络

一、引言 在当今信息爆炸的时代&#xff0c;推荐系统已成为电子商务和社交网络中不可或缺的工具&#xff0c;旨在为用户筛选出符合其兴趣的信息。传统的协同过滤&#xff08;CF&#xff09;技术通过挖掘用户与项目之间的交互记录来生成推荐&#xff0c;但这种方法简化了模型&a…

蓝桥杯3526 子树的大小 | 数学规律

题目传送门 这个题目是一个数学题&#xff0c;比较好的方法是从上往下寻找子树的最左和最右的结点&#xff0c;每层统计子结点数&#xff0c;到树的底部时打印结果。 如何求最左、最右的子结点呢&#xff1f; 对于第i个结点,其前面有i-1个结点,每个结点各有m个孩子,再加上1号结…

大语言模型的语境中“越狱”和思维链

大语言模型的语境中“越狱”和思维链 越狱(Jailbreaking) 含义:在大语言模型的语境中,“越狱”是指用户试图绕过语言模型的安全限制和使用规则,让模型生成违反伦理道德、包含有害内容(如暴力、歧视、恶意软件代码等)的输出。这些安全限制是由模型开发者设置的,目的是确…

解决leetcode第3418题机器人可以获得的最大金币数

3418.机器人可以获得的最大金币数 难度&#xff1a;中等 问题描述&#xff1a; 给你一个mxn的网格。一个机器人从网格的左上角(0,0)出发&#xff0c;目标是到达网格的右下角(m-1,n-1)。在任意时刻&#xff0c;机器人只能向右或向下移动。 网格中的每个单元格包含一个值coin…

python实现pdf转word和excel

一、引言   在办公中&#xff0c;我们经常遇收到pdf文件格式&#xff0c;因为pdf格式文件不易修改&#xff0c;当我们需要编辑这些pdf文件时&#xff0c;经常需要开通会员或收费功能才能使用编辑功能。今天&#xff0c;我要和大家分享的&#xff0c;是如何使用python编程实现…

【实践】操作系统智能助手OS Copilot新功能测评

一、引言 数字化加速发展&#xff0c;尤其人工智能的发展速度越来越快。操作系统智能助手成为提升用户体验与操作效率的关键因素。OS Copilot借助语言模型&#xff0c;人工智能等&#xff0c;对操作系统的自然语言交互操作 推出很多功能&#xff0c;值得开发&#xff0c;尤其运…

人物一致性训练测评数据集

1.Pulid 训练:由1.5M张从互联网收集的高质量人类图像组成,图像标题由blip2自动生成。 测试:从互联网上收集了一个多样化的肖像测试集,该数据集涵盖了多种肤色、年龄和性别,共计120张图像,我们称之为DivID-120,作为补充资源,还使用了最近开源的测试集Unsplash-50,包含…