[STM32] Standby wake-up program example

00. Table of Contents

01. Introduction to Standby Mode

Many microcontrollers have low power consumption modes, and STM32F4 is no exception. After the system or power is reset, the microcontroller is in operation. The HCLK in the running state provides the clock for the CPU, and the core executes the program code. When the CPU does not need to continue to run, multiple low-power modes can be used to save power, such as when waiting for an external event. The user needs to select an optimal low power consumption mode based on the lowest power consumption, fastest startup time, and available wake-up sources. The three low-power modes of STM32F4 are briefly introduced in section 5.2.4, here we will review them again.
STM32F4 provides three low-power modes to achieve different levels of power reduction purposes. The three modes are as follows:
1) Sleep mode (CM4 core stops working, peripherals are still running);
2) Stop mode (all All clocks are stopped);
3) Standby mode;

02. Hardware Module

The hardware resources used are:
1) Indicator DS0
2) KEY_UP button
3) TFTLCD module

03. Related functions

stm32f4xx_pwr.c / stm32f4xx_pwr.h

void PWR_EnterSTOPMode();//进入停机模式
void PWR_EnterSTANDBYMode(void);//进入待机模式
void PWR_WakeUpPinCmd(FunctionalState NewState);//使能Wakeup引脚唤醒
FlagStatus PWR_GetFlagStatus(uint32_t PWR_FLAG);
void PWR_ClearFlag(uint32_t PWR_FLAG);

core_cm4.h

__WFI();
__WFE();

04. Program Example One

Press KEY0 to enter standby mode KEY_UP wake up

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "beep.h"
#include "key.h"
#include "usmart.h"
#include "lcd.h"
#include "rtc.h"
#include "rng.h"
#include "key.h"


int main(void)
{
    
     


	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
	
	delay_init(168);
	
	uart_init(115200);
	
	usmart_dev.init(84);

	
	LED_Init();
	
	KEY_Init();
	
	LCD_Init();
	
		
	POINT_COLOR = RED;
	
	LCD_ShowString(30,50,200,16,16,"Explorer STM32F4");	
	LCD_ShowString(30,70,200,16,16,"PWR TEST");	
	LCD_ShowString(30,90,200,16,16,"ATOM@tom");
	LCD_ShowString(30,110,200,16,16,"2020/09/10");	 
	

	while(1)
	{
    
    
		if (Key_Scan() == KEY0_PRESS)
		{
    
    
			//使能PWR时钟
			RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); 
			
			//后备区域访问使能
			PWR_BackupAccessCmd(ENABLE);
			
			//关闭RTC相关中断
			RTC_ITConfig(RTC_IT_TS|RTC_IT_WUT|RTC_IT_ALRB|RTC_IT_ALRA,DISABLE);
			//清除RTC相关中断标志
			RTC_ClearITPendingBit(RTC_IT_TS|RTC_IT_WUT|RTC_IT_ALRB|RTC_IT_ALRA);
			
			//清除wake-up标志
			PWR_ClearFlag(PWR_FLAG_WU);
			
			//使能唤醒管脚功能
			PWR_WakeUpPinCmd(ENABLE);
			
			//进入待机模式
			PWR_EnterSTANDBYMode();
		
		}
	
		delay_ms(10);
	}
}

05. Program example two

wkup.h

#ifndef __WK_UP_H__
#define __WK_UP_H__

#include "sys.h"

#define WKUP_KD PAin(0)


//检测WKUP脚的信号
u8 Check_WKUP(void);

//WKUP唤醒初始化
void WKUP_Init(void);

//系统进入待机模式
void Sys_Enter_Standby(void);


#endif/*__WK_UP_H__*/


wkup.c

#include "wkup.h"

#include "led.h"
#include "delay.h"

//检测WKUP脚的信号
u8 Check_WKUP(void)
{
    
    
	u8 t = 0;
	
	//记录松开的次数
	u8 tx = 0;
	LED1 = 0;
	
	while(1)
	{
    
    
		if (WKUP_KD)
		{
    
    
			t++;
			tx = 0;
		}
		else
		{
    
    
			tx++;
			//查过90ms没有WKUP信号
			if (tx > 3)
			{
    
    
				LED1 = 1;
				return 0;
			}
		}
	
		delay_ms(30);
		
		if (t >= 100)
		{
    
    
			LED1 = 0;
			return 1;
		}
	}	
}

//WKUP唤醒初始化
void WKUP_Init(void)
{
    
    

	GPIO_InitTypeDef  GPIO_InitStructure;
	NVIC_InitTypeDef   NVIC_InitStructure;
	EXTI_InitTypeDef   EXTI_InitStructure;
	
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//使能GPIOA时钟 
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);//使能SYSCFG时钟
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //PA0
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//输入模式
	GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; 
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; 
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;//下拉
	GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化	

	//(检查是否是正常开)机    		 
	if(Check_WKUP()==0)
	{
    
    
		Sys_Enter_Standby();	//不是开机,进入待机模式  
	}
	SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);//PA0 连接到中断线0
	

	EXTI_InitStructure.EXTI_Line = EXTI_Line0;//LINE0
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//中断事件
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; //上升沿触发 
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;//使能LINE0
	EXTI_Init(&EXTI_InitStructure);//配置
		
	
	NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;//外部中断0
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;//抢占优先级2
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;//子优先级2
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能外部中断通道
	NVIC_Init(&NVIC_InitStructure);//配置NVIC
}

//系统进入待机模式
void Sys_Enter_Standby(void)
{
    
    
	//等待按键松开
	while(WKUP_KD)
		;
	
	//复位所有的IO口
	RCC_AHB1PeriphResetCmd(0x04FF, ENABLE);
	
	//使能PWR时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); 
	
	//后备区域访问使能
	PWR_BackupAccessCmd(ENABLE);
	
	//关闭RTC相关中断
	RTC_ITConfig(RTC_IT_TS|RTC_IT_WUT|RTC_IT_ALRB|RTC_IT_ALRA,DISABLE);
	//清除RTC相关中断标志
	RTC_ClearITPendingBit(RTC_IT_TS|RTC_IT_WUT|RTC_IT_ALRB|RTC_IT_ALRA);
	
	//清除wake-up标志
	PWR_ClearFlag(PWR_FLAG_WU);
	
	//使能唤醒管脚功能
	PWR_WakeUpPinCmd(ENABLE);
	
	//进入待机模式
	PWR_EnterSTANDBYMode();
}

//中断,检测到PA0脚的一个上升沿.	  
//中断线0线上的中断检测
void EXTI0_IRQHandler(void)
{
    
     		    		    				     		    
	EXTI_ClearITPendingBit(EXTI_Line0); // 清除LINE10上的中断标志位
	if(Check_WKUP())//关机?
	{
    
    		  
		Sys_Enter_Standby(); //进入待机模式 
	}
} 

main.c

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "beep.h"
#include "key.h"
#include "usmart.h"
#include "lcd.h"
#include "rtc.h"
#include "rng.h"
#include "key.h"
#include "wkup.h"


int main(void)
{
    
     


	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
	
	delay_init(168);
	
	uart_init(115200);
	
	usmart_dev.init(84);

	
	LED_Init();
	
	KEY_Init();
	
	LCD_Init();
	
	WKUP_Init();
	
		
	POINT_COLOR = RED;
	
	LCD_ShowString(30,50,200,16,16,"Explorer STM32F4");	
	LCD_ShowString(30,70,200,16,16,"PWR TEST");	
	LCD_ShowString(30,90,200,16,16,"ATOM@tom");
	LCD_ShowString(30,110,200,16,16,"2020/09/10");	 

	while(1)
	{
    
    
		LED2 = !LED2;
		
		delay_ms(250);
	}
}

06. Appendix

6.1 [STM32] STM32 series tutorial summary

Website: [STM32] STM32 series tutorial summary

07. Statement

This tutorial refers to the "STM32 F4 Development Guide" of Punctual Atom

Guess you like

Origin blog.csdn.net/dengjin20104042056/article/details/108517208