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

32 低功耗模式(睡眠 停机 待机 )

一、前言

在实际嵌入式开发过程中,我们会去考虑我们设计出来的产品的实际工作时间,例如桥梁探测系统,智能穿戴设备,我们希望在满足用户前提下尽可能地减少用户充电次数,所以引出今日沟通的主题:低功耗模式。比如桥梁探测设备,在冬季不下雨的时候,设备就可以进入休眠模式,实时探测数据的时间间隔可以适当拉长。接下来我们一起来了解下三种模式。

1 电源控制

电源控制(PWR:Power Control)。电源对电子设备来说非常重要,它是保证系统稳定运行的基础。在保证系统能稳定运行的同时,对嵌入式设备一般又有低功耗的需求。

1.1电源框图

1)VDDA供电区域

主要负责模拟部分的供电。为了提高转换的精确度,ADC使用一个独立的电源供电,过滤和屏蔽来自印刷电路板上的毛刺干扰。主要给A/D转换器、温度传感器、复位模块、PLL等供电。

2)VDD供电区域

VDD是数字电的正极,VSS是数字电的负极,电压3.3V。给I/O电路、待机电路和电压调节器供电。

3)1.8V供电区域

CPU核心、内部存储器、内置的数字外设都是工作在1.8V的电压。1.8V的低电压是由从电压调节器得到的。

4)后备供电区域

VBAT引脚会接电池和其他电源,当VDD断电时,可以保存备份寄存器的内容和给RTC供电。

VBAT脚也为RTC、LSE振荡器和PC13至PC15供电,这保证当主要电源被切断时RTC能继续工作。

5)电压调节器

复位后,电压调节器总是工作使能的。有3种不同的工作模式:

  1. 运转模式:调节器以正常功耗模式提供1.8V电源(内核、内存和外设)2.
  2. 停止模式:调节器以低功耗模式提供1.8V电源,用于保存寄存器和SRAM的内容
  3. 待机模式:调节器停止供电。除了备用电路和备份域外,寄存器和SRAM的内容全部丢失。

1.2上电复位和掉电复位

类似于按键(有延迟),当VDD/VDDA低于指定的限位电压VPOR/VPDR时,系统保持为复位状态,而无需外部复位电路。

复位和解除复位有一个40mv的迟滞电压。当电压大于VPOR时解除复位,当电压小于VPDR时进入复位。设置2个阈值的作用是当电压在附近抖动的时候防止频繁的复位和解除复位。

1.3 低功耗

在系统或电源复位以后,微控制器处于运行状态。当CPU不需继续运行时,可以利用多种低功耗模式来节省功耗,例如等待某个外部事件时。

用户需要根据最低电源消耗、最快速启动时间和可用的唤醒源等条件,选定一个最佳的低功耗模式。

STM32F10xxx有三种低功耗模式:

1.3.1 睡眠模式

(1)睡眠模式
  1. SLEEP-NOW:如果SLEEPONEXIT位被清除,当WRI或WFE被执行时,微制器立即进入睡眠模式。
  2. SLEEP-ON-EXIT:如果SLEEPONEXIT位被置位,系统从最低优先级的中断处理程序中退出时,微控制器就立即进入睡眠模式。

注意:在睡眠模式下,所有的I/O引脚都保持它们在运行时的状态。验证:LED进入睡眠模式依然会亮

(2)退出睡眠模式

如果执行WFI指令进入睡眠模式,任意一个被嵌套向量中断控制器响应的外设中断都能将系统从睡眠模式唤醒。

如果执行WFE指令进入睡眠模式,则一旦发生唤醒事件时,微处理器都将从睡眠模式退出。

1.3.2停止模式

停止模式是在Cortex™-M3的深睡眠模式基础上结合了外设的时钟控制机制,在停止模式下电压调节器可运行在正常或低功耗模式。此时在1.8V供电区域的的所有时钟都被停止,PLL、HSI和HSE RC振荡器的功能被禁止,SRAM和寄存器内容被保留下来。

注意:在停止模式下,所有的I/O引脚都保持它们在运行模式时的状态。

(1)进入停止模式

在停止模式下,通过设置电源控制寄存器(PWR_CR)的LPDS位使内部调节器进入低功耗模式,能够降低更多的功耗。

  1. 如果正在进行闪存编程,直到对内存访问完成,系统才进入停止模式。
  2. 如果正在进行对APB的访问,直到对APB访问完成,系统才进入停止模式。
(2)退出停止模式

1.3.3待机模式

待机模式可实现系统的最低功耗

该模式是在Cortex-M3深睡眠模式时关闭电压调节器。整个1.8V供电区域被断电。PLL、HSI和HSE振荡器也被断电。SRAM和寄存器内容丢失。只有备份寄存器和待机电路维持供电。这么说吧,能停的全停。

注意:在待机模式下,所有的I/O引脚处于高阻态,除了以下的引脚:

  1. 复位引脚(始终有效)
  2. 当被设置为防侵入或校准输出时的TAMPER引脚。
  3. 被使能的唤醒引脚。

二、代码介绍

1 睡眠模式

/** * 需求 : 测试STM32芯片进入低功耗 - 睡眠模式 */ /** * 睡眠模式 */ void enter_sleep_mode() { SCB->SCR &= ~SCB_SCR_SLEEPONEXIT; // 立即进入睡眠 //SCB->SCR |= SCB_SCR_SLEEPONEXIT; // 所有中断程序处理完后再进入睡眠 __wfi(); } int main(void) { USART_Init(); LED_Init(); LED_On(LED_BLUE); printf("测试STM32芯片进入低功耗 - 睡眠模式 \n"); printf("5s后STM32芯片进入睡眠模式 \n"); SysTick_DelayS(2); printf("3s后STM32芯片进入睡眠模式 \n"); SysTick_DelayS(1); printf("2s后STM32芯片进入睡眠模式 \n"); SysTick_DelayS(1); printf("1s后STM32芯片进入睡眠模式 \n"); SysTick_DelayS(1); // !进入睡眠模式 enter_sleep_mode(); // 蓝灯依然点亮 printf("STM32正常工作 \n"); while(1) { LED_Blink(LED_BLUE); } }

2 停止模式

/** * 需求 : 测试STM32芯片进入低功耗 - 停止模式 */ /** * 停止模式 */ void enter_stop_mode() { // 开启时钟 RCC->APB1ENR |= RCC_APB1ENR_PWREN; // 深睡眠 SCB->SCR |= SCB_SCR_SLEEPDEEP; // 掉电 PWR->CR &= ~PWR_CR_PDDS; // 低功耗 PWR->CR |= PWR_CR_LPDS; __wfi(); } /** * 睡眠模式 */ void enter_sleep_mode() { // 浅睡眠 SCB->SCR &= ~SCB_SCR_SLEEPDEEP; SCB->SCR &= ~SCB_SCR_SLEEPONEXIT; // 立即进入睡眠 //SCB->SCR |= SCB_SCR_SLEEPONEXIT; // 所有中断程序处理完后再进入睡眠 __wfi(); } void system_clock_reset(void) { __IO uint32_t StartUpCounter = 0, HSEStatus = 0; /* Enable HSE */ RCC->CR |= ((uint32_t)RCC_CR_HSEON); do { HSEStatus = RCC->CR & RCC_CR_HSERDY; StartUpCounter++; } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); /* PLL configuration: PLLCLK = HSE * 9 = 72 MHz */ RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL)); RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9); /* Enable PLL */ RCC->CR |= RCC_CR_PLLON; /* Wait till PLL is ready */ while((RCC->CR & RCC_CR_PLLRDY) == 0) { } /* Select PLL as system clock source */ RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL; /* Wait till PLL is used as system clock source */ while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08) { } } int main(void) { USART_Init(); KEY_Init(); LED_Init(); LED_On(LED_BLUE); printf("测试STM32芯片进入低功耗 - 停止模式 \n"); printf("5s后STM32芯片进入停止模式 \n"); SysTick_DelayS(2); printf("3s后STM32芯片进入停止模式 \n"); SysTick_DelayS(1); printf("2s后STM32芯片进入停止模式 \n"); SysTick_DelayS(1); printf("1s后STM32芯片进入停止模式 \n"); SysTick_DelayS(1); // !进入停止模式 enter_stop_mode(); // !外部中断唤醒芯片后,默认会采用HSI的震荡电路的频率,所以不是72M。 // !所以如果想要STM32芯片正常工作,那么就需要重新选择PLL时钟源 system_clock_reset(); SysTick_DelayMs(10); // 蓝灯依然点亮 printf("STM32正常工作 \n"); while(1) { LED_Blink(LED_BLUE); } }

3 待机模式

/** * 需求 : 测试STM32芯片进入低功耗 - 待机模式 */ /** * 待机模式 */ void enter_standby_mode() { // 开启时钟 RCC->APB1ENR |= RCC_APB1ENR_PWREN; // 深睡眠 SCB->SCR |= SCB_SCR_SLEEPDEEP; // 掉电 PWR->CR |= PWR_CR_PDDS; // 清除唤醒标志位 PWR->CR |= PWR_CR_CWUF; // 使能唤醒引脚 PWR->CSR |= PWR_CSR_EWUP; __wfi(); } /** * 停止模式 */ void enter_stop_mode() { // 开启时钟 RCC->APB1ENR |= RCC_APB1ENR_PWREN; // 深睡眠 SCB->SCR |= SCB_SCR_SLEEPDEEP; // 掉电 PWR->CR &= ~PWR_CR_PDDS; // 低功耗 PWR->CR |= PWR_CR_LPDS; __wfi(); } /** * 睡眠模式 */ void enter_sleep_mode() { // 浅睡眠 SCB->SCR &= ~SCB_SCR_SLEEPDEEP; SCB->SCR &= ~SCB_SCR_SLEEPONEXIT; // 立即进入睡眠 //SCB->SCR |= SCB_SCR_SLEEPONEXIT; // 所有中断程序处理完后再进入睡眠 __wfi(); } void system_clock_reset(void) { __IO uint32_t StartUpCounter = 0, HSEStatus = 0; /* Enable HSE */ RCC->CR |= ((uint32_t)RCC_CR_HSEON); do { HSEStatus = RCC->CR & RCC_CR_HSERDY; StartUpCounter++; } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); /* PLL configuration: PLLCLK = HSE * 9 = 72 MHz */ RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL)); RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9); /* Enable PLL */ RCC->CR |= RCC_CR_PLLON; /* Wait till PLL is ready */ while((RCC->CR & RCC_CR_PLLRDY) == 0) { } /* Select PLL as system clock source */ RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL; /* Wait till PLL is used as system clock source */ while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08) { } } int main(void) { USART_Init(); KEY_Init(); LED_Init(); LED_On(LED_BLUE); printf("测试STM32芯片进入低功耗 - 待机模式 \n"); printf("5s后STM32芯片进入待机模式 \n"); SysTick_DelayS(2); printf("3s后STM32芯片进入待机模式 \n"); SysTick_DelayS(1); printf("2s后STM32芯片进入待机模式 \n"); SysTick_DelayS(1); printf("1s后STM32芯片进入待机模式 \n"); SysTick_DelayS(1); // !进入待机模式 enter_standby_mode(); while(1) { } }

三、寄存器介绍

四、归纳和总结

相同点

  1. 三种模式均通过PWR外设控制,核心操作是配置PWR_CR寄存器 + 执行WFI/WFE指令。
  2. 唤醒后都需要重新配置部分硬件(待机模式需完全重启,停止模式需配置外设时钟,睡眠模式无需额外配置)。
  3. 低功耗的核心逻辑都是减少时钟和电压调节器的功耗消耗

不同点

  1. 断电程度:睡眠模式 < 停止模式 < 待机模式,断电越彻底,功耗越低,但数据保持能力越弱。
  2. 唤醒难度:睡眠模式最容易(任意中断 / 事件),待机模式最难(仅特定唤醒源)。
  3. 恢复速度:睡眠模式最快(无缝恢复),待机模式最慢(相当于复位重启)。

核心参数对比

http://www.cnnetsun.cn/news/69864.html

相关文章:

  • AI编程革命!Claude Skills大揭秘:小白也能快速上手的Agent开发神器,大模型开发者必看!
  • 内点法求最优潮流附matlab代码
  • 三相PWM整流器有限集模型预测电流控制附Simulink仿真模型
  • 光伏四可“可观”功能:光伏电站全景数字化的底层支撑技术
  • 如何用FLUX.1-dev镜像在本地部署下一代AI绘画模型?
  • 基于 Comsol 移动网格方法的激光熔池流动数值模拟
  • BLDC无刷直流电机Matlab仿真:转速电流双闭环控制及有感无感换相方式研究
  • [光学原理与应用-491]:水冷机、零气模块CDA、功率计等影响266皮秒紫外激光器的种子源1064nm功率稳定性结果的主要因素有哪些?
  • 昆仑通态MCGS与欧姆龙E5CC温控器通讯实战:PID模式及输出启停控制
  • 通达信〖逆势突破强牛〗指标公式 逆市环境中率先突破前期重要压力位 较强内在上涨动力
  • 基于扰动观测器的永磁同步电机(PMSM)模型预测控制(MPC)仿真探索
  • AEB联合仿真算法设计:Carsim2019.0+Matlab/Simulink2021a实现...
  • Java毕设选题推荐:基于springboot个人博客系统的设计与实现基于SpringBoot+Vue个人博客系统的设计与实现【附源码、mysql、文档、调试+代码讲解+全bao等】
  • Java毕设选题推荐:基于springboot停车场车位预约系统基于Java springboot停车场管理系统停车位预约【附源码、mysql、文档、调试+代码讲解+全bao等】
  • Java毕设选题推荐:基于springboot的无人化、线上化、数据化海洋馆预约系统的设计与实现【附源码、mysql、文档、调试+代码讲解+全bao等】
  • Ascend C高级API应用:InitGlobalMemory与Pad操作的底层原理
  • Java毕设选题推荐:基于Java Web的新能源汽车信息咨询服务基于SpringBoot+Vue的新能源汽车信息咨询服务的设计与实现【附源码、mysql、文档、调试+代码讲解+全bao等】
  • 开箱即用的 GoWind Admin|风行,企业级前后端一体中后台框架:OPA 集成指南:从原理到实践
  • Object.defineProperty和Proxy实现拦截的区别
  • 若依物联网
  • PSEN1抗体:如何揭示阿尔茨海默病致病机制与治疗新靶点?
  • Docker Engine 升级指南:保障容器安全的关键步骤
  • 基于zigbee灯光控制照明及色温调节系统的设计与实现(有完整资料)
  • 7、Python高级语法:描述器、属性与元编程实战
  • 【开题答辩全过程】以 基于java技术的校园一卡通系统的设计与实现为例,包含答辩的问题和答案
  • 11、Python 包与应用开发全解析
  • django基于智能推荐算法的全屋定制平台网站设计
  • 详谈:解释器模式(四)
  • 双Buck电路并联下的下垂控制与VDCM协同控制策略:增强直流微电网稳定性的仿真应用
  • Java 日期格式化方法:SimpleDateFormat 和 DateTimeFormatter