关于STM32xE系列芯片STOP模式下使用RTC唤醒所遇到的问题记录
问题描述:在执行STOP模式下,无法通过时钟唤醒,只可以通过外部中断唤醒
解决方案:
将PWR_EnterSTOPMode(PWR_Regulator_LowPower,PWR_STOPEntry_WFI);
更改为PWR_EnterSTOPMode(PWR_Regulator_ON,PWR_STOPEntry_WFI);
如果使用PWR_Regulator_LowPower会将大部分的寄存器关断,最终导致的结果是程序不运行。
整体代码如下:
//对PE15设置为外部中断#wxf
void STOP_init()
{
//设置PE15作为中断唤醒引脚#wxf
GPIO_InitTypeDef GPIO_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOE|RCC_APB2Periph_AFIO, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
//GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO¿ÚËÙ¶ÈΪ50MHz#wxf
GPIO_Init(GPIOE, &GPIO_InitStructure);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource15);
//增加外部中断
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
EXTI_ClearITPendingBit(EXTI_Line15);
EXTI_InitStructure.EXTI_Line = EXTI_Line15;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
EXTI_Init(&EXTI_InitStructure);
EXTI_GenerateSWInterrupt(EXTI_Line15);
//设置中断等级#wxf
//NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);#wxf
NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
u8 RTC_Init()
{
//u8 temp = 0;
NVIC_InitTypeDef NVIC_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
//增加对时钟唤醒的支持
RCC_LSICmd(ENABLE);
while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY)==RESET)
{
}
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR|RCC_APB1Periph_BKP,ENABLE);
PWR_BackupAccessCmd(ENABLE); //允许背部区域写
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
RCC_RTCCLKCmd(ENABLE);
RTC_WaitForLastTask();
RTC_WaitForSynchro();
RTC_WaitForLastTask();
RTC_ITConfig(RTC_IT_ALR,ENABLE);
RTC_WaitForLastTask();
RTC_EnterConfigMode();进入RTC配置模式
RTC_SetPrescaler(39999);
RTC_WaitForLastTask();
RTC_SetCounter(0); //初始设定为0秒
RTC_WaitForLastTask();
RTC_SetAlarm(60); //闹钟值设置为40s
RTC_WaitForLastTask(); //等待上述配置完成
RTC_ExitConfigMode(); //推出配置模式
//BKP_WriteBackupRegister(BKP_DR1,0xC0B4);
//PWR_BackupAccessCmd(DISABLE); //²»ÔÊÐí±³²¿ÇøÓòд²Ù×÷
//NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;
//NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
//NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;#wxf
//NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
//NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = RTCAlarm_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
EXTI_ClearITPendingBit(EXTI_Line17);
EXTI_InitStructure.EXTI_Line = EXTI_Line17;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
//RTC_ClearITPendingBit(RTC_IT_SEC);
RTC_ClearITPendingBit(RTC_IT_ALR);
RTC_WaitForLastTask(); //等待上述配置完成
return 0;
}
void RTC_ClockUP()
{
RTC_EnterConfigMode();//进入RTC配置
RTC_WaitForLastTask();
RTC_SetCounter(0); //初始值设定为0s
RTC_WaitForLastTask();
RTC_SetAlarm(60); //闹钟值设定为40秒
RTC_WaitForLastTask(); //等待上述配置完成
RTC_ExitConfigMode(); //退出配置模式
}
实现
STOP_init();
//RTC_ClockUP();
RTC_ClearITPendingBit(RTC_IT_ALR);
RTC_WaitForLastTask(); //等待上述配置完成
EXTI_ClearITPendingBit(EXTI_Line17); //PWR_EnterSTOPMode(PWR_Regulator_LowPower,PWR_STOPEntry_WFI);PWR_Regulator_ON
PWR_EnterSTOPMode(PWR_Regulator_ON,PWR_STOPEntry_WFI);//进入低功耗
SystemInit();//恢复时钟
RTC_Init();//RTC重新开始及时
注:在上电初始化中记得初始化RTC与中断
以上仅供参考