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

【STM32】 STM32低功耗模式详解:睡眠模式与唤醒机制【待测试】

本篇知识点基于F0讲解

一、STM32三种低功耗模式参考表格

模式功耗唤醒时间保持状态典型应用场景
睡眠模式中等 (mA级)最短 (μs级)CPU停止,外设保持短暂待机,快速响应
停止模式低 (μA级)中等 (ms级)RAM保持,时钟停止长时间待机,电池供电
待机模式极低 (nA级)最长 (复位级)仅备份域保持超低功耗需求,看门狗唤醒

二、睡眠模式深入解析

1. 进入睡眠模式

在这里插入图片描述

void PWR_EnterSleepMode(uint8_t PWR_SLEEPEntry)
{/* 1. 参数合法性检查 */assert_param(IS_PWR_SLEEP_ENTRY(PWR_SLEEPEntry));/* 2. 清除SLEEPDEEP位(关键步骤)*/SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;/* 3. 选择进入方式 */if(PWR_SLEEPEntry == PWR_SLEEPEntry_WFI) {__WFI();  // 等待中断指令} else {__WFE();  // 等待事件指令}
}
关键操作解析:
  1. 参数检查 assert_param()

    • 确保传入参数只能是:
      • PWR_SLEEPEntry_WFI (0x01)
      • PWR_SLEEPEntry_WFE (0x02)
    • 防止非法参数导致未定义行为
  2. 清除SLEEPDEEP位

    SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
    
    • 目的:明确指定进入睡眠模式(非停止/待机模式)
    • 寄存器说明
      Cortex-M0系统控制寄存器(SCR)的SLEEPDEEP位:
      • 0 = 睡眠模式
      • 1 = 深度睡眠模式(停止/待机)
    • 硬件关联:该位与电源控制寄存器(PWR_CR)的PDDS和LPDS位协同工作
  3. 休眠指令选择

    指令汇编指令唤醒条件特点
    WFIWFI任意中断传统唤醒方式
    WFEWFE事件信号支持SEVONPEND和事件线

2. 退出睡眠模式

在这里插入图片描述

(1) WFI唤醒机制
  • 唤醒条件:任何在NVIC中使能的外设中断
  • 唤醒流程
    中断源 CPU WFI位置 ISR 主程序 触发中断 退出睡眠 跳转至中断服务程序 返回原代码继续执行 中断源 CPU WFI位置 ISR 主程序
  • 特点
    • 自动清除中断挂起位
    • 唤醒后从WFI下一条指令开始执行
(2) WFE唤醒机制

提供两种事件驱动唤醒方式:

方式一:SEVONPEND机制

配置步骤

  1. 使能SCB_SCR的SEVONPEND位
    SCB->SCR |= SCB_SCR_SEVONPEND_Msk;
    
  2. 配置外设中断(但禁用NVIC中断)
  3. 执行__WFE()进入睡眠

唤醒条件:外设中断挂起位置位(即使NVIC中断禁用)

唤醒后操作

// 必须双重清除挂起位!
EXTI_ClearITPendingBit(EXTI_LineX);  // 清除外设级挂起位
NVIC_ClearPendingIRQ(IRQn);         // 清除NVIC级挂起位

注意事项

  • 不清除挂起位会导致之后如果执行WFE时会立即唤醒(无法正常进入睡眠)
  • 适用于复用现有中断逻辑的场景
实践代码
void Enter_Sleep_WFE(void)
{// 配置唤醒源(SEVONPEND模式)SCB->SCR |= SCB_SCR_SEVONPEND_Msk;EXTI->IMR |= EXTI_IMR_MR5;  // 使能PA5中断NVIC_DisableIRQ(EXTI4_15_IRQn); // 禁用NVIC中断__WFE(); // 进入睡眠// ===== 唤醒后处理 =====// 1. 清除外设挂起位(写1清除)EXTI->PR = EXTI_PR_PR5;//NVIC_ClearPendingIRQ(IRQn);         // 清除NVIC级挂起位// 2. 清除NVIC挂起位NVIC->ICPR[0] = (1 << (EXTI4_15_IRQn & 0x1F));//NVIC_ClearPendingIRQ(IRQn);         // 清除NVIC级挂起位// 3. 添加延迟防止信号抖动for(volatile int i=0; i<100; i++);// 4. 执行业务逻辑Handle_Wakeup_Event();
}
方式二:纯事件模式

配置步骤

  1. 设置EXTI为事件模式
    EXTI_InitTypeDef exti = {0};
    exti.EXTI_Line = EXTI_Line5;
    exti.EXTI_Mode = EXTI_Mode_Event;  // 关键配置
    exti.EXTI_Trigger = EXTI_Trigger_Rising;
    EXTI_Init(&exti);
    
  2. 执行__WFE()进入睡眠

唤醒条件:EXTI线检测到指定事件边沿

优势

  • 无需中断处理函数
  • 无需清除挂起位
  • 唤醒延迟最短(约6个时钟周期)

3. 唤醒机制对比表

特性WFI唤醒WFE+SEVONPENDWFE+事件模式
配置复杂度★☆☆ (简单)★★☆ (中等)★★☆ (中等)
中断处理程序需要不需要不需要
挂起位管理自动清除需手动双重清除无挂起位产生
唤醒延迟12-15周期12-15周期5-8周期
功耗优化★★☆★★★★★★★
适用场景常规中断响应复用现有中断资源专用低功耗事件

4. 最佳实践建议

(1) 配置推荐
// 最优配置:纯事件模式唤醒
void Enter_LowPower_Mode(void)
{// 1. 配置事件唤醒源EXTI_InitTypeDef exti = {0};exti.EXTI_Line = EXTI_Line5;exti.EXTI_Mode = EXTI_Mode_Event;exti.EXTI_Trigger = EXTI_Trigger_Falling;exti.EXTI_LineCmd = ENABLE;EXTI_Init(&exti);// 2. 关闭非必要外设时钟RCC_APB1PeriphClockCmd(UNUSED_PERIPH, DISABLE);// 3. 进入睡眠PWR_EnterSleepMode(PWR_SLEEPEntry_WFE);
}
  • 关键提醒:事件模式需确保 GPIO 时钟开启(RCC_AHBPeriph_GPIOx)。若为省电关闭时钟,事件将无法触发唤醒。
(2) 唤醒处理
// 事件唤醒后直接处理业务
if(GPIO_ReadInputDataBit(WAKEUP_PORT, WAKEUP_PIN) == ACTIVE_STATE)
{Process_Wakeup_Event(); // 无需清除挂起位
}
(3) 常见问题解决

问题:唤醒后立即重新睡眠

  • 原因:未正确清除挂起位
  • 解决方案
    // 对于SEVONPEND模式
    EXTI_ClearITPendingBit(EXTI_LineX);
    NVIC_ClearPendingIRQ(IRQn);// 额外添加延迟
    delay_us(10);
    

5. 功耗优化技巧

  1. 时钟管理
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, DISABLE);
    
  2. IO状态配置
    • 未用引脚设为模拟输入
    • 输出引脚固定电平
  3. 外设状态管理
    • ADC禁用并关闭参考电压
    • 串口接收器禁用
  4. 唤醒源选择
    • 优先选择低功耗唤醒源(EXTI > 定时器)
http://www.lryc.cn/news/578518.html

相关文章:

  • 单元测试详解
  • 记录一个 Linux中脚本无法执行的问题
  • 构建淘宝评论监控系统:API 接口开发与实时数据采集教程
  • Camera相机人脸识别系列专题分析之十五:人脸特征检测FFD算法之libcvface_api.so算法API详细注释解析
  • Docker制作python环境
  • C++ 11 中 condition_variable 的探索与实践
  • 当足球遇上AI:赛事分析、伤病预测与智能裁判的崛起
  • postman入门篇
  • RabbitMQ - SpringAMQP及Work模型
  • k8s将service的IP对应的不同端口分配到不同的pod上
  • Vue 3 中的 `h` 函数详解
  • CAD文件处理控件Aspose.CAD教程:使用 Python 将绘图转换为 Photoshop
  • 【Python】字典get方法介绍
  • 面试拷打-20250701
  • 计网学习笔记第1章 计算机网络体系结构(灰灰题库)
  • 论文阅读笔记 NoPoSplat
  • 笔记/计算机网络
  • 动手学深度学习13.5. 多尺度目标检测-笔记练习(PyTorch)
  • 推客系统小程序终极指南:从0到1构建自动裂变增长引擎,实现业绩10倍增长!
  • (JAVA)自建应用调用企业微信API接口,实现消息推送
  • uniapp+vue写小程序页面,实现一张图片默认放大后,可以在容器内上下左右拖动查看
  • android13 如何定时输出app的帧率FPS
  • 应急响应类题练习——玄机第五章 Windows 实战-evtx 文件分析
  • mac重复文件清理,摄影师同款清理方案
  • COCO、VOC 和 YOLO三种主流目标检测数据格式的详细对比与示例说明
  • Java Selenium反爬虫技术方案
  • 笔记本电脑怎样投屏到客厅的大电视?怎样避免将电脑全部画面都投出去?
  • 基于c#语言的股票模拟交易软件的开发与实现
  • Vue3 使用 i18n 实现国际化完整指南
  • AiPy实战(7):一键生成天气组件,解放UI设计的双手