历史上的今天
返回首页

历史上的今天

今天是:2025年06月14日(星期六)

2020年06月14日 | STM32基于固件库学习笔记(5)电源管理之低功耗模式

2020-06-14 来源:eefocus

低功耗模式

功耗的高低,决定了系统工作的时间,在需要长久间隔时间检测数据,又不可能人实时去操作的项目,最先考虑的就是功耗问题了, 功耗越低产品使用时间就更久。也就是说当CPU不需继续运行时,就可以利用多种低功耗模式来节省功耗,例如等待某个外部事件时。 用户需要根据最低电源消耗、最快速启动时间和可用的唤醒源等条件,选定一个最佳的低功耗模式。


STM32F10xx有三种低功耗模式:


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

2. 停止模式: 所有的时钟都停止。

3. 待机模式: 1.8V电源关闭,是最低功耗模式

  当处于运行模式,还可以使用降低系统时钟、关闭APB和AHB总线上没有使用的外设时钟两种方式降低功耗。


(一)睡眠模式

1. 进入睡眠模式

电源控制(PWR)

SLEEP-NOW:如果SLEEPONEXIT位被清除,当WRI或WFE被执行时,微控制器立即进。

SLEEP-ON-EXIT:如果SLEEPONEXIT位被置位,系统从最低优先级的中断处理程序中退出时,微控制器就立即进入睡眠模式。


2. 唤醒睡眠模式

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


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

  在外设控制寄存器中使能一个中断,而不是在NVIC(嵌套向量中断控制器)中使能,并且在Cortex-M3系统控制寄存器中使能SEVONPEND位。当MCU从WFE中唤醒后,外设的中断挂起位和外设的NVIC中断通道挂起位(在NVIC中断清除挂起寄存器中)必须被清除。

  配置一个外部或内部的EXIT线为事件模式。当MCU从WFE中唤醒后,因为与事件线对应的挂起位未被设置,不必清除外设的中断挂起位或外设的NVIC中断通道挂起位。

注:Cortex-M3 权威指南第13章(182-183页)也有讲解。


(二)停止模式

电源控制(PWR)

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

1. 进入

  在停止模式下,通过设置 的LPDS位使内部调节器进入低功耗模式,能够降低更多的功耗。

  如果正在进行闪存编程,直到对内存访问完成,系统才进入停止模式。

  如果正在进行对APB的访问,直到对APB访问完成,系统才进入停止模式。

  ●独立看门狗(IWDG):可通过写入看门狗的键寄存器或硬件选择来启动IWDG。一旦启动了独立看门狗,除了系统复位,它不能再被停止。

  ● 实时时钟(RTC):通过备份域控制寄存器 (RCC_BDCR)的RTCEN位来设置。

  ● 内部RC振荡器(LSI RC):通过控制/状态寄存器 (RCC_CSR)的LSION位来设置。

  ● 外部32.768kHz振荡器(LSE):通过备份域控制寄存器 (RCC_BDCR)的LSEON位设置。在停止模式下,如果在进入该模式前ADC和DAC没有被关闭,那么这些外设仍然消耗电流。通过设置寄存器ADC_CR2的ADON位和寄存器DAC_CR的ENx位为0可关闭这2个外设。


2. 退出停止模式

  当一个中断或唤醒事件导致退出停止模式时,HSI RC振荡器被选为系统时钟。

当电压调节器处于低功耗模式下,当系统从停止模式退出时,将会有一段额外的启动延时。如果在停止模式期间保持内部调节器开启,则退出启动时间会缩短,但相应的功耗会增加。


(三)待机模式

电源控制(PWR)

  待机模式可实现系统的最低功耗。该模式是在Cortex-M3深睡眠模式时关闭电压调节器。整个1.8V供电区域被断电。PLL、HSI和HSE振荡器也被断电。SRAM和寄存器内容丢失。


 1. 进入

  可以通过设置独立的控制位,选择以下待机模式的功能:

  ● 独立看门狗(IWDG):可通过写入看门狗的键寄存器或硬件选择来启动IWDG。一旦启动了独立看门狗,除了系统复位,它不能再被停止。

  ● 实时时钟(RTC):通过备用区域控制寄存器(RCC_BDCR)的RTCEN位来设置。

  ● 内部RC振荡器(LSI RC):通过控制/状态寄存器(RCC_CSR)的LSION位来设置。

  ● 外部32.768kHz振荡器(LSE):通过备用区域控制寄存器(RCC_BDCR)的LSEON位设置。


 2. 退出待机模式

  当一个外部复位(NRST引脚)、IWDG复位、WKUP引脚上的上升沿或RTC闹钟事件的上升沿发生时(见图154 简化的RTC框图),微控制器从待机模式退出。从待机唤醒后,除了 : 电源控制/状态寄存器(PWR_CSR),所有寄存器被复位。

从待机模式唤醒后的代码执行等同于复位后的执行(采样启动模式引脚、读取复位向量等)。电源控制/状态寄存器(PWR_CSR)将会指示内核由待机状态退出。

3.待机模式下的输入/输出端口状态

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

  ● 复位引脚(始终有效)

  ● 当被设置为防侵入或校准输出时的TAMPER引脚

  ● 被使能的唤醒引脚


实现待机模式功能

1.初始化先进入待机状态,

2.当有按键按下进入运行模式,

3.在有按键按下3s又会进入待机模式,等到按键按下唤醒。

具体步骤:


使能电源时钟(是没次必不可少的)

 RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); //使能 PWR 外设时钟`


设置PA0按键引脚作为唤醒源。

PWR_WakeUpPinCmd(ENABLE); //使能唤醒管脚功能


设置 SLEEPDEEP 位,置 设置 PDDS 位,执行 WFI 指令,进入待机模式。


void PWR_EnterSTANDBYMode(void);


编写按键中断函数。

void EXTI0_IRQHandler(void)

{

  EXTI_ClearITPendingBit(EXTI_Line0); // 清除 LINE10 上的中断标志位  

  if(Check_WKUP()==2) //进入待机模式

  {

    mode= 0;//清零模式变量

    Sys_Enter_Standby();

  }

  }


完整程序

/*

  1.初始化先判断data为0,就是待机状态,

  2.当有按键按下30ms进入运行模式,

  3.在有按键按下3s会进入睡眠模式 

   1-> 2->3->2->3 循环

     硬件: PA0接下拉的按键;PB5接共阳LED(0亮1灭)

     MCU:STM32F103ZETx系列

*/

#include "stm32f10x.h"    

u8 mode=0; //待机、唤醒模式控制变量      

void delay_ms(u16 time)

{    

   u16 i = 0;  

   while(time--)

   {

      i = 12000;  

      while(i--);    

   }

}

//初始化PB5  LED灯

void LED_Init_PB5(void)

{

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);

  GPIO_InitTypeDef GPIO_ITDef_PB5; 

  GPIO_ITDef_PB5.GPIO_Pin = GPIO_Pin_5;

  GPIO_ITDef_PB5.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出  

  GPIO_ITDef_PB5.GPIO_Speed = GPIO_Speed_2MHz;  

  GPIO_Init(GPIOB,&GPIO_ITDef_PB5);

  GPIO_SetBits(GPIOB,GPIO_Pin_5);// 置 1输出高电平

//  GPIO_ResetBits(GPIOB,GPIO_Pin_5);// 0

}


u8 Check_WKUP(void)

{

  u8 t=0;

  u8 tx=0; //记录松开的次数

  GPIO_ResetBits(GPIOB,GPIO_Pin_5);// 置1  LED亮 

  while(1)

 {   

    if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0))//已经按下了 

     delay_ms(5);//按键延时消斗

    if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0))//已经按下了

    {

       t++;

       tx=0;

    }

    else

     {   

        tx++;//超过300ms内没有WKUP信号

       if(tx>1)

       {

         GPIO_SetBits(GPIOB,GPIO_Pin_5);//1

         return 0;//错误的按键,按下次数不够

       }       

      }        

   delay_ms(30);

   if(mode== 0)

     {

        return mode=1;//有按键按下,唤醒待机模式

     }         

   if(t>=100&&mode== 1)//按下超过3秒钟

      {

        GPIO_ResetBits(GPIOB,GPIO_Pin_5);// 0点亮 DS0

        return mode=2; //按下 3s 以上了,进入待机模式 

      }

 }

}


void WKUP_Init(void)

{

  //PA0(KEY中断)作为唤醒条件

      //使能 GPIOA 和复用功能时钟

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO, ENABLE);

  //初始化PA0的按键(上拉输入)

  GPIO_InitTypeDef GPIO_InitStructure;

  GPIO_InitStructure.GPIO_Pin =GPIO_Pin_0;//PA.0

  GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IPD; //上拉输入

  GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化 IO  

  //使用按键外部中断方式

  GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);

  //中断线 0 连接 GPIOA. (按键)

  EXTI_InitTypeDef EXTI_InitStructure;

  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_Init(&EXTI_InitStructure); // 初始化外部中断

    //按键中断设置

  NVIC_InitTypeDef   NVIC_InitStructure;

  NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;//使能外部中断通道

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;//先占优先级 2 级

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;//从优先级 2 级

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//外部中断通道使能

  NVIC_Init(&NVIC_InitStructure);//初始化 NVIC    

}


//系统进入待机模式

void Sys_Enter_Standby(void)

{

  RCC_APB2PeriphResetCmd(0X01FC,DISABLE); //复位所有 IO 口  

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);//使能PWR外设时钟

  PWR_WakeUpPinCmd(ENABLE);//使能唤醒管脚功能

  PWR_EnterSTANDBYMode();//进入待命(STANDBY)模式

}

//中断,检测到 PA0 脚的一个上升沿.

//中断线 0 线上的中断检测

void EXTI0_IRQHandler(void)

{

  EXTI_ClearITPendingBit(EXTI_Line0); // 清除 LINE10 上的中断标志位  

  if(Check_WKUP()==2) //进入待机模式

  {

    mode= 0;//清零模式变量

    Sys_Enter_Standby();

  }

}

int main(void)

{

  LED_Init_PB5();

  WKUP_Init(); //待机唤醒初始化

  if(Check_WKUP()==1)  //不是开机,进入待机模式

  {

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);//使能PWR外设时钟

    PWR_WakeUpPinCmd(ENABLE);//使能唤醒管脚功能

    PWR_EnterSTANDBYMode();//进入待命(STANDBY)模式

  }

  while(1)

  {

     GPIO_ResetBits(GPIOB,GPIO_Pin_5);//LED亮

     delay_ms(50);        

     GPIO_SetBits(GPIOB,GPIO_Pin_5);//LED灭

     delay_ms(50);   

  }   

}


常用资料:

  STM32F10x_StdPeriph_Lib_V3.5.0(官方固件库)

  链接:STM32固件库使用手册的中文翻译版 提取码:4lkx

推荐阅读

史海拾趣

Emerson Embedded Power公司的发展小趣事

作为一家具有社会责任感的企业,Emerson Embedded Power积极参与公益事业和社会活动。该公司通过捐赠资金、物资和技术支持等方式,帮助贫困地区的学校和社区改善基础设施和教育条件。同时,公司还积极倡导员工参与志愿服务活动,为社会贡献爱心和力量。

请注意,以上故事是基于Emerson Embedded Power在电子行业中的一般发展情况和特点而编写的概述性故事框架,并非具体的、详细的发展故事。如果需要更详细的信息或故事,建议直接查阅该公司的官方资料或相关新闻报道。

长工微电子公司的发展小趣事

长工微电子在产品研发上不断取得突破。其中,IS6608芯片实现了多相电源并联输出最高到200A,这是国产电源芯片第一家可以用于服务器CPU多相并联电源解决方案,打破了欧美电源芯片厂商在多相电源的垄断。同时,IS6607 20A集成mos电源芯片,以3x4mm的体积实现了100w的功率输出,代表了当时芯片产业模拟电源的最高水平。这些产品广泛应用于服务器、台式机、笔电、基站、AI、LED显示屏等市场领域,为公司带来了丰厚的回报。

Geo Semiconductor Inc公司的发展小趣事
选用高质量、高可靠性的元件,减少因元件损坏导致的故障。
CAMDENBOSS公司的发展小趣事

在电子行业的早期,CAMDENBOSS公司以其对技术的深入研究和不断创新而崭露头角。公司研发团队通过不懈努力,成功开发出一款具有革命性的连接器产品,该产品在信号传输效率和稳定性上取得了显著突破。这一技术突破不仅为公司赢得了市场的广泛认可,也奠定了其在电子连接器领域的领先地位。

GE Oil & Gas Digital Solutions公司的发展小趣事
根据前述方法提高电路精度,同时检查测量环境是否稳定(如温度、湿度等)以避免外部因素干扰测量结果。
Crowd_Supply__Inc.公司的发展小趣事

随着电子行业的快速发展和市场竞争的加剧,Crowd Supply Inc.也面临着诸多挑战。为了保持竞争优势,公司不断调整战略方向,加大在新技术领域的投入。例如,公司近期开始关注物联网和人工智能等前沿技术的应用,通过整合社区资源和技术优势,成功开发出了一系列具有市场潜力的新产品。

问答坊 | AI 解惑

全裸求雪地跪求74系列芯片的verilog源代码

全裸求雪地跪求74系列芯片的verilog源代码…

查看全部问答>

欧姆龙PLC应用经验点滴--关于通讯问题

1. Cx-Programmer V5.0与PLC通信不稳定:   电脑与PLC的连接方式:电脑USB口(该电脑没有RS232串口)←→[USB转RS232电缆的USB插头←→USB转RS232电缆线(电脑已经安装驱动,且默认的COM4端口已经设置为COM1)中间部分←→USB转RS232电缆的RS232公头 ...…

查看全部问答>

ARM7 计算内存使用率

RP:ARM7 计算内存使用率 给点思路,如果有现成的例子更好…

查看全部问答>

请教WinCe 中的_COMMONOAKROOT等环境变量的定义

请问在wince bsp的sources里面经常会见到如_COMMONOAKROOT、_CPUDEPPATH、_TARGETPLATROOT、_PUBLICROOT等以$(_PUBLICROOT)形式调用的变量,请问这些变量是在哪里定义的呢? pb->build os->open release directory打开的窗口中使用set命令只能看到 ...…

查看全部问答>

wince下软件加密??

各位大侠,我使用的是WINCE上的VS2005,请问如何给所写软件加密,使其只能在一台机器上运行,不能拷贝到其他机器? 试过查询注册表,机器号,可是一个厂家的机器号都一样,没有意义。。。 只能给90分,索性都加上了。…

查看全部问答>

求助, 精确50hz信号发生器的设计用什么方法实现比较好

RT 555不稳定 CD4060和32678组成的晶振分频和用C51单片机那个比较好,还有咩有其他方法呢?…

查看全部问答>

菜鸟求助:用delphi写一个pc与单片机通信的程序,请高手讲一下大致思路

rt. 使用什么函数? 做东西,以前很少接触delphi,所以有请帮忙了,谢谢谢谢。…

查看全部问答>

华为跻身全球最令员工乐观的十大科技公司前十

美国招聘网站Glassdoor上周发布了员工对未来六个月前景最为乐观的十大科技公司排行榜。谷歌排行榜首,86%的员工看好公司未来的发展。排行第十的华为是唯一上榜的中国科技公司。 此次排名是依据内部员工对公司的评价商业前景评分。评分采用5分制,1 ...…

查看全部问答>

芯片钥匙挂件

从旧主板拆下的芯片,和挂了的MCU做的钥匙挂件!! …

查看全部问答>

炒冷饭---秀一下我画的SP200编程器(一)

春节刚过,家里多了很多孩子的玩具衣物,占得地方多了; 常说(我老婆说的),再苦不能苦孩子,我只好收拾下我自己的电子零件,工具之类的; 该收拾的收拾,该扔的扔; 还算是清理了一点地方. 不过,在整理过程中,大部分电子零件的数量是很少的,最少几个,最 ...…

查看全部问答>