#include "RTC_Alarm.h"
////RTC闹钟初始化:启动时钟、配置LSI做RTC时钟、设置预分频31999得到1Hz
////设置运行时间WORK_TIMES
//RTC中断配置
static void RTC_NVIC_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
/* Enable the RTC Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn; //配置外部中断源(秒中断)
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 7;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* Enable the RTC Alarm Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = RTCAlarm_IRQn; //配置外部中断源(闹钟中断)
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
//闹钟中断接到第17线外部中断
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);
}
void Clock_init(void)
{
if(BKP_ReadBackupRegister(BKP_DR1) != 0xA5A5) //判断保存在备份寄存器的RTC标志是否已经被配置过
{
RTC_Alarm_Configuration();
// Time_Adjust(); //设置RTC 时钟参数
BKP_WriteBackupRegister(BKP_DR1, 0xA5A5); //RTC设置后,将已配置标志写入备份数据寄存器
}
else
{
// if(RCC_GetFlagStatus(RCC_FLAG_PORRST) != RESET) //检查是否掉电重启
// {
// }
// else if(RCC_GetFlagStatus(RCC_FLAG_PINRST) != RESET) //检查是否reset复位
// {
// }
/***新加的,测试,待机唤醒后,程序不经过上面的if部分,所以没有这三步(两个语句),所以程序会卡,所以加上,果然***/
// RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
// /* 允许访问BKP区域 */
// PWR_BackupAccessCmd(ENABLE);
RTC_Alarm_Configuration();
// RTC_WaitForSynchro(); //等待RTC寄存器被同步
// RTC_ITConfig(RTC_IT_SEC, ENABLE); //使能秒中断
// RTC_WaitForLastTask();
// RTC_ITConfig(RTC_IT_ALR, ENABLE); //naozhong
// RTC_WaitForLastTask(); //等待写入完成
}
RCC_ClearFlag(); //清除复位标志
}
//RTC闹钟初始化:启动时钟、配置LSI做RTC时钟、设置预分频40000得到1Hz
//设置运行时间WORK_TIMES
void RTC_Alarm_Configuration(void)
{
/* 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();
/* RTC clock source configuration ----------------------------------------*/
/* Enable the LSI OSC */
RCC_LSICmd(ENABLE);
/* Wait till LSI is ready */
while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET)
{
}
/* Select the RTC Clock Source */
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
/* Enable the RTC Clock */
RCC_RTCCLKCmd(ENABLE);
/* Wait for RTC registers synchronization */
RTC_WaitForSynchro();
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
/* 使能RTC闹钟中断*/
RTC_ITConfig(RTC_IT_ALR, ENABLE);
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
/* Set RTC prescaler: set RTC period to 1sec */
RTC_SetPrescaler(40000);
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
//中断配置
RTC_NVIC_Config();
//设置运行WORK_TIMES
RTC_SetAlarm(RTC_GetCounter() + WORK_TIMES);
RTC_WaitForLastTask();
}
void RTCAlarm_IRQHandler(void)
{
RTC_WaitForSynchro();
if(RTC_GetITStatus(RTC_IT_ALR) != RESET)
{
EXTI_ClearITPendingBit(EXTI_Line17);
RTC_WaitForLastTask();
if(PWR_GetFlagStatus(PWR_FLAG_WU) != RESET)
{
// 清除唤醒标志
PWR_ClearFlag(PWR_FLAG_WU);
RTC_WaitForLastTask();
}
RTC_ClearITPendingBit(RTC_IT_ALR);
RTC_WaitForLastTask();
RTC_Enter_StandbyMode(STANDBY_TIMES);//1秒后唤醒
}
}
//设置闹钟时长并进入待机
//s为中断秒数
void RTC_Enter_StandbyMode(u32 s)
{
RTC_SetAlarm(RTC_GetCounter() + s);
// 进入待机模式, 此时所有1.8V域的时钟都关闭,HIS和HSE的振荡器关闭, 电压调节器关闭.
// 只有WKUP引脚上升沿,RTC警告事件,NRST引脚的外部复位,IWDG复位.
/* Request to enter STANDBY mode (Wake Up flag is cleared in PWR_EnterSTANDBYMode function) */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC|RCC_APB2Periph_ADC1,DISABLE);
RCC->APB2RSTR|=0X01FC;
// RCC_APB2PeriphResetCmd(0X01FC,DISABLE); //复位所有IO口,屏蔽这条语句
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
PWR_WakeUpPinCmd(ENABLE); //使能唤醒管脚功能
RTC_WaitForLastTask();
PWR_EnterSTANDBYMode();//进入待机模式
}
程序较长。你可以把其中的一部分注释掉, 只留下核心代码,然后看一下问题出现在哪里。
您好,我是有问必答小助手,你的问题已经有小伙伴为您解答了问题,您看下是否解决了您的问题,可以追评进行沟通哦~
如果有您比较满意的答案 / 帮您提供解决思路的答案,可以点击【采纳】按钮,给回答的小伙伴一些鼓励哦~~
ps:问答VIP仅需29元,即可享受5次/月 有问必答服务,了解详情>>> https://vip.csdn.net/askvip?utm_source=1146287632