STM32F103低功耗实验

实验目的

本章学习STM32的低功耗控制,掌握如何进入低功耗状态以及如何从此状态唤醒,数据手册请参看第四章电源控制PWR中的内容

实验简介

现在很多MCU都有低功耗控制,当需要系统省电时,就需要进入适当的低功耗模式来降低系统的功耗,尤其当MCU用在电池供电的设备上时,低功耗尤为重要,下面我们介绍STM32的3种低功耗以及唤醒条件。

睡眠模式:进入睡眠模式时,内核时钟停止,从睡眠模式中恢复不需要任何特殊的序列,但要重新使能ARM内核的时钟。在睡眠模式下,指令的执行被中止直至复位或中断出现。外设在CPU内核处于睡眠模式期间继续运行,并可产生中断使处理器恢复执行指令。睡眠模式下,处理器内核自身,存储器系统,有关控制器及内部总线停止工作,因此这些器件的动态功耗会降低,只要出现任何使能的中断,CPU内核就会从睡眠模式中唤醒。
STM32F103低功耗实验_第1张图片
停止模式:在停止模式下电压调节器可运行在正常或低功耗模式。此时在1.8V供电区域的所有时钟都被停止,PLL,HSI,和 HSE RC振荡器的功能被禁止,SRAM和寄存器内容被保留下来。在停止模式下,所有I/O引脚都保持他们在运行模式时的状态。
停止模式进入和退出
STM32F103低功耗实验_第2张图片
待机模式:待机模式可实现系统的最低功耗。该模式是在Cortex-M3深睡眠模式时关闭电压调节器。整个1.8V供电区域被断开。PLL ,HSI 和 HSE 振荡器也被断电。SRAM和寄存器内容丢失。只有备份的寄存器和待机电路维持供电。

待机模式的进入和退出
STM32F103低功耗实验_第3张图片
这三种模式最低功耗的是待机模式,其只需要2uA左右的电流,停机模式是次低功耗的,其典型的电流消耗在20uA左右。最后就是睡眠模式了。STM32F103低功耗实验_第4张图片

代码

待机模式
main.c

#include "MyIncludes.h"

u16 sys_cnt = 0;
void systick_isr(void)
{
   if(sys_cnt <100)
   sys_cnt++;
   else
   {
     sys_cnt = 0;
     HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_4|GPIO_PIN_5);
   }
}

void Key_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct;
 
  __GPIOC_CLK_ENABLE();
  //使能c时钟
 
 GPIO_InitStruct.Pin = GPIO_PIN_1 | GPIO_PIN_3 ;
 GPIO_InitStruct.Mode = GPIO_MODE_INPUT;//输入
 GPIO_InitStruct.Pull = GPIO_NOPULL;//上拉
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;//高速
 HAL_GPIO_Init(GPIOC,&GPIO_InitStruct);
}

int main(void)
{
  System_Init();
  
  LED_Init();
 
  HAL_GPIO_WritePin(GPIOC,GPIO_PIN_4|GPIO_PIN_5,GPIO_PIN_RESET);
  delay_ms(2000);
  HAL_GPIO_WritePin(GPIOC,GPIO_PIN_4|GPIO_PIN_5,GPIO_PIN_SET);
  delay_ms(1000);
  
  SysTick_Init(systick_isr);

  Key_Init();
  
  LowPWR_Init();
  //低功耗初始化

  while(1)
  {
    while(HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_3) == GPIO_PIN_RESET )
    {
    
    }
    //等待按键松开
    delay_ms(50);
    if(HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_3) ==GPIO_PIN_RESET )
    {
      printf("Enter StandbyMode\r\n");
      StandbyMode_Enter();
    }
  }
  
}

pwr.h

#ifndef __PWR_H_
#define __PWR_H_

#include "stm32f1xx.h"
#include "stm32_types.h"
#include "stm32f1xx_hal.h"

void LowPWR_Init(void);
//低功耗初始化
void StandbyMode_Enter(void);
//系统进入待机模式
//STM32F1的PA0可用作唤醒引脚WKUO
void StopMode_Enter(void);
//系统进入停止模式
void StopMode_Exit(void);
//系统退出停止模式
void SleepMode_Exit(void);
//退出休眠模式
#endif

pwr.c

#include "pwr.h"

PWR_PVDTypeDef sConfigPVD;

void LowPWR_Init(void)
//低功耗初始化
{
 __HAL_RCC_PWR_CLK_ENABLE();
 //使能PWR时钟
}

void StandbyMode_Enter(void)
//系统进入待机模式
//STM32F1的PA0可用作唤醒引脚WKUP,上升沿唤醒
//待机唤醒等同于复位操作
{
  if( __HAL_PWR_GET_FLAG(PWR_FLAG_SB) != RESET )
  //检查并处理系统是否从待机模式恢复
  {
    __HAL_PWR_CLEAR_FLAG(PWR_FLAG_SB);
    //清除标志
  }
 
  HAL_PWR_DisableWakeUpPin(PWR_WAKEUP_PIN1);
  //禁止PA0作为唤醒引脚
  
  __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
  //清除唤醒标志

  HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN1);
  //使能PA0作为唤醒引脚,PA0的上升沿唤醒

  HAL_SuspendTick();
  //禁止SysTick中断,防止唤醒系统
  
  HAL_PWR_EnterSTANDBYMode();
  //进入待机模式
}

void StopMode_Enter(void)
//系统进入停止模式
{
   HAL_SuspendTick();
   //禁止SysTick中断
   HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON,PWR_STOPENTRY_WFI);
   //进入停止模式,低功耗调压器开启
}

void StopMode_Exit(void)
//退出停止模式
{
  __HAL_RCC_HSE_CONFIG(RCC_HSE_ON);
  //使能HSE
  while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET);
  //等待HSE准备就绪
  __HAL_RCC_PLL_ENABLE();
  //使能PLL
  while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET)
  //等待PLL准备就绪
  {
  }
  __HAL_RCC_SYSCLK_CONFIG(RCC_SYSCLKSOURCE_PLLCLK);
  // 选择PLL作为系统时钟源
 
  while(__HAL_RCC_GET_SYSCLK_SOURCE() != 0x08)
  //等待PLL被选择为系统时钟源
  {
  }
}

void SleepMode_Enter(void)
//系统进入睡眠模式
{
  HAL_SuspendTick();
  //禁止SysTICK中断,防止唤醒系统
  HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON,PWR_SLEEPENTRY_WFI);
  //进入睡眠模式
}

void SleepMode_Exit(void)
//退出休眠模式
{
  HAL_ResumeTick();
  //唤醒SYSTICK
  //初始化外设
}

void PVD_IRQHandler(void)
//中断服务函数
{
  HAL_PWR_PVD_IRQHandler();
}

void HAL_PWR_PVDCallback(void)
//中断回调函数
{

}

你可能感兴趣的:(星光STM32)