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

单片机的低功耗模式

什么是低功耗?

        STM32的低功耗(low power mode)特性是其嵌入式处理器系列的一个重要优势,特别适用于需要长时间运行且功耗敏感的应用场景,如便携式设备、物联网设备、智能家居系统等。

        在很多应用场合中都对电子设备的功耗要求非常苛刻,如某些传感器信息采集设备,仅靠小型的电池提供电源,要求工作长达数年之久,且期间不需要任何维护;由于智慧穿戴设备的小型化要求,电池体积不能太大导致容量也比较小,所以也很有必要从控制功耗入手,提高设备的续行时间。

STM32电源系统结构

电压调节器的作用:

  • 调节1.8v的供电区域,用于CPU的核心、存储器、内置的数字外设(NVIC) ;
  • 检测后备供电区域的的电压。若电压突然变成低电压,将电路连接到Vbat供电。

 低功耗模式介绍

 STM32具有运行、睡眠、停止和待机(3种低功耗模式)四种工作模式

 上电后默认是在运行模式,当内核(CPU)不需要继续运行时,可以选择后面的三种工作模式。

睡眠模式 (sleep mode)

        睡眠模式下,CPU停止工作,但所有的外设(如ADC、通信接口等)仍然运行,时钟继续运转。

使用场景:

暂时关闭CPU但是外围设备需要继续工作的场景。

模式特点:

  • 对系统影响小,但是节能效果最差。
  • 在睡眠模式下,所有的 I/O引脚都 保持 它们在运行模式时的状态

进入条件: 

  • 当系统控制寄存器中的SLEEPDEEP位被清除(通常为0,并且SLEEPONEXIT位根据需求设置时(如果设置为1,则在最低优先级中断处理程序退出时进入Sleep模式;如果为0,则执行WFIWFE时立即进入)。
  • 执行WFIWait For Interrupt)或WFEWait For Event)指令来进入。

唤醒条件:

  • 任意一个中断都能将系统从Sleep模式唤醒。
  • 如果执行WFE指令进入Sleep模式,则一旦发生唤醒事件时,MCU将唤醒。

停机模式 (stop mode)

        在停机模式下,CPU 和 核心外围设备的时钟会停止但部分唤醒源(如外部中断和某些定时器)仍然运行。Stop模式实现了非常低的功耗,同时保留了SRAM 和 寄存器的内容

适用场景:

这适用于需要长时间等待外部事件唤醒的应用,如等待用户输入或外部信号。

模式特点:

  • 节能效果好,程序不会复位但恢复时间较长(比如震荡器需要重新起震等)
  • 在停机模式下,所有的 I/O引脚都 保持 它们在运行模式时的状态。
  • 退出停机模式,HSI RC振荡器被选为系统时钟

进入条件:

  • 执行 WFIWait For Interrupt)或  WFEWait For Event)指令来进入。
  • 在进入Stop模式之前,通常需要关闭不必要的外设时钟,并保存需要保留的状态信息。
  • 需要将SLEEPDEEP位设置为1以进入深度睡眠模式,然后通过设置 电源 控制/状态寄存器(PWR_CSR)中的 PDDS位为来选择进入 Stop模式。
  • 根据需求设置 LPDS 位( LPDS = 0 :表示在深睡眠模式下,电压调节器保持 开启 状态; LPDS = 1 :表示在深睡眠模式下,电压调节器进入低功耗 模式。)
唤醒条件:
  • Stop模式可以通过外部中断(如按键中断、USART接收中断等)唤醒。
  • RTC闹钟事件、USB唤醒、以太网(ETH)唤醒等也可以作为唤醒源,但这些通常需要通过外部中断来触发。

 待机模式(standby mode)

        在该模式下,CPU、外围设备和时钟都被关闭只保留唤醒逻辑和备份寄存器。这适用于不需要保留RAM内容且可以从复位状态恢复的设备,常见于需要极低功耗且稀疏唤醒的应用。Standby模式是STM32中功耗最低的模式之一。

模式特点:

  • 节能效果最好,但程序会复位只有少数条件唤醒。
  • Standby模式下,大部分IO引脚处于高阻态,只有复位引脚、TAMPER引脚(如果配置为防侵入或校准输出)和WKUP引脚可用作唤醒源

进入条件:

  • Standby模式进入前,需要清除电源控制/状态寄存器(PWR_CSR)中的WUF,以确保没有未处理的唤醒标志。
  • SLEEPDEEP位设置为1以进入深度睡眠模式,并设置PDDS位为1来选择进入Standby模式。
  • 执行 WFI 或 WFE 指令进入Standby模式。

唤醒条件:

  • Standby模式可以通过WKUP引脚的上升沿唤醒。
  • RTC闹钟事件也可以作为唤醒源。
  • 独立看门狗(IWDG)复位NRST引脚上的外部复位也可以唤醒STM32,但这通常用于系统复位而非低功耗唤醒。

总结:(三种模式的对比)

唤醒模式:CPU关闭,各种外设和时钟正常;

停机模式:CPU关闭,核心外围设备的时钟停止运行,但部分唤醒源(中断和定时器)正常;

待机模式:CPU、外围设备和时钟都被关闭,只保留唤醒逻辑和备份寄存器。

三种模式的进入条件流程图:

 低功耗的寄存器

  •  电源控制寄存器(PWR_CR)

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

 低功耗模式的库函数

  •  使能时钟电源(关闭电压调节器)

  • 使能Wakeup引脚的唤醒功能 

  • 清除唤醒标志位 

小实验:低功耗实验 

实验目的

  • 按下按键2,进入低功耗模式(睡眠、停机、待机);
  • 按下按键1,退出低功耗模式;
  • 正常模式下,LED1闪烁;进入停机模式,LED2长亮,退出停机模式则LED2熄灭。

硬件清单

 开发板、ST-Link、USB转TTL

文件代码 

  • lqwr.c文件代码

配置流程:

  1. 初始化唤醒引脚:GPIO_PIN_0配置成上升沿触发中断的模式;
  2. sleep模式:暂停滴答定时器,防止滴答定时器唤醒、进入睡眠模式的函数;
  3. stop模式:暂停滴答定时器、进入停机模式的函数、配置时钟频率为72MHz;
  4. standby模式:开始电源时钟(关闭电压调节器)、使能引脚的唤醒功能(只有GPIO_PIN_O)、清除唤醒标记位、进入待机模式的函数。

注意事项:

  • 睡眠模式和停机模式唤醒之后,系统不会进行复位,继续向下执行;
  • 待机模式再唤醒之后,系统会进行复位,程序会从开始进行运行。
#include "lpwr.h"
#include "led.h"
#include "sys.h"//初始化
void lpwr_init(void){__HAL_RCC_GPIOA_CLK_ENABLE();GPIO_InitTypeDef gpio_initstruct;gpio_initstruct.Pin = GPIO_PIN_0;gpio_initstruct.Mode = GPIO_MODE_IT_RISING;gpio_initstruct.Pull = GPIO_PULLUP;gpio_initstruct.Speed  = GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(GPIOA,&gpio_initstruct);HAL_NVIC_SetPriority(EXTI0_IRQn,2,2);HAL_NVIC_EnableIRQ(EXTI0_IRQn);
}
//中断服务函数
void EXTI0_IRQHandler(void){HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
}
中断回调函数 .可以不用写
//void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){
//    if(GPIO_Pin == GPIO_PIN_0){
//        
//    }
//}
//进入sleep模式
void lpwr_enter_sleep(void){HAL_SuspendTick();//暂停滴答定时器器,否则会将系统进行唤醒。HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON,PWR_SLEEPENTRY_WFI);       //Regulator :电压调节器
}
//进入stop模式
void lpwr_enter_stop(void){//暂停滴答定时器HAL_SuspendTick();//点亮LED2led2_on();//进入停机模式HAL_PWR_EnterSTOPMode(PWR_MAINREGULATOR_ON,PWR_STOPENTRY_WFI);//熄灭LED2,代表退出停机模式led2_off();//进入停机模式后,再退出之后,系统时钟的RC振荡器被选择为:HSI(内部低速时钟,8MHz)stm32_clock_init(RCC_PLL_MUL9);     /* 设置时钟, 72Mhz */
}
//进入待机模式
void lpwr_enter_sandby(void){//使能电源时钟(关闭电压调节器)__HAL_RCC_PWR_CLK_ENABLE();//使能WAKEUP引脚唤醒功能HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN1);//清除唤醒标记,否则将持续保持唤醒状态__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);//进入待机模式HAL_PWR_EnterSTANDBYMode();//测试:看看代码会不会运行到下面?led2_on();//答:当唤醒模式后,LED2灯不会亮,原因:进入待机模式后,唤醒之后程序会从头开始运行,会进行复位。 
}
  • lpwr.h文件代码
#ifndef __LPWR_H__
#define __LPWR_H__
#include "stm32f1xx.h"void lpwr_init(void);
void lpwr_enter_sleep(void);
void lpwr_enter_stop(void);
void lpwr_enter_sandby(void);#endif
  • mian.c文件代码 
#include "sys.h"
#include "led.h"
#include "delay.h"
#include "uart1.h"
#include "lpwr.h"
#include "key.h"int main(void)
{HAL_Init();                         /* 初始化HAL库 */stm32_clock_init(RCC_PLL_MUL9);     /* 设置时钟, 72Mhz */led_init();                         /* LED初始化 */uart1_init(115200);printf("hello,world");key_init();lpwr_init();uint8_t i = 0;while(1){ 
//        led1_toggle();
//        delay_ms(200);//每隔200ms led灯进行反转的另一种写法:if(i % 20 == 0)led1_toggle();i++;delay_ms(10);if(key_scan() == 2)lpwr_enter_sandby();  //进入睡眠模式,所有的I/O引脚都 保持 它们在运行模式时的状态}
}

延时200ms的方式:

方式1:delay_ms(200);

方式2:定义一个函数if语句。

http://www.xdnf.cn/news/12610.html

相关文章:

  • AI Agent 架构设计:ReAct 与 Self-Ask 模式对比与分析
  • bat批量去掉本文件夹中的文件扩展名
  • Python 函数全攻略:函数进阶(生成器、闭包、内置函数、装饰器、推导式)
  • 6.6并发编程
  • 引起MySQL CPU 使用率过高常见因素和解决方案
  • Svelte 核心语法详解:Vue/React 开发者如何快速上手?
  • LeetCode刷题 -- 542. 【01 矩阵】最短距离更新算法实现(双向DP)
  • 粤龙庄新文化解释:龙腾南粤,酱蕴山河
  • 计算机网络第2章(下):物理层传输介质与核心设备全面解析
  • 手机号段数据库与网络安全应用
  • Java应用Flink CDC监听MySQL数据变动内容输出到控制台
  • 家政小程序开发——AI+IoT技术融合,打造“智慧家政”新物种
  • 腾讯 ovCompose 跨平台框架发布,几年后还会有人用吗?
  • VScode 使用 git 提交数据到指定库的完整指南
  • TensorFlow深度学习实战(20)——自组织映射详解
  • 【Java开发日记】说一说 SpringBoot 中 CommandLineRunner
  • PyTorch 中contiguous函数使用详解和代码演示
  • 第4章——springboot自动配置
  • LabVIEW音频测试分析
  • ​React Hooks 的闭包陷阱问题
  • YoloV12改进策略:Block改进|TAB,融合组内自注意力(IASA)和组间交叉注意力(IRCA)|即插即用
  • spring:实例工厂方法获取bean
  • 408考研逐题详解:2009年第33题
  • 第22讲、Odoo18 QWeb 模板引擎详解
  • 【PCIe总线】 -- PCI、PCIe相关实现
  • 第十五届蓝桥杯单片机国赛
  • SQL-labs通关(level1-22)
  • 主流信创数据库对向量功能的支持对比
  • Vue Fragment vs React Fragment
  • Mysql-定时删除数据库中的验证码