STM32入门学习笔记之低功耗实验

2023-06-25  

13.1 STM32低功耗模式概述

STM32在系统或电源复位后,芯片处于运行状态,此时HCLK为CPU提供时钟,内核执行程序代码,当CPU不需要继续运行时,可以采用低功耗模块来降低芯片的运行电流,STM32有3种低功耗模式:

(1)睡眠模式:内核停止,外设继续运行

(2)待机模式:1.8V的内核电源被关闭,SRAM内容丢失,PLL,HIS,HSE振荡器断电,此模式下最低电流2uA

(3)停机模式:停止所有时钟,此模式下最低电流20uA

上述三种模式的配置与唤醒条件如下表所示。

模式 进入操作 唤醒
睡眠 WFI指令 任一中断
WFE指令 唤醒事件
待机 PDDS位+SLEEPDEEP位+WFI或者WFE WKUP引脚上升沿RTC警告事件NRST端口的复位信号IWDG复位
停机 PDDS和LPDS位+SLEEPDEEP位+WFI或WFE 任一外部中断(需要在外部中断寄存器中设置)


从待机模式唤醒后,除了电源控制/状态寄存器PWR_CSR,所有的寄存器被复位,唤醒后执行的代码等同于复位后的执行,此时电源控制/状态寄存器PWR_CSR将会指示内核由待机状态退出,进入待机模式后,除了复位引脚以及被设置为防侵入或校准输出时的TAMPER引脚和被使能的唤醒引脚,其他IO均进入高阻状态。


13.2 相关寄存器

13.2.1 电源控制寄存器:PWR_CR

15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
- DBP PLS[2:0] PVDE CSBF CWUF PDDS LPDS







Bit 8:取消后备区域的写保护

0:禁止写入RTC和后备寄存器

1:允许写入RTC和后备寄存器

Bit 7~Bit 5:PVD电平选择

000:2.2V

001:2.3V

010:2.4V

011:2.5V

100:2.6V

101:2.7V

110:2.8V

111:2.9V

Bit 4:电源电压监测器PVD使能

0:禁止PVD

1:开启PVD

Bit 3:清除待机位

0:无功效

1:清除SBF待机位

Bit 2:清除唤醒位

0:无功效

1:2个系统时钟周期后清除WUF唤醒位

Bit 1:掉电深睡眠

0:当CPU进入深睡眠时进入停机模式,调压器的状态由LPDS位控制

1:CPU进入深睡眠时进入待机模式

Bit 0:深睡眠下的低功耗

0:在停机模式下电压调压器开启

1:在停机模式下电压调压器处于低功耗模式


13.2.2 电源控制/状态寄存器:PWR_CSR

15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

EWUP
PVD0 SBF WUF









Bit 8:使能WKUP引脚

0:WKUP引脚为通用I/O

1:WKUP引脚用于将CPU从待机模式唤醒,WKUP引脚被设为输入下拉

Bit 2:PVD输出

0:VDD/VDDA高于由PLS[2:0]选定的PVD阀值

1:VDD/VDDA低于由PLS[2:0]选定的PVD阀值

Bit 1:待机标志

0:系统不在待机模式

1:系统进入待机模式

Bit 0:唤醒标志

0:没有发生唤醒事件

1:在WKUP引脚上发生唤醒事件或出现RTC闹钟事件


13.3 实验例程

功能:芯片运行15s之后进入待机模式,然后按下接在WKUP端口的按键唤醒,CPU在唤醒模式下驱动接在PB5上的LED以1Hz频率闪烁。

(1)打开sys.c文件编写一个功能函数,添加以下代码。

/***************************************************

Name    :Standby_Set

Function  :设置待机模式

Parameter  :None

Return    :None

***************************************************/

void Standby_Set()

{

  SCB->SCR |= 1<<2 ;                                          //使能SLEEPDEEP位

    RCC->APB1ENR |= 1<<28 ;                                        //使能电源时钟      

   PWR->CSR |= 1<<8 ;                                          //设置WKUP用于唤醒

  PWR->CR |= 1<<2 ;                                          //清除Wake-up 标志

  PWR->CR |= 1<<1 ;                                          //PDDS置位      

  __asm volatile("wfi");                                        //执行WFI指令

}

(2)打开sys.h文件添加功能函数的声明。


void Standby_Set( void ) ;                                        //设置待机模式

(3)打开1.c输入以下代码。


#include "sys.h"

#include "delay.h"

#include "usart1.h"

/***************************************************

Name    :LED_Init

Function  :LED初始化

Parameter  :None

Return    :None

***************************************************/

#define LED PBout( 5 )                                          //定义LED端口

void LED_Init()

{

  RCC->APB2ENR |= 1<<3 ;

  GPIOB->CRL &= 0xFF0FFFFF ;

  GPIOB->CRL |= 0x00300000 ;

  LED = 1 ;

}

/***************************************************

Name    :TIM1_UP_IRQHandler

Function  :TIM1中断服务函数

Paramater  :None

Return    :None

***************************************************/

u8 TIM1_Count ;

void TIM1_UP_IRQHandler()

{

  if( ( TIM1->SR&0x01 )==0x01 )

  {

    TIM1_Count ++ ;

    if( TIM1_Count==15 )

    {

      Standby_Set() ;                                        //进入待机模式

      TIM1_Count = 0 ;

    }

  }

  TIM1->SR &= ~( 1<<0 ) ;

}

/***************************************************

Name    :TIM1_Init

Function  :定时器1初始化

Parameter  :

      psc:预分频系数

      arr:重装载值

Return    :None

***************************************************/

void TIM1_Init( u16 psc, u16 arr )

{

  RCC->APB2ENR |= 1<<11 ;

  TIM1->DIER |= 1<<0 ;

  TIM1->PSC = psc ;

  TIM1->ARR = arr ;

  TIM1->CR1 |= 1<<0 ;

  NVIC_Init( 3, 2, TIM1_UP_IRQn, 2 ) ;

  TIM1_Count = 0 ;

}

/***************************************************

Name    :main

Function  :主函数

Parameter  :None

Return    :None

***************************************************/

int main()

{

  STM32_Clock_Init( 9 ) ;                                        //STM32时钟初始化

  SysTick_Init( 72 ) ;                                        //SysTick初始化

  USART1_Init( 72, 115200 ) ;                                      //初始化串口1波特率115200

  LED_Init() ;                                            //LED初始化

  TIM1_Init( 7199, 9999 ) ;                                      //定时器1初始化

  while( 1 )

  {

    LED = 0 ;

    delay_ms( 500 ) ;

    LED = 1 ;

    delay_ms( 500 ) ;

  }

}


文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。