我通过设置RTC时钟定时每一分钟唤醒MCU一次进行一些查询检测工作。但会偶尔发现无法唤醒MCU,感觉RTC无法产生中断,应该是RTC的问题,现在就是不知道是硬件引起的还是软件引起的。因为有的机子从来没有问题,有的偶尔会有,但不是每次都出现,有的用了很久也没有出现过。很困扰。以下是RTC的处理代码,有哪位大侠搞过RTC闹钟唤醒睡眠的,帮看看有没有问题。 /****************************************************************************** **函数名: Init_RTC **入 口: **返 回: **功 能: RTC配置初始化 *******************************************************************************/ void Init_RTC(void) { RTC_Config(); GetRTCTime(); Set_RTC_Alarm_Minute(); //设置闹钟时间 } /****************************************************************************** **函数名:RTC_Config **入 口: **返 回: **功 能: RTC配置,24小时的时间格式 *******************************************************************************/ void RTC_Config(void) { RTC_InitTypeDef RTC_InitStructure; RCC_APB1PeriphClockCmd( RCC_APB1Periph_PWR, ENABLE ); /* Enable the PWR clock */ PWR_BackupAccessCmd( ENABLE ); /* Allow access to RTC */ if( RTC_ReadBackupRegister( RTC_BKP_DR0 ) != RTC_BKP_VALUE )//如果掉电了,则重新初始化时间 { RCC_LSEConfig( RCC_LSE_ON); /* Enable the LSE OSC */ while( RCC_GetFlagStatus( RCC_FLAG_LSERDY ) == RESET ); /* Wait till LSE is ready */ RCC_RTCCLKConfig( RCC_RTCCLKSource_LSE ); /* Select the RTC Clock Source */ RCC_RTCCLKCmd( ENABLE ); /* Enable the RTC Clock */ RTC_WaitForSynchro(); /* Wait for RTC APB registers synchronisation */ //设置RTC时钟分频,1秒 RTC_InitStructure.RTC_AsynchPrediv = 127; RTC_InitStructure.RTC_SynchPrediv = 255;//255 RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24; //24小时的时间格式 if( RTC_Init( &RTC_InitStructure ) == ERROR ) { /* 此处作设置失败处理 */ } //设置默认的时间:2017-1-1- 12:30:00 SetCalendarTime( DEFAULT_HOUR, DEFAULT_MIN, DEFAULT_SEC); //时间 SetCalendarDate(3,DEFAULT_YEAR,DEFAULT_MON,DEFAULT_DAY); //日期 bPowerDown = TRUE;//系统掉电,又重新上电 bSynchronizeTime = TRUE; } else { RTC_WaitForSynchro(); /* Wait for RTC APB registers synchronisation */ RTC_ClearFlag( RTC_FLAG_ALRAF ); /* Clear the RTC Alarm Flag */ } } /****************************************************************************** **函数名:Set_RTC_Alarm_Minute **入 口: **返 回: **功 能: 设置RTC报警时间,单位为分钟 *******************************************************************************/ void Set_RTC_Alarm_Minute(void) { RTC_AlarmTypeDef RTC_AlarmStructure; unsigned char hour = 0; unsigned char min = 0; // unsigned char sec = 0; //GetRTCTime(); //获取系统时间 hour = RTC_Time[3]; min = RTC_Time[4]; min += 1; if(min >= 60) { min = 0; hour += 1; if(hour >= 24) hour = 0; } RTC_ITConfig( RTC_IT_ALRA, DISABLE ); /* Enable the RTC Alarm A Interrupt */ RTC_AlarmCmd( RTC_Alarm_A, DISABLE ); /* Disable the Alarm A */ RTC_AlarmStructure.RTC_AlarmTime.RTC_H12 = RTC_H12_AM; RTC_AlarmStructure.RTC_AlarmTime.RTC_Hours = hour; RTC_AlarmStructure.RTC_AlarmTime.RTC_Minutes = min; RTC_AlarmStructure.RTC_AlarmTime.RTC_Seconds = 0; /* Set the Alarm A */ RTC_AlarmStructure.RTC_AlarmDateWeekDay = 31; RTC_AlarmStructure.RTC_AlarmDateWeekDaySel = RTC_AlarmDateWeekDaySel_Date; RTC_AlarmStructure.RTC_AlarmMask = RTC_AlarmMask_DateWeekDay; RTC_SetAlarm( RTC_Format_BIN, RTC_Alarm_A, &RTC_AlarmStructure ); /* Configure the RTC Alarm A register */ RTC_ITConfig( RTC_IT_ALRA, ENABLE ); /* Enable the RTC Alarm A Interrupt */ RTC_AlarmCmd( RTC_Alarm_A, ENABLE ); /* Enable the alarm A */ } /****************************************************************************** **函数名:GetRTCTime **入 口: **返 回: **功 能: 读取RTC时间 *******************************************************************************/ void GetRTCTime(void) { unsigned char Getweek = 0; GetCalendarTime(&RTC_Time[3],&RTC_Time[4],&RTC_Time[5]); GetCalendarDate(&Getweek,&RTC_Time[0],&RTC_Time[1],&RTC_Time[2]); } /****************************************************************************** **函数名:RTC_IRQHandler **入 口: **返 回: **功 能: 日历报警中断 *******************************************************************************/ void RTC_IRQHandler( void ) { if( RTC_GetITStatus( RTC_IT_ALRA ) != RESET ) { if((gStatus != G_POWER_OFF)&&(gStatus != G_MODE_CHARGE)) { GprsConnectInTime++; } else { GprsConnectInTime = 0; } bOneMinuteFlg = TRUE;//一分钟时间到 bBatTest1Min = TRUE; //一分钟测量一次电量 RTC_ClearITPendingBit( RTC_IT_ALRA ); } EXTI_ClearITPendingBit(EXTI_Line17); } } } } /****************************************************************************** **函 数 名: **入 口: **返 回: **功 能: *******************************************************************************/ void NVIC_Configuration(void) { NVIC_InitTypeDef NVIC_InitStructure; EXTI_InitTypeDef EXTI_InitStructure; //RTC时钟中断 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); NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn; NVIC_InitStructure.NVIC_IRQChannelPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); RTC_ClearITPendingBit( RTC_IT_ALRA ); EXTI_ClearITPendingBit(EXTI_Line17); } /****************************************************************************** **函数名:main **入 口: **返 回: **功 能: 系统主程序 *******************************************************************************/ int main(void) { ............. Init_RTC(); //日历时间初始化 ................ NVIC_Configuration(); //系统中断配置初始化 while(1) { //每分钟检测一次 if(bOneMinuteFlg == TRUE) { bOneMinuteFlg = FALSE; GetRTCTime(); //获取系统时间 Set_RTC_Alarm_Minute(); //设置闹钟中断时间 } .......................... SleepMode(); ............................ } |
另外,如果是一分钟唤醒一次,不如使用RTC WakeUp,这个简单方便。
RTC_AlarmStructure.RTC_AlarmMask = RTC_AlarmMask_Seconds | RTC_AlarmMask_DateWeekDay;
hour = RTC_Time[3];
min = RTC_Time[4];
min += 1;
if(min >= 60)
{
min = 0;
hour += 1;
if(hour >= 24) hour = 0;
}
RTC_ITConfig( RTC_IT_ALRA, DISABLE ); /* Enable the RTC Alarm A Interrupt */
RTC_AlarmCmd( RTC_Alarm_A, DISABLE ); /* Disable the Alarm A */
RTC_AlarmStructure.RTC_AlarmTime.RTC_H12 = RTC_H12_AM;
RTC_AlarmStructure.RTC_AlarmTime.RTC_Hours = hour;
RTC_AlarmStructure.RTC_AlarmTime.RTC_Minutes = min;
RTC_AlarmStructure.RTC_AlarmTime.RTC_Seconds = 0;
你说的这个我也会试试。不过以上我是根据每次当前时间设置下一次闹钟时间的,就是下一次分钟闹钟,我觉得这个也没有什么问题。