×
单片机 > 单片机程序设计 > 详情

stm32的待机模式解析

发布时间:2020-07-08 发布时间:
|

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的唤醒了。



『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
基于AT91M42800A的LED显示系统设计