【一】RTC初始化函数,用宏定义设置内部/外部晶振,使用主频晶振8MHz,外部RTC晶振32.768KHz。
/****************************************************************************/
/*Function Name : RTC Config */
/*Author : Paul */
/*Data : 2021-1-20 09:56:59 */
/*Timer : none */
/*Input Parameters : none. */
/*Return type : none */
/*Output Parameters : none */
/****************************************************************************/
#define RTC_CLOCK_SOURCE_LSE // 32.768KHz
//#define RTC_CLOCK_SOURCE_LSI // 40KHz
//#define RTC_CLOCK_SOURCE_HSE // 8MHz/32=250KHz
void RTC_Config(void)
{
RTC_InitTypeDef RTC_InitStructure;
u32 timerOut;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); /* Enable the PWR clock */
PWR_BackupAccessCmd(ENABLE); /* Allow access to RTC */
if(RTC_ReadBackupRegister(RTC_BKP_DR0)!=0xA5A5)
RTC_Set_DateTime(21,RTC_Month_January,RTC_Weekday_Friday,1,9,0,0); // 2021.1.1 09:00:00
#if defined (RTC_CLOCK_SOURCE_LSI)
RCC_LSICmd(ENABLE);
while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET) /* Wait till LSI is ready */
{
}
#elif defined (RTC_CLOCK_SOURCE_LSE)
RCC_LSEConfig(RCC_LSE_ON);
timerOut=0;
while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET) /* Wait till LSI is ready */
{
timerOut++;
if(timerOut>0xf000)
break;
}
#endif
#if defined (RTC_CLOCK_SOURCE_LSI) /* Select the RTC Clock Source */
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
#elif defined (RTC_CLOCK_SOURCE_LSE)
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
#elif defined (RTC_CLOCK_SOURCE_HSE)
RCC_RTCCLKConfig(RCC_RTCCLKSource_HSE_Div32); //直接8Mhz/32=250KHz
#endif
RCC_RTCCLKCmd(ENABLE);/* Enable the RTC Clock */
RTC_WaitForSynchro();/* Wait for RTC APB registers synchronisation */
#if defined (RTC_CLOCK_SOURCE_LSI)
/* Calendar Configuration */
/*RTC_LSI 为40kHz RTC_LSI = SynchPrediv * AsynchPrediv*/
RTC_InitStructure.RTC_AsynchPrediv = 0x01; // 1->40KHz
RTC_InitStructure.RTC_SynchPrediv = 0x4E1F; // 19999->40KHz
RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24;
RTC_Init(&RTC_InitStructure);
#elif defined (RTC_CLOCK_SOURCE_LSE)
/* Calendar Configuration */
/*RTC_LSE 为32.768kHz RTC_LSI = SynchPrediv * AsynchPrediv*/
RTC_InitStructure.RTC_AsynchPrediv = 0x7F; //127->32.768KHz
RTC_InitStructure.RTC_SynchPrediv = 0xFF; // 255->32.768KHz
RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24;
RTC_Init(&RTC_InitStructure);
#elif defined (RTC_CLOCK_SOURCE_HSE)
/* Calendar Configuration */
/*RTC_LSE 为250.000kHz RTC_LSI = SynchPrediv * AsynchPrediv*/
RTC_InitStructure.RTC_AsynchPrediv = 0x09; //99->250KHz
RTC_InitStructure.RTC_SynchPrediv = 0xC35; // 2499->250KHz
RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24;
RTC_Init(&RTC_InitStructure);
#endif
//RTC_Alarm_Config();
}
【二】设置RTC时间函数,涉及到年、月、日、时、分、秒
/****************************************************************************/
/*Function Name : RTC Set DateTime */
/*Author : Paul */
/*Data : 2021-1-20 09:56:40 */
/*Timer : none */
/*Input Parameters : none. */
/*Return type : none */
/*Output Parameters : none */
/****************************************************************************/
void RTC_Set_DateTime(uint8_t year,uint8_t month, uint8_t weekday,uint8_t date,uint8_t hours ,uint8_t minutes ,uint8_t seconds)
{
RTC_TimeTypeDef RTC_TimeStructure;
RTC_DateTypeDef RTC_DateStructure;
/* Set the time to 00h 00mn 00s AM */
RTC_TimeStructure.RTC_H12 = RTC_H12_PM;
RTC_TimeStructure.RTC_Hours = hours;
RTC_TimeStructure.RTC_Minutes = minutes;
RTC_TimeStructure.RTC_Seconds = seconds;
RTC_SetTime(RTC_Format_BIN, &RTC_TimeStructure);
RTC_DateStructure.RTC_WeekDay=weekday;
RTC_DateStructure.RTC_Month=month;
RTC_DateStructure.RTC_Date=date;
RTC_DateStructure.RTC_Year=year;
RTC_SetDate(RTC_Format_BIN,&RTC_DateStructure);
RTC_WriteBackupRegister(RTC_BKP_DR0, 0xA5A5);
}
【三】闹钟配置函数
/****************************************************************************/
/*Function Name : RTC Alarm Config */
/*Author : Paul */
/*Data : 2021-1-21 11:48:43 */
/*Timer : none */
/*Input Parameters : none. */
/*Return type : none */
/*Output Parameters : none */
/****************************************************************************/
void RTC_Alarm_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
RTC_TimeTypeDef RTC_TimeStructure;
RTC_AlarmTypeDef RTC_AlarmStructure;
/* EXTI configuration *******************************************************/
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);
/* Enable the RTC Wakeup Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
RTC_ITConfig( RTC_IT_ALRA, DISABLE );
RTC_AlarmCmd(RTC_Alarm_A,DISABLE);
/* RTC_AlarmStructure.RTC_AlarmMask = RTC_AlarmMask_All;
RTC_SetAlarm(RTC_Format_BCD, RTC_Alarm_A, &RTC_AlarmStructure);
RTC_AlarmSubSecondConfig(RTC_Alarm_A, 0xFF, RTC_AlarmSubSecondMask_SS14_8);*/
RTC_GetTime(RTC_Format_BIN, &RTC_TimeStructure);
RTC_AlarmStructure.RTC_AlarmTime.RTC_H12=RTC_H12_AM;
RTC_AlarmStructure.RTC_AlarmTime.RTC_Hours=RTC_TimeStructure.RTC_Hours;
RTC_AlarmStructure.RTC_AlarmTime.RTC_Minutes=RTC_TimeStructure.RTC_Minutes;
RTC_AlarmStructure.RTC_AlarmTime.RTC_Seconds=RTC_TimeStructure.RTC_Seconds+5;
if(RTC_AlarmStructure.RTC_AlarmTime.RTC_Seconds >=60)
RTC_AlarmStructure.RTC_AlarmTime.RTC_Seconds-=60;
RTC_AlarmStructure.RTC_AlarmDateWeekDay = 0x31;
RTC_AlarmStructure.RTC_AlarmDateWeekDaySel = RTC_AlarmDateWeekDaySel_Date;
RTC_AlarmStructure.RTC_AlarmMask = RTC_AlarmMask_DateWeekDay | RTC_AlarmMask_Hours|RTC_AlarmMask_Minutes;
RTC_SetAlarm(RTC_Format_BIN, RTC_Alarm_A, &RTC_AlarmStructure);
RTC_ClearITPendingBit(RTC_IT_ALRA);
RTC_ITConfig(RTC_IT_ALRA, ENABLE);
RTC_AlarmCmd(RTC_Alarm_A, ENABLE);/* Enable the alarm */
}
【四】RTC中断函数
/****************************************************************************/
/*Function Name : RTC IRQHandler */
/*Author : Paul */
/*Data : 2021-1-20 10:35:27 */
/*Timer : none */
/*Input Parameters : none. */
/*Return type : none */
/*Output Parameters : none */
/****************************************************************************/
void RTC_IRQHandler(void)
{
if(RTC_GetFlagStatus(RTC_IT_TS)!=RESET)
{
RTC_ClearITPendingBit(RTC_IT_TS);
}
if(RTC_GetITStatus(RTC_IT_ALRA) != RESET)
{
RTC_ClearITPendingBit(RTC_IT_ALRA);
RTC_AlarmTime_Add_5_Sencond();
WDR_Count_Rst();
}
EXTI_ClearITPendingBit(EXTI_Line17);
}