1.对RTC的操作必须确保前一次写操作完成后操作,所以必须通过查询RTC—CR寄存器的RTOFF状态位,只有RTOFF为1,才可以写RTC寄存器。
2.首先需要定义几个先。
#define RTCClockSource_LSE
程序:
1.RTC配置
void RTC_Configuration(void) {
/* Enable PWR and BKP clocks ,打开电源 管理和备份寄存器时钟*/
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE); /* Allow access to BKP Domain ,使能RTC和备份寄存器的访问*/
PWR_BackupAccessCmd(ENABLE);
/* Reset Backup Domain ,设为BKP备份区域的全部为缺省值*/
BKP_DeInit();
//RTC所需的晶振再TCC部分的寄存器选择,rtc时钟从LSI,LSE,HSE选择
#ifdef RTCClockSource_LSI
/* Enable LSI */
RCC_LSICmd(ENABLE);
/* Wait till LSI is ready */
while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET) { }
/* Select LSI as RTC Clock Source */
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
#elif defined RTCClockSource_LSE
/* Enable LSE */
//01.RCC打开了LSE的时钟
RCC_LSEConfig(RCC_LSE_ON);
/* Wait till LSE is ready */
//02。等待LSE就绪,如果谐振不对,就会死在这里
while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET) { }
/* Select LSE as RTC Clock Source */
//03.RTC使用时钟源
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
#endif
/* Enable RTC Clock */
//RTC时钟开启
RCC_RTCCLKCmd(ENABLE);
#ifdef RTCClockOutput_Enable
/* Disable the Tamper Pin */
BKP_TamperPinCmd(DISABLE);
/* To output RTCCLK/64 on Tamper pin, the tamper functionality must be disabled */
/* Enable RTC Clock Output on Tamper Pin */
BKP_RTCCalibrationClockOutputCmd(ENABLE);
#endif
/* Wait for RTC registers synchronization */
//RTC 等待同步
RTC_WaitForSynchro();
/* Wait until last write operation on RTC registers has finished */
//RTC等待就绪
RTC_WaitForLastTask();
/* Enable the RTC Second */
//使能RTC秒中断
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预分频,32KHZ
#ifdef RTCClockSource_LSI
RTC_SetPrescaler(31999);
/* RTC period = RTCCLK/RTC_PR = (32.000 KHz)/(31999+1) */
#elif defined RTCClockSource_LSE
RTC_SetPrescaler(32767);
/* RTC period = RTCCLK/RTC_PR = (32.768 KHz)/(32767+1) */
#endif
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
}
2.时间显示调整配置
/******************************************************************************* * Function Name : Time_Regulate
* Description : Returns the time entered by user, using Hyperterminal.
*******************************************************************************/ u32 Time_Regulate(void) {
u32 Tmp_HH = 0xFF, Tmp_MM = 0xFF, Tmp_SS = 0xFF;
printf ("\r\n==============TimeSettings============================="); printf("\r\n Please Set Hours");
while(Tmp_HH == 0xFF)
{
Tmp_HH = USART_Scanf(23);
}
printf(": %d", Tmp_HH);
printf("\r\n Please Set Minutes");
while(Tmp_MM == 0xFF)
{
Tmp_MM = USART_Scanf(59);
}
printf(": %d", Tmp_MM);
printf("\r\n Please Set Seconds");
while(Tmp_SS == 0xFF)
{
Tmp_SS = USART_Scanf(59);
}
printf(": %d", Tmp_SS);
/* Return the value to store in RTC counter register */
return((Tmp_HH*3600 + Tmp_MM*60 + Tmp_SS));
}
/******************************************************************************* * Function Name : Time_Adjust
*******************************************************************************/ void Time_Adjust(void) {
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
/* Change the current time */
RTC_SetCounter(Time_Regulate());
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
}
/******************************************************************************* * Function Name : Time_Display
* Description : Displays the current time.
*******************************************************************************/ void Time_Display(u32 TimeVar) {
u32 THH = 0, TMM = 0, TSS = 0;
/* Compute hours */
THH = TimeVar/3600;
/* Compute minutes */
TMM = (TimeVar % 3600)/60;
/* Compute seconds */
TSS = (TimeVar % 3600)% 60;
printf("Time: %0.2d:%0.2d:%0.2d\r",THH, TMM, TSS); }
/******************************************************************************* * Function Name : Time_Show
* Description : Shows the current time (HH:MM:SS) on the Hyperterminal.
******************************************************************************/ void Time_Show(void) {
printf("\n\r");
/* Infinite loop */
while(1) {
/* If 1s has paased */
if(TimeDisplay == 1)
{
/* Display current time */
Time_Display(RTC_GetCounter());
TimeDisplay = 0;
} } }
3.RTC的中断配置
NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
4.上电判断是否,如果否,则直接显示时钟,否则直接配置时间
if(BKP_ReadBackupRegister(BKP_DR1) != 0xA5A5)
{
/* Backup data register value is not correct or not yet programmed (when the first time the program is executed) */
printf("\r\n\n RTC not yet configured....");
RTC_Configuration();
printf("\r\n RTC configured....");
/* Adjust time by values entred by the user on the hyperterminal */
Time_Adjust();
//往备份域寄存器中写一个特殊的字符
BKP_WriteBackupRegister(BKP_DR1, 0xA5A5);
}
else {
/* Check if the Power On Reset flag is set */
if(RCC_GetFlagStatus(RCC_FLAG_PORRST) != RESET)
{
printf("\r\n\n Power On Reset occurred....");
}
/* Check if the Pin Reset flag is set */
else if(RCC_GetFlagStatus(RCC_FLAG_PINRST) != RESET)
{
printf("\r\n\n External Reset occurred....");
}
printf("\r\n No need to configure RTC....");
/* Wait for RTC registers synchronization */
//RTC等待同步
RTC_WaitForSynchro();
/* Enable the RTC Second */
//使能RTC秒中断
RTC_ITConfig(RTC_IT_SEC, ENABLE);
/* Wait until last write operation on RTC registers has finished */
//RTC写入准备就绪
RTC_WaitForLastTask();
}
/* Clear reset flags */
//清除RTC重启标志
RCC_ClearFlag();
/* Display time in infinte loop */
Time_Show();