目录

1.硬件原理

2.低功耗模式

3.睡眠模式实验

4.停止模式实验

5.待机模式实验


前言:STM32F10xxx系列产品都有电源管理模块,芯片功耗会影响到一个产品的续航能力;比如在一些终端传感器场合里,为了减轻后期的维护投入,要求长期工作时间较长,更需要合理的芯片功耗管理。芯片自带几种运行模式,包括正常模式、睡眠模式、停止模式、待机模式。越往后,芯片的功耗越低,但能执行功能就越少。低功耗的电源管理策略就是在芯片不需要对外界响应的时候进入低功耗模式,而当外界条件满足的时候,退出低功耗模式(唤醒),正常执行处理工作。下面对其模式之间的转换和各个模式下的芯片内部的运转情况等一探究竟。

写代码前要先了解芯片的特性及工作原理,难免会先阅读一些长长的文档。下面核心讲解一些要点。

1.硬件原理

下图是芯片的电源框架:

图左边7个电压点对应芯片的7个引脚,在芯片电路原理图能找到对应的引脚。

是ADC转换器的参考电压,有些芯片没有这连个引脚,内部已经把他们接到了。

是ADC转换器的供电电源,独立电源供电是为了过滤和屏蔽来自印刷电路板上的毛刺干扰,提高转换的精确度。(也可以直接连到)。

STM32的工作电压(VDD)为2.0~3.6V。通过内置的电压调节器提供所需的1.8V电源。

使用电池或其他电源连接到VBAT脚上,当VDD断电时,可以保存备份寄存器的内容和维持RTC的

功能。(如果没有外部电池,好像不接也可以,但是数据手册说必须接到)。

电池备份区域:

当备份区域由VDD(内部模拟开关连到VDD)供电时,下述功能可用:

● PC14和PC15可以用于GPIO或LSE(低速外部时钟)引脚

● PC13可以作为通用I/O口、TAMPER引脚、RTC校准时钟、RTC闹钟或秒输出

当后备区域由VBAT供电时(VDD消失后模拟开关连到VBAT),可以使用下述功能:

● PC14和PC15只能用于LSE(低速外部时钟)引脚

● PC13可以作为TAMPER引脚、RTC闹钟或秒输出

电压调节器:

复位后调节器总是使能的。根据应用方式它以3种不同的模式工作。

● 运转模式:调节器以正常功耗模式提供1.8V电源(内核,内存和外设)。

● 停止模式:调节器以低功耗模式提供1.8V电源,以保存寄存器和SRAM的内容。

● 待机模式:调节器停止供电。除了备用电路和备份域外,寄存器和SRAM的内容全部丢失。

2.低功耗模式

STM32F10xxx有三种低功耗模式:

● 睡眠模式(Cortex™-M3内核停止,所有外设包括Cortex-M3核心的外设,如NVIC、系统时钟(SysTick)等仍在运行)

● 停止模式(所有的时钟都已停止)

● 待机模式(1.8V电源关闭)

此外,在运行模式下,可以通过以下方式中的一种降低功耗:

● 降低系统时钟

● 关闭APB和AHB总线上未被使用的外设时钟。

注意:在睡眠模式、停止模式及待机模式中,若备份区域电源正常供电,备份区域的RTC都可以正常运行、备份区域内的寄存器及备份区域内的SRAM数据会被保存,不受功耗模式影响。

3.睡眠模式实验

下面代码利用编译器内置函数__WFI()进入睡眠,任何中断将退出睡眠(实验使用串口中断和外部中断)。利用串口将芯片状态信息发送出来。可以先把代码复制到工程编译下载,实验现象通过串口上位机观察,如果有可调电源的话,可以对比正常工作和睡眠模式下的电流大小,正常来说睡眠模式下功率低,那么电流会比正常工作下低。下面程序并不复杂,程序进入while循环延时一段时间就会进入睡眠状态,利用上位机向串口发送数据或者将PA.0引脚接电源都可产生中断,从而退出睡眠模式。

#include "stm32f10x.h"
#include "stdio.h"static void EXTI_Key_Config(void);
static void NVIC_Configuration(void);
static void USART1_Config(void);
static void Delay(__IO u32 nCount);int main(void)
{   USART1_Config();EXTI_Key_Config();//配置中断控制器NVICNVIC_Configuration();while(1){printf("STM32正常运行.\r\n");Delay(0xfffff);//NVIC_SystemLPConfig(NVIC_LP_SLEEPONEXIT,DISABLE);//调用__WFI时立即进入睡眠NVIC_SystemLPConfig(NVIC_LP_SLEEPONEXIT,ENABLE);//调用__WFI时,等待系统从最低优先级的中断处理程序中退出后进入睡眠printf("STM32进入睡眠.\r\n");__WFI();//WFI指令进入睡眠//开始等待中断唤醒Delay(0xfffff);printf("已退出睡眠模式.\r\n");}
}static void EXTI_Key_Config(void)
{GPIO_InitTypeDef GPIO_InitStructure;EXTI_InitTypeDef EXTI_InitStructure;//开启外设时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO,ENABLE);//初始化 GPIOA.0  设置为下拉输入GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_0;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; GPIO_Init(GPIOA, &GPIO_InitStructure);//GPIOA.0 中断线配置GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0);//GPIOA.0 中断初始化配置EXTI_InitStructure.EXTI_Line=EXTI_Line0;EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;//上升沿时进入中断EXTI_InitStructure.EXTI_LineCmd = ENABLE;//初始化外设EXTI寄存器EXTI_Init(&EXTI_InitStructure);
}void USART1_Config(void)
{GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;//配置串口1(USART1)时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);//配置串口1(USART1 Tx (PA.09))GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);//配置串口1 USART1 Rx (PA.10)GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(GPIOA, &GPIO_InitStructure);//串口1模式(USART1 mode)配置 USART_InitStructure.USART_BaudRate = 9600;//一般设置为9600;USART_InitStructure.USART_WordLength = USART_WordLength_8b;USART_InitStructure.USART_StopBits = USART_StopBits_1;USART_InitStructure.USART_Parity = USART_Parity_No ;USART_InitStructure.USART_HardwareFlowControl =         USART_HardwareFlowControl_None;USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;USART_Init(USART1, &USART_InitStructure);USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启中断USART_Cmd(USART1, ENABLE); //使能串口
}int fputc(int ch, FILE *f)//重写标准库的fputc函数
{//将Printf内容发往串口USART_SendData(USART1, (unsigned char) ch);while( USART_GetFlagStatus(USART1,USART_FLAG_TC)!= SET);    return (ch);
}static void NVIC_Configuration(void)
{NVIC_InitTypeDef NVIC_InitStructure;NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);    NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;               NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;      NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;    NVIC_Init(&NVIC_InitStructure);//使能外部中断 PA.0NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;   NVIC_Init(&NVIC_InitStructure);//使能串口1中断
}void Delay(__IO u32 nCount)     //简单的延时函数
{for(; nCount != 0; nCount--);
} 

在stm32f10x_it.c文件加入:

#include "delay.h"
void EXTI0_IRQHandler(void)
{     Delay(0xFFFFF);//防抖//检查指定的EXTI0线路触发请求发生与否if(EXTI_GetITStatus(EXTI_Line0) != RESET)     {   printf("按键中断唤醒.\r\n");}//清除EXTI0线路挂起位EXTI_ClearITPendingBit(EXTI_Line0);
}void USART1_IRQHandler(void)
{unsigned char code;if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET){     code=USART_ReceiveData(USART1);printf("串口中断唤醒.\r\n");}
} 
睡眠模式的各种特性
特性                                                                                         说明
立即睡眠 在执行__WFI或__WFE指令时立即进入睡眠模式
退出时睡眠 在退出优先级最低的中断服务程序后才进入睡眠模式
进入方式

内核寄存器SLEEPDEEP=0,然后调用WFI或者WFE指令即可进入睡眠模式

另外若内核寄存器SLEEPONEXIT=0,进入“立即睡眠”模式;SLEEPONEXIT=1,进入“退出时睡眠”

唤醒方式

如果是使用WFI指令睡眠,则可使用任意中断唤醒

如果是使用WFE指令睡眠,则由事件唤醒

睡眠时 关闭内核时钟,内核停止,而外设正常运行,在软件上表现为不再执行新的代码。这个状态会保留睡眠前的内核寄存器、内存数据(RAM数据),所有的I/O引脚都保持它们在运行模式时的状态
唤醒延时 无延时
唤醒后 若有中断唤醒,先进入中断,退出中断服务程序后,接着执行WFI指令后的程序;若由事件唤醒,直接执行WFE后的程序

注意:在系统处于睡眠低功耗模式(包括后面介绍的停止模式、待机模式)时,不能用下载器进行程序下载,所以下载程序时要先把系统唤醒。或者使用如下方法:按着板子的复位键,点击电脑端的“下载”,然后松开复位键,就能正常给板子下载程序了。

4.停止模式实验

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

停止模式的功耗比睡眠模式更低,代码操作上相对比睡眠模式复杂一点。跟睡眠模式的唤醒不同,只有EXTI线的中断才能退出停止模式,因为其他外设在停止模式时被关闭,并不能响应中断。将mani函数替换为下面代码,其他不变:

int main(void)
{   USART1_Config();EXTI_Key_Config();NVIC_Configuration();//配置中断控制器NVICRCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);//使能电源管理单元的时钟while(1){printf("STM32正常运行.\r\n");Delay(0xfffff);printf("STM32进入停止模式.\r\n");PWR_EnterSTOPMode(PWR_Regulator_LowPower,PWR_STOPEntry_WFI);//进入停止模式,设置电压调节器为低功耗模式,等待中断唤醒//PWR_EnterSTOPMode(PWR_Regulator_ON,PWR_STOPEntry_WFI);//进入停止模式,设置电压调节器为正常模式,等待中断唤醒//开始等待任意EXTI线中断唤醒SystemInit();//唤醒后需要恢复系统时钟,因为退出停止模式后,系统默认使用的HSI作为系统时钟/*实际上在运行main函数前,会先执行SystemInit函数以配置系统时钟,这个在启动文件里可以看到。*///刚退出停止模式时,使用HSI作为系统时钟,回影响串口波特率//输出不对,在重新配置时钟后才能使用串口的输出Delay(0xfffff);printf("已退出停止模式.\r\n");}
}
停止模式的各种特性
特性 说明
调压器低功耗模式 调压器可工作在正常模式或低功耗模式,可进一步降低功耗
进入方式

内核寄存器SLEEPDEEP=1,PWR_CR寄存器的PDDS=0,然后调用WFI或者WFE指令即可进入睡眠模式

PWR_CR寄存器的LPDS=0时,调压器工作在正常模式,LPDS=1时工作在低功耗模式

除了通过配置寄存器,还可以直接调用标准库函数PWR_EnterSTOPMode,如上代码

唤醒方式

如果是WFI指令进入停止模式的,可使用任意EXTI线的中断唤醒

如果是WFE指令进入停止模式的,可使用任意配置为事件模式的EXTI线事件唤醒

停止时 内核停止,外设也停止。这个状态会保留停止前的内核寄存器、内存的数据(RAM)
唤醒方式 基础延时是HSI振荡器的启动时间,若调压器工作在低功耗模式,还需要加上调压器从低功耗模式切换至正常模式下的时间
唤醒后 若有中断唤醒,先进入中断,退出中断服务程序后,接着执行WFI指令后的程序;若由事件唤醒,直接执行WFE后的程序。唤醒后,STM32会使用HSI作为系统时钟

5.待机模式实验

待机模式可实现系统的最低功耗。该模式是在Cortex-M3深睡眠模式时关闭电压调节器。整个1.8V供电区域被断电。PLL、HSI和HSE振荡器也被断电。SRAM和寄存器内容丢失。只有备份的寄存器和待机电路维持供电。也就是说从待机模式唤醒后,由于没有之前代码的运行记录,只能对芯片复位,重新检测boot条件,从头开始执行程序。它有4种唤醒方式,分别是WAUP(PA0)引脚的上升沿、RTC闹钟事件、NRST引脚的复位和IWDG(独立看门狗)复位。

我们不需要对PA.0引脚进行如上面的初始化,也不需要初始化一个外部中断,将下面两个函数替换,其余保持不变:

int main(void)
{   USART1_Config();//EXTI_Key_Config();//配置中断控制器NVICNVIC_Configuration();RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);//使能电源管理单元的时钟if(PWR_GetFlagStatus(PWR_FLAG_WU)){printf("\r\n待机模式复位.\r\n");}else{printf("\r\n非待机模式复位.\r\n");}while(1){printf("STM32正常运行.\r\n");Delay(0xfffff);printf("STM32进入待机模式.\r\n");PWR_ClearFlag(PWR_FLAG_WU);//清除唤醒标志状态PWR_WakeUpPinCmd(ENABLE);//使能Wake引脚的唤醒功能,使能PA0PWR_EnterSTANDBYMode();//进入待机模式}
}static void NVIC_Configuration(void)
{NVIC_InitTypeDef NVIC_InitStructure;NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);    NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;               NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;      NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;    //NVIC_Init(&NVIC_InitStructure);//使能外部中断 PA.0NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;     NVIC_Init(&NVIC_InitStructure);//使能串口1中断
}

程序下载后,按下复位键,串口会打印非待机模式复位,接着运行while函数,延时后进入待机模式,等待唤醒,在PA0引脚给上升沿信号,串口打印已待机模式复位,代码重头开始执行。

待机模式的各种特性
特性 说明
进入方式 内核寄存器SLEEPDEEP=1,PWR_CR寄存器中的PDDS=1,PWR_CR寄存器中的唤醒状态为WUF=0,然后调用WFI或者调用WFE指令即可进入待机模式(没区别)
唤醒方式 通过WAUP引脚的上升沿,RTC闹钟、唤醒、入侵、时间戳事件或NRST引脚外部复位及IWDG复位唤醒
待机时 内核停止,片上外设也停止;内核寄存器、内存的数据会丢失;除了复位引脚、RTC_AF1引脚及WAUP引脚外,其他I/O口均工作在高阻态
唤醒延迟 芯片复位时间
唤醒后 相当于芯片复位,在程序表现为从头开始执行代码(等于重新上电)

最后,除了利用上面三种模式实现低功耗外,还可以在运行模式下,关闭某些外设时钟或者利用分频器降低外设时钟,同样也可以减低系统功耗。电池备份区域部分这里没有细说,后面单独一篇介绍。

道虽迩,不行不至,事虽小,不为不成。——《荀子》

stm32之电源管理(实现低功耗)相关推荐

  1. STM32笔记--电源管理

    为什么STM32需要电源管理: 在很多应用场合,对电子设备的功耗要求非常苛刻.如某些传感器信息采集设备,仅靠小型的电池提供电源,要求工作长达数年之久,且期间不需要任何维护.为此,大多数 MCU 都会提 ...

  2. stm32外部中断_STM32学习笔记 | 电源管理及低功耗设计要点

    一款好的电子产品,都需要认真考虑电源管理的问题,电池供电的产品更应该注意低功耗的实现. STM32电源介绍 嵌入式开发直播课 - STM32 USART串口的应用 - 创客学院直播室​www.make ...

  3. STM32CubeMX学习笔记(15)——电源管理(PWR)低功耗睡眠模式

    一.低功耗模式简介 系统提供了多个低功耗模式,可在 CPU 不需要运行时(例如等待外部事件时)节省功耗.由用户根据应用选择具体的低功耗模式,以在低功耗.短启动时间和可用唤醒源之间寻求最佳平衡. 睡眠模 ...

  4. STM32CubeMX学习笔记(16)——电源管理(PWR)低功耗停止模式

    一.低功耗模式简介 系统提供了多个低功耗模式,可在 CPU 不需要运行时(例如等待外部事件时)节省功耗.由用户根据应用选择具体的低功耗模式,以在低功耗.短启动时间和可用唤醒源之间寻求最佳平衡. 睡眠模 ...

  5. STM32CubeMX学习笔记(17)——电源管理(PWR)低功耗待机模式

    一.低功耗模式简介 系统提供了多个低功耗模式,可在 CPU 不需要运行时(例如等待外部事件时)节省功耗.由用户根据应用选择具体的低功耗模式,以在低功耗.短启动时间和可用唤醒源之间寻求最佳平衡. 睡眠模 ...

  6. S32K3xx电源管理(低功耗)学习

    S32K3xx电源管理学习 目录 S32K3xx电源管理学习 一.S32K3xx的两种工作模式 二.S32K3xx在两种模式下允许运行哪些外设 三.S32K3xx从Standby模式唤醒后程序从哪里允 ...

  7. ESPIDF开发ESP32学习笔记【电源管理与低功耗模式】

    电源管理 ESP-IDF中集成的电源管理算法可以根据应用程序组件的需求,调整外围总线 (APB) 频率.CPU 频率,并使芯片进入 Light-sleep 模式,尽可能减少运行应用程序的功耗 应用程序 ...

  8. 【STM32】电源控制、低功耗模式(实例:待机模式)

    STM32F1xx官方资料: <STM32中文参考手册V10>-第4章4.3小节 低功耗模式 STM32的电源控制 STM32的电源框图 STM32的工作电压(VDD)为2.0-3.6V. ...

  9. 1566_AURIX_TC275_电源管理_低功耗模式

    全部学习汇总:GreyZhang/g_TC275: happy hacking for TC275! (github.com) Idle模式每一个核都可以单独进入,但是standby.sleep模式是 ...

最新文章

  1. UBuntu 系统设置禁用快捷键
  2. AI 风投的下一个拐点是进还是退?
  3. 打开mobilenet——ssd的demo.py显示这样的错误解决方法:Intel MKL FATAL ERROR: Cannot load libmkl_avx.so or libmkl_def.s
  4. struct stat结构体简介
  5. 云在天之南——我的七天七夜(率性苍山洱海)
  6. Python练习:平方值格式化
  7. C#.NET学习笔记2---C#.第一个C#程序
  8. 在命令行中使用vs编译器
  9. Mysql错误:#1054 - Unknown column '字段名' in 'field list'
  10. 【色彩管理】Lab色彩模式详解
  11. win8服务器备份在哪个文件夹,iPhone备份文件在哪里?Win8系统路径介绍
  12. WARN: Establishing SSL connection without server‘s identity verification is not recommended 的解决方法
  13. 在arcengine中实现图片预览
  14. L2-037 包装机
  15. 【VisionMaster】二次开发之第三方库的使用
  16. 服务器主板纽扣电池型号,纽扣电池的常见型号(cr2032,cr2450)怎么看
  17. 2022 程序员必读书单合集,别炫砂糖橘了,快来趁着春节一起读读书~
  18. .NET发送邮件和接收邮件
  19. Linkedin领英怎么导出非好友电话、邮箱等资料
  20. iapp一本通php教程,iApp教程post详细教程

热门文章

  1. python批量导入MongoDB数据库
  2. 北哥大话Yii2缓存机制 - File缓存
  3. 警惕技术人员的极端性
  4. 关于easyui datagrid分页的json格式
  5. 前端月趋势榜:6 月新增的、最热门的 20 个前端开源项目 - 2106
  6. 干死该死的横向滚动条
  7. Android配置启动界面:Activity基本使用
  8. helm3 helm-push插件安装及基本使用
  9. JVM调优:定位垃圾的常用算法
  10. IOUtils工具类复制输入输出流示例