【STM32】HAL库-电源控制(低功耗模式)

电源框图

在这里插入图片描述

STM32 的电源系统主要分为备份域电路、内核电路以及 ADC 电路三部分

  • 备份域电路
    STM32 的 LSE 振荡器、RTC、备份寄存器及备份 SRAM 这些器件被包含进备份域电路中,这部分的电路可以通过 STM32 的 VBAT 引脚获取供电电源,在实际应用中一般会使用 3V 的钮扣电池对该引脚供电。
    当 VDD 主电源存在时,由于 VDD 电压较高,备份域电路通过 VDD 供电,当 VDD 掉电时,备份域电路由钮扣电池通过 VBAT 供电,保证电路能持续运行,从而可利用它保留关键数据。

  • 调压器供电电路(1.2V域)
    在 STM32 的电源系统中调压器供电的电路是最主要的部分,调压器为除了备份域及待机电路以外的所有数字电路供电,其中包括内核、数字外设、时钟以及 RAM
    调压器可以运行在“运行模式”、“停止模式”以及“待机模式”。
    在运行模式下,1.2V域全功率运行;
    在停止模式下 1.2V 域运行在低功耗状态,1.2V 区域的所有时钟都被关闭,相应的外设都停止了工作,但它会保留内核寄存器以及 SRAM 的内容;
    在待机模式下,整个 1.2V 域都断电,该区域的内核寄存器及 SRAM 内容都会丢失 (备份区域的寄存器及 SRAM 不受影响)。

  • ADC 电源及参考电压
    为了提高转换精度,STM32 的 ADC 配有独立的电源接口,方便进行单独的滤波。ADC的工作电源使用 VDDA 引脚输入,使用 VSSA 作为独立的地连接,VREF 引脚则为ADC 提供测量使用的参考电压。

电池备份区域

在这里插入图片描述
当VDD断电时,可以保存备份寄存器的内容和维持RTC的功能。
VBAT为RTC、LSE(低速外部时钟)振荡器、备份寄存器和PC13至PC15供电。

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

  • PC14和PC15可以用于GPIO或LSE引脚
  • PC13可以作为通用I/O口、TAMPER引脚、RTC校准时钟、RTC闹钟或秒输出

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

  • PC14和PC15只能用于LSE引脚
  • PC13可以作为TAMPER引脚、RTC闹钟或秒输出

STM32低功耗模式

STM32有三种低功耗模式,分别为:

  • 睡眠模式
  • 停止模式
  • 待机模式

上面介绍的电压调节器也有三种模式,也是运转(正常),停止,待机模式。
在这里插入图片描述
电源控制/状态寄存器(PWR_CSR) 从待机模式唤醒时不被清除

停止模式下,对VDD供电区域的影响仅有HSI和HSE的振荡器关闭,当从停止模式唤醒后,需要重新配置时钟(默认是HSI)。对片外外设寄存器没影响。
系统滴答定时器的中断也会在睡眠/停止模式下唤醒单片机。故需要在进入睡眠/停止模式前失能系统滴答定时器。

STM32在正常模式下,可通过以下措施来降低功耗。

  • 通过对预分频寄存器进行编程,可以降低任意一个系统时钟(SYSCLK、HCLK、PCLK1、PCLK2)的速度。

  • 可以利用预分频器来降低外设的时钟。

  • 任何时候都可以通过停止为外设和内存提供时钟(HCLK和PCLKx)来减少功耗。

睡眠模式

在睡眠模式中,仅关闭了内核时钟,内核停止运行,但其片上外设,核心的外设全都还照常运行,在软件上表现为不再执行新的代码。这个状态会保留睡眠前的内核寄存器、内存的数据。唤醒后 ,若由中断唤醒,先进入中断,退出中断服务程序后,接着执行 WFI指令后的程序;若由事件唤醒,直接接着执行 WFE 后的程序。唤醒延迟:无延迟。(WFI:Wait For Interrupt,WFE:Wait For Event

在睡眠模式下,所有的I/O引脚都保持它们在运行模式时的状态
SRAM和寄存器内容被保留下来

进入睡眠模式

通过执行WFIWFE指令进入睡眠状态。

在执行WFIWFE指令进入睡眠状态前,有两种选项可用于选择睡眠模式进入机制:

  • SLEEP-NOW:如果SLEEPONEXIT位被清除,当WFI或WFE被执行时,微控制器立即进入睡眠模式
  • SLEEP-ON-EXIT:如果SLEEPONEXIT位被置位,系统从最低优先级的中断处理程序中退出时,微控制器就立即进入睡眠模式(这样一来,处理器的所有工作就只是响应中断了,其它时间都在睡眠

进入睡眠模式前,记得把系统滴答定时器关闭。
在这里插入图片描述

退出睡眠模式

  • 如果执行WFI指令进入睡眠模式,任意一个被嵌套向量中断控制器响应的外设中断都能将系统从睡眠模式唤醒,唤醒后先进入中断,退出中断服务程序后,接着执行 WFI指令后的程序
  • 如果执行WFE指令进入睡眠模式,则一旦发生唤醒事件时,微处理器将从睡眠模式退出,唤醒后直接接着执行 WFE 后的程序

唤醒事件由以下方式产生:

  • 在外设控制寄存器中使能一个中断,而不是在NVIC(嵌套向量中断控制器)中使能,并且在系统控制寄存器中使能SEVONPEND位。当MCU从WFE中唤醒后,外设的中断挂起位和外设的NVIC中断通道挂起位(在NVIC中断清除挂起寄存器中)必须被清除
  • 配置一个外部或内部的EXIT线为事件模式。当MCU从WFE中唤醒后,因为与事件线对应的挂起位未被设置,不必清除外设的中断挂起位或外设的NVIC中断通道挂起位

睡眠模式-外部中断唤醒demo

采用STM32F103C8T6单片机,KeilMDK5.32版本

开启外部中断1,用外部中断1来唤醒STM32,WFI指令进入睡眠状态,选择SLEEP-NOW微控制器立即进入睡眠模式。
PC13控制LED灯,LED的亮灭用来指示程序是否在运行
外部中断函数为空,什么也不做

STM32CubeMX配置
外部中断线1为产生中断,下降沿触发。
在这里插入图片描述
在这里插入图片描述

主要代码如下
在睡眠模式下,如果开启了系统滴答定时器,记得关闭系统滴答定时器,因为系统滴答定时器的中断也会唤醒CPU。

  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
	HAL_Delay(1000);//延时1000毫秒
	/* 采用位带操作实现LED翻转 */
	PCout(13) = !PCin(13);
	if(times > 4)
	{
		//HAL_SuspendTick();//停止系统滴答计时器
		CLEAR_BIT(SysTick->CTRL, SysTick_CTRL_ENABLE_Msk);//失能系统滴答定时器
		HAL_PWR_EnterSLEEPMode(0, PWR_SLEEPENTRY_WFI);//WFI指令进入睡眠模式
		times = 0;
		SET_BIT(SysTick->CTRL, SysTick_CTRL_ENABLE_Msk);//使能系统滴答定时器
		//HAL_ResumeTick();//恢复系统滴答计时器
	}
	times++;//循环次数加一
  }

工程文件下载链接

睡眠模式-外部中断唤醒-仅响应中断demo

采用STM32F103C8T6单片机,KeilMDK5.32版本

开启外部中断1,用外部中断1来唤醒STM32,WFI指令进入睡眠状态,选择SLEEP-ON-EXIT系统从最低优先级的中断处理程序中退出时,微控制器就立即进入睡眠模式
PC13控制LED灯,在外部中断函数中翻转LED。

STM32CubeMX配置
与睡眠模式-外部中断唤醒demo一致

主要代码如下

  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
	HAL_Delay(1000);//延时1000毫秒
	if(times > 4)
	{
		PCout(13) = !PCin(13);//LED翻转,指示即将进入睡眠模式
		//HAL_SuspendTick();//停止系统滴答计时器
		CLEAR_BIT(SysTick->CTRL, SysTick_CTRL_ENABLE_Msk);//失能系统滴答定时器
		HAL_PWR_EnableSleepOnExit();//开启仅响应中断,最低优先级中断服务函数结束之后单片机又进入睡眠模式
		HAL_PWR_EnterSLEEPMode(0, PWR_SLEEPENTRY_WFI);//WFI指令进入睡眠模式
		times = 0;
		SET_BIT(SysTick->CTRL, SysTick_CTRL_ENABLE_Msk);//使能系统滴答定时器
		//HAL_ResumeTick();//恢复系统滴答计时器
	}
	times++;//循环次数加一
  }

外部中断服务函数代码:

/**
  * @brief  EXTI line detection callbacks.
  * @param  GPIO_Pin: Specifies the pins connected EXTI line
  * @retval None
  */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	/* 采用位带操作实现LED翻转 */
	PCout(13) = !PCin(13);
}

工程文件下载链接

睡眠模式-外部事件唤醒demo

采用STM32F103C8T6单片机,KeilMDK5.32版本

配置一个外部EXIT1线为事件模式来唤醒STM32,WFE指令进入睡眠状态,选择SLEEP-NOW微控制器立即进入睡眠模式。
PC13控制LED灯,LED的亮灭用来指示程序是否在运行
注意:未开启外部中断(NVIC寄存器中为使能外部中断)

STM32CubeMX配置
在这里插入图片描述

主要代码

  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
	HAL_Delay(1000);//延时1000毫秒
	/* 采用位带操作实现LED翻转 */
	PCout(13) = !PCin(13);
	if(times > 4)
	{
		//HAL_SuspendTick();//停止系统滴答计时器
		CLEAR_BIT(SysTick->CTRL, SysTick_CTRL_ENABLE_Msk);//失能系统滴答定时器
		HAL_PWR_EnterSLEEPMode(0, PWR_SLEEPENTRY_WFE);//WFE指令进入睡眠模式
		times = 0;
		SET_BIT(SysTick->CTRL, SysTick_CTRL_ENABLE_Msk);//使能系统滴答定时器
		//HAL_ResumeTick();//恢复系统滴答计时器
	}
	times++;//循环次数加一
  }

工程文件下载链接

停止模式

在停止模式中,进一步关闭了其它所有的时钟,于是所有的外设都停止了工作,但由于其 1.2V 区域的部分电源没有关闭,还保留了内核的寄存器、内存的信息,所以从停止模式唤醒,并重新开启时钟后,还可以从上次停止处继续执行代码。唤醒后,若由中断唤醒,先进入中断,退出中断服务程序后,接着执行 WFI指令后的程序;若由事件唤醒,直接接着执行 WFE 后的程序。
SRAM和寄存器内容被保留下来
PLL、HSI和HSE RC振荡器的功能被禁止
所有的I/O引脚都保持它们在运行模式时的状态

系统时钟:停止模式唤醒后,STM32会使用 HSI(f1的HSI为8M,f4为12M)作为系统时钟。所以,有必要在唤醒以后,在程序上重新配置系统时钟,将时钟切换回HSE。
唤醒延迟 :基础延迟为 HSI振荡器的启动时间,若调压器工作在低功耗模式,还需要加上调压器从低功耗切换至正常模式下的时间,若 FLASH 工作在掉电模式,还需要加上 FLASH 从掉电模式唤醒的时间。

进入/退出停止模式

在停止模式下,通过设置电源控制寄存器(PWR_CR)的LPDS位使内部调节器进入低功耗模式,能够降低更多的功耗
如果正在进行闪存编程,直到对内存访问完成,系统才进入停止模式
如果正在进行对APB的访问,直到对APB访问完成,系统才进入停止模式。
在停止模式下,如果在进入该模式前ADC和DAC没有被关闭,那么这些外设仍然消耗电流。通过设置寄存器ADC_CR2的ADON位和寄存器DAC_CR的ENx位为0可关闭这2个外设。

进入停止模式前,记得把系统滴答定时器关闭。
在这里插入图片描述
执行WFE进入的唤醒事件如下:
在这里插入图片描述

从停止模式中唤醒后,需要重新配置时钟。对片外外设寄存器没有影响。

停止模式-外部中断唤醒-电压调节器为低功耗模式demo

采用STM32F103C8T6单片机,KeilMDK5.32版本

开启外部中断线1 并连接PA1,下降沿触发,上拉输入;在NVIC中使能外部中断1,设置优先级。
WFI指令进入停止模式状态。

STM32CubeMX配置
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
主要代码

  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
	HAL_Delay(1000);//延时1000毫秒
	/* 采用位带操作实现LED翻转 */
	PCout(13) = !PCin(13);
	if(times > 4)
	{
		//HAL_SuspendTick();//停止系统滴答计时器
		CLEAR_BIT(SysTick->CTRL, SysTick_CTRL_ENABLE_Msk);//失能系统滴答定时器
		HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);//电压调节器为低功耗模式,WFI指令进入停止模式
		SystemClock_Config();//重新配置系统时钟
		times = 0;
		SET_BIT(SysTick->CTRL, SysTick_CTRL_ENABLE_Msk);//使能系统滴答定时器
		//HAL_ResumeTick();//恢复系统滴答计时器
	}
	times++;//循环次数加一
  }

工程文件下载链接

停止模式-外部事件唤醒-电压调节器为低功耗模式demo

采用STM32F103C8T6单片机,KeilMDK5.32版本

开启外部事件线1 并连接PA1,下降沿触发,上拉输入;未在NVIC中使能外部中断1,设置优先级
WFE指令进入停止模式状态。

STM32CubeMX配置
在这里插入图片描述
在这里插入图片描述

主要代码

  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
	HAL_Delay(1000);//延时1000毫秒
	/* 采用位带操作实现LED翻转 */
	PCout(13) = !PCin(13);
	if(times > 4)
	{
		HAL_SuspendTick();//停止系统滴答计时器
		//CLEAR_BIT(SysTick->CTRL, SysTick_CTRL_ENABLE_Msk);//失能系统滴答定时器
		HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFE);//电压调节器为低功耗模式,WFE指令进入停止模式
		SystemClock_Config();//重新配置系统时钟
		times = 0;
		//SET_BIT(SysTick->CTRL, SysTick_CTRL_ENABLE_Msk);//使能系统滴答定时器
		HAL_ResumeTick();//恢复系统滴答计时器
	}
	times++;//循环次数加一
  }

工程文件下载链接

待机模式

待机模式可实现系统的最低功耗。该模式是在Cortex-M3深睡眠模式时关闭电压调节器。整个1.8V供电区域被断电。PLL、HSI和HSE振荡器也被断电SRAM和寄存器内容丢失。只有备份的寄存器和待机电路维持供电。也就是说,从待机模式唤醒后,由于没有之前代码的运行记录,只能对芯片复位,重新检测 boot条件,从头开始执行程序。

从待机唤醒后,除了电源控制/状态寄存器(PWR_CSR),所有寄存器被复位

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

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

进入/退出待机模式

在这里插入图片描述

待机模式-WKUP唤醒demo

采用STM32F103C8T6单片机,KeilMDK5.32版本

PA0用于唤醒单片机,下拉输入,上升沿触发。

STM32CubeMX配置
设置PA0为WKUP引脚

:经过实验,在STM32CubeMX中配置PA0为WKUP没有起作用,还是得手动配置PA0。

在这里插入图片描述
通过置位电源控制/状态寄存器(PWR_CSR) 的第8位来设置PA0为WKUP
HAL库代码如下

HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN1);//强制使能 WKUP(PA0)引脚

在这里插入图片描述

查询最新英文官方文档(2021-02-23)链接
在这里插入图片描述

主要代码

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */
	uint8_t times = 0;//循环次数
  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  /* USER CODE BEGIN 2 */
	HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN1);//强制使能WKUP(PA0)引脚
	SET_BIT(PWR->CR, PWR_CR_CWUF_Msk);//写1清除该位 唤醒位
	SET_BIT(PWR->CR, PWR_CR_CSBF_Msk);//写1清除该位 待机位
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
	HAL_Delay(1000);//延时1000毫秒
	/* 采用位带操作实现LED翻转 */
	PCout(13) = !PCin(13);
	if(times > 4)
	{
		SET_BIT(PWR->CR, PWR_CR_CWUF_Msk);//写1清除该位 唤醒位 如果不清楚此位 系统将保持唤醒状态
		HAL_PWR_EnterSTANDBYMode();//进入待机模式
		/* 待机模式唤醒后 等同于单片机复位 */
	}
	times++;//循环次数加一
  }
  /* USER CODE END 3 */
}

其中待机位和唤醒位需要清除。唤醒位不清除系统将保持在唤醒状态,即使PA0处于未触发状态。
通过电源控制寄存器(PWR_CR)的第2第3位写1清除。
在这里插入图片描述

在这里插入图片描述
HAL库清除待机位,唤醒位

SET_BIT(PWR->CR, PWR_CR_CWUF_Msk);//写1清除该位 唤醒位
SET_BIT(PWR->CR, PWR_CR_CSBF_Msk);//写1清除该位 待机位

工程文件下载链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值