stm32专题三十一:电源管理实现低功耗

这个滞回电压,是为了让单片机容忍一定程度的电压波动,而不是只要电压稍微一变化,就立刻掉电复位。

为了方便进行电源管理,STM32 把它的外设、内核等模块跟据功能划分了供电区域,其内部电源区域划分如图:

CPU内核为1.8V供电,以降低功耗,整个1.8V供电区域由电压调节器单独供电,有时CPU可以休眠,有时可以不休眠,这是由电压调节器来提供的。 

stm32功耗模式        

按功耗由高到低排列,STM32 具有运行、睡眠、停止和待机四种工作模式。上电复位后 STM32处于运行状态时,当内核不需要继续运行,就可以选择进入后面的三种低功耗模式降低功耗,这三种模式中,电源消耗不同、唤醒时间不同、唤醒源不同,用户需要根据应用需求,选择最佳的低功耗模式。三种低功耗的模式说明见下表。

睡眠模式下,任何中断都可以唤醒内核,外部 / 内部高速时钟保持打开,调压器保持打开,因此,内核只要被唤醒,就能马上正常的执行程序(优点:响应速度快;缺点:功耗比较大);

停止模式下,HSE和HSI被关闭,调压器可选开启或低功耗模式(若选为低功耗模式,则还需要加上调压器从低功耗切换至正常模式下的时间),外部中断唤醒内核。当内核被唤醒时,需要重新配置系统时钟使用外部 HSE 且 PLL 正常倍频(System_Init函数),这个过程就会消耗一定时间;否则程序会直接使用 HSI(不倍频) = 8MHz 作为系统时钟,此时系统运行的相当慢,一些对时钟要求较高的函数配置会无法运行(优点:功耗较小;缺点:需要重新配置系统时钟,响应速度慢);

待机模式下,整个1.8V供电区域被关闭,调压器被关闭,只能特定方式唤醒。唤醒之后程序从最开始(启动文件)执行(优点:功耗最低;缺点,每次都是复位执行);

3种模式的详细描述和寄存器配置 

内核寄存器配置说明如下:

 关于立即睡眠和退出后睡眠的区别(中文参考手册):

开启后会默认使用HSI作为系统时钟,通常我们为确保正常使用,还要重新开启HSE: 

相关的寄存器配置:

电源控制寄存器,配置停止模式(正常 or 低功耗):

 相关的寄存器配置:

电源管理库函数 

1 配置PVD检测函数 PWR_PVDLevelConfig ,其实就是写入PWR_CR寄存器的这几位:

 

标准库函数源码:

/**
  * @brief  Configures the voltage threshold detected by the Power Voltage Detector(PVD).
  * @param  PWR_PVDLevel: specifies the PVD detection level
  *   This parameter can be one of the following values:
  *     @arg PWR_PVDLevel_2V2: PVD detection level set to 2.2V
  *     @arg PWR_PVDLevel_2V3: PVD detection level set to 2.3V
  *     @arg PWR_PVDLevel_2V4: PVD detection level set to 2.4V
  *     @arg PWR_PVDLevel_2V5: PVD detection level set to 2.5V
  *     @arg PWR_PVDLevel_2V6: PVD detection level set to 2.6V
  *     @arg PWR_PVDLevel_2V7: PVD detection level set to 2.7V
  *     @arg PWR_PVDLevel_2V8: PVD detection level set to 2.8V
  *     @arg PWR_PVDLevel_2V9: PVD detection level set to 2.9V
  * @retval None
  */
void PWR_PVDLevelConfig(uint32_t PWR_PVDLevel)
{
  uint32_t tmpreg = 0;
  /* Check the parameters */
  assert_param(IS_PWR_PVD_LEVEL(PWR_PVDLevel));
  tmpreg = PWR->CR;
  /* Clear PLS[7:5] bits */
  tmpreg &= CR_PLS_MASK;
  /* Set PLS[7:5] bits according to PWR_PVDLevel value */
  tmpreg |= PWR_PVDLevel;
  /* Store the new value */
  PWR->CR = tmpreg;
}

2 WFI 与 WFE 命令:

/* ###################  Compiler specific Intrinsics  ########################### */
 
#if defined ( __CC_ARM   ) /*------------------RealView Compiler -----------------*/
/* ARM armcc specific functions */
 
#define __enable_fault_irq                __enable_fiq
#define __disable_fault_irq               __disable_fiq
 
#define __NOP                             __nop
#define __WFI                             __wfi
#define __WFE                             __wfe
#define __SEV                             __sev
#define __ISB()                           __isb(0)
#define __DSB()                           __dsb(0)
#define __DMB()                           __dmb(0)
#define __REV                             __rev
#define __RBIT                            __rbit
#define __LDREXB(ptr)                     ((unsigned char ) __ldrex(ptr))
#define __LDREXH(ptr)                     ((unsigned short) __ldrex(ptr))
#define __LDREXW(ptr)                     ((unsigned int  ) __ldrex(ptr))
#define __STREXB(value, ptr)              __strex(value, ptr)
#define __STREXH(value, ptr)              __strex(value, ptr)
#define __STREXW(value, ptr)              __strex(value, ptr)

 3 进入停止模式

配置PWR_CR寄存器的这两个位,以及SLEEPDEEP位。

/**
* @brief 进入停止模式
*
* @note 在停止模式下所有 I/O 的会保持在停止前的状态
* @note 从停止模式唤醒后,会使用 HSI 作为时钟源
* @note 调压器若工作在低功耗模式,可减少功耗,但唤醒时会增加延迟
* @param PWR_Regulator: 设置停止模式时调压器的工作模式
* @arg PWR_MainRegulator_ON: 调压器正常运行
* @arg PWR_Regulator_LowPower: 调压器低功耗运行
* @param PWR_STOPEntry: 设置使用 WFI 还是 WFE 进入停止模式
* @arg PWR_STOPEntry_WFI: WFI 进入停止模式
* @arg PWR_STOPEntry_WFE: WFE 进入停止模式
* @retval None
*/
void PWR_EnterSTOPMode(uint32_t PWR_Regulator, uint8_t PWR_STOPEntry)
{
	 uint32_t tmpreg = 0;
	 /* 检查参数 */
	 assert_param(IS_PWR_REGULATOR(PWR_Regulator));
	 assert_param(IS_PWR_STOP_ENTRY(PWR_STOPEntry));
	
	 /* 设置调压器的模式 ------------*/
	 tmpreg = PWR->CR;
	 /* 清除 PDDS 及 LPDS 位 */
	 tmpreg &= CR_DS_MASK;
	 /* 根据 PWR_Regulator 的值(调压器工作模式)配置 LPDS,MRLVDS 及 LPLVDS 位*/
	 tmpreg |= PWR_Regulator;
	 /* 写入参数值到寄存器 */
	 PWR->CR = tmpreg;
	 /* 设置内核寄存器的 SLEEPDEEP 位 */
	 SCB->SCR |= SCB_SCR_SLEEPDEEP;
	
	 /* 设置进入停止模式的方式-----------------*/
	 if (PWR_STOPEntry == PWR_STOPEntry_WFI) {
	 /* 需要中断唤醒 */
	 __WFI();
	 } else {
	 /* 需要事件唤醒 */
	 __WFE();
	 }
	
	 /* 以下的程序是当重新唤醒时才执行的,清除 SLEEPDEEP 位的状态 */
	 SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP);
}

 在执行最后一句代码前,系统由于调用了__WFI 或 __WFE,已经进入了停止模式,因此,这句清除SLEEPDEEP 位并不会执行。而当内核重新被唤醒时,才会清除SLEEPDEEP位,方便使用。

4 进入待机模式

/**
* @brief 进入待机模式
* @note 待机模式时,除以下引脚,其余引脚都在高阻态:
* -复位引脚
* - RTC_AF1 引脚 (PC13) (需要使能侵入检测、时间戳事件或 RTC 闹钟事件)
* - RTC_AF2 引脚 (PI8) (需要使能侵入检测或时间戳事件)
* - WKUP 引脚 (PA0) (需要使能 WKUP 唤醒功能)
* @note 在调用本函数前还需要清除 WUF 寄存器位
* @param None
 * @retval None
 */
void PWR_EnterSTANDBYMode(void)
{
	/* 清除 Wake-up 标志 */
	PWR->CR |= PWR_CR_CWUF;
	/* 选择待机模式 */
	PWR->CR |= PWR_CR_PDDS;
	/* 设置内核寄存器的 SLEEPDEEP 位 */
	SCB->SCR |= SCB_SCR_SLEEPDEEP;
	/* 存储操作完毕时才能进入待机模式,使用以下语句确保存储操作执行完毕 */
	#if defined ( __CC_ARM )
	__force_stores();
	#endif
	/* 等待中断唤醒 */
	__WFI();
}

  • 20
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
STM32实现的主要方法有两种,一种是使用STM32提供的模式,另一种是自己编写代码实现。 1. 使用STM32提供的模式 STM32提供了多种模式,包括Sleep、Stop、Standby等。不同的模式可以根据需求选择,具体的实现方法如下: 1.1 Sleep模式 在Sleep模式下,系统时钟会停止,但是I/O口和外部中断仍然可以工作。可以通过设置RCC->APB1LPENR和RCC->APB2LPENR寄存器来关闭不需要的外设时钟,以达到降的目的。进入Sleep模式的方法是调用以下函数: ``` void HAL_PWR_EnterSLEEPMode(uint32_t Regulator, uint8_t SLEEPEntry) ``` 其中,Regulator参数用于选择进入Sleep模式后电源的状态,可以选择DCDC或LDO,SLEEPEntry参数用于选择进入Sleep模式前是否关闭中断。 1.2 Stop模式 在Stop模式下,系统时钟和所有外设时钟都会停止。进入Stop模式的方法是调用以下函数: ``` void HAL_PWR_EnterSTOPMode(uint32_t Regulator, uint8_t STOPEntry) ``` 其中,Regulator参数用于选择进入Stop模式后电源的状态,可以选择DCDC或LDO,STOPEntry参数用于选择进入Stop模式前是否关闭中断。 1.3 Standby模式 在Standby模式下,系统时钟和所有外设时钟都会停止,并且芯片的状态会保存到备份寄存器中。进入Standby模式的方法是调用以下函数: ``` void HAL_PWR_EnterSTANDBYMode(void) ``` 2. 自己编写代码实现 除了使用STM32提供的模式外,还可以自己编写代码实现。具体的实现方法如下: 2.1 关闭不需要的外设时钟 可以通过设置RCC->APB1ENR和RCC->APB2ENR寄存器来关闭不需要的外设时钟,以达到降的目的。 2.2 降系统时钟频率 可以通过设置RCC->CFGR寄存器来降系统时钟频率,以达到降的目的。 2.3 休眠前关闭所有中断 在进入休眠前,关闭所有中断可以降。 2.4 使用模式的外设 一些外设在工作时也会消较大的,可以使用模式的外设来达到降的目的。 以上是实现STM32的主要方法,根据具体需求选择合适的方法即可。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值