stm32的待机模式解析

stm32的待机模式是stm32最省电的模式,几乎所有的内部寄存器都掉电了,只有待机电路和RTC部分等还有电。假如寄存器都掉电的话,那就是和按复位键一样了,程序重新从main函数开始执行。

那么如何进入待机模式:

1.RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);//使能PWR外设时钟

2.PWR_EnterSTANDBYMode();                                                                //进入STANDBY模式 

如何出待机模式:

1.PA0的上升沿

2.闹钟中断的上升沿

3.独立看门狗的复位

4.复位引脚

一般来讲采用1和2来唤醒待机模式下的stm32。

1.模式PA0的配置(并不需要配置中断)

   GPIO_InitTypeDef  GPIO_InitStructure;  		  
	NVIC_InitTypeDef NVIC_InitStructure;
	EXTI_InitTypeDef EXTI_InitStructure;


	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);//使能GPIOA和复用功能时钟
	GPIO_InitStructure.GPIO_Pin =GPIO_Pin_0;	 //PA.0
	GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IPD;//上拉输入
	GPIO_Init(GPIOA, &GPIO_InitStructure);	//初始化IO
在进入待机模式之前要配置PA0唤醒的功能

        RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);	//使能PWR外设时钟
	PWR_WakeUpPinCmd(ENABLE);  //使能唤醒管脚功能
	PWR_EnterSTANDBYMode();	  //进入待命(STANDBY)模式	 

2.RTC的闹钟唤醒

首先要配置RTC,使能闹钟中断。

NVIC_InitTypeDef NVIC_InitStructure;
	 /* Enable PWR and BKP clocks */
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
	
	/* Allow access to BKP Domain */
	PWR_BackupAccessCmd(ENABLE);
	
	/* Reset Backup Domain */
	BKP_DeInit();
	
	/* Enable LSE */
	RCC_LSEConfig(RCC_LSE_ON);
	/* Wait till LSE is ready */
	while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
	{}
	
	/* Select LSE as RTC Clock Source */
	RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
	
	/* Enable RTC Clock */
	RCC_RTCCLKCmd(ENABLE);
	
	/* Wait for RTC registers synchronization */
	RTC_WaitForSynchro();
	
	/* Wait until last write operation on RTC registers has finished */
	RTC_WaitForLastTask();
	
	/* Enable the RTC Second */
	RTC_ITConfig(RTC_IT_SEC, ENABLE);
	
	/* Wait until last write operation on RTC registers has finished */
	RTC_WaitForLastTask();
	
	/* Set RTC prescaler: set RTC period to 1sec */
	RTC_SetPrescaler(32767); /* RTC period = RTCCLK/RTC_PR = (32.768 KHz)/(32767+1) */
	
	/* Wait until last write operation on RTC registers has finished */
	RTC_WaitForLastTask();


	NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;             //TIM2中断
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先占优先级0级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;        //从优先级3级
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;          //IRQ通道被使能
	NVIC_Init(&NVIC_InitStructure);                          //初始化NVIC寄存器
我的做法是将RTC的CNT值读出然后加上一个多长时间进入闹钟中断的值,写入RTC闹钟的计数器中

temp = RTC_GetCounter();
	temp+=5;
	
	RTC_WaitForSynchro();
	RTC_SetAlarm(temp);
	RTC_WaitForLastTask(); 	
	
	RTC_WaitForSynchro();
	RTC_ITConfig(RTC_IT_ALR | RTC_IT_SEC, ENABLE);
	/* Wait until last write operation on RTC registers has finished */
	RTC_WaitForLastTask(); 	

这里使能了秒中断和ALR中断。中断函数是这样写的

void RTC_IRQHandler()
{
	 u32 temp = 0;
	 static u8 temp1= 5;
	if(RTC_GetITStatus(RTC_IT_ALR) == SET)
	{
		RTC_ClearITPendingBit(RTC_IT_ALR);
		temp = RTC_GetCounter();
		temp+=5;
		RTC_WaitForSynchro();
		RTC_SetAlarm(temp);
		RTC_WaitForLastTask();
		RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);	//使能PWR外设时钟
		PWR_EnterSTANDBYMode();	  //进入STANDBY模式	  	
	}
	else if(RTC_GetITStatus(RTC_IT_SEC) == SET)
	{
		RTC_ClearITPendingBit(RTC_IT_SEC);
		temp1--;
		LCD_ShowString(30,65,200,16,16,"count down:");
		LCD_ShowxNum(120,65,temp1,2,16,0x80);	
	}	



}
发生RTC中断的时候,重新配置ALR等,然后进入待机模式,秒中断则是在LCD上显示倒计时的数字。


3.同时使用PA0和RTC闹钟中断。

PA0的配置是这样的:

void WKUP_Init(void)
{	
    GPIO_InitTypeDef  GPIO_InitStructure;  		  
	NVIC_InitTypeDef NVIC_InitStructure;
	EXTI_InitTypeDef EXTI_InitStructure;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);//使能GPIOA和复用功能时钟
	GPIO_InitStructure.GPIO_Pin =GPIO_Pin_0;	 //PA.0
	GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IPD;//上拉输入
	GPIO_Init(GPIOA, &GPIO_InitStructure);	//初始化IO
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);	//使能PWR外设时钟
	PWR_WakeUpPinCmd(ENABLE);  //使能唤醒管脚功能
此时,stm32就同时支持RTC定时唤醒和PA0的唤醒了。





你可能感兴趣的:(stm32的待机模式解析)