stm32的RTC时钟源有三个方式(截图来源正点原子资料)
1.HSE分频过来
2.LSE 32.768K晶体
3.LSI内部RC振荡器
下面示例采用的是HSE时钟源
1.RTC时钟源配置
#define RTC_CLOCK_SOURCE_HSE
#define RTC_FLAG_BKP 1
__IO uint32_t AsynchPrediv = 0, SynchPrediv = 0;
void RTC_Config(void)
{
#if defined (RTC_CLOCK_SOURCE_LSI) /* LSI used as RTC source clock*/
/* The RTC Clock may varies due to LSI frequency dispersion. */
/* 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);
/*40khz (0x18f+1)*(0x63+1)=40k */
SynchPrediv = 0x18F;
AsynchPrediv = 0x63;
#elif defined (RTC_CLOCK_SOURCE_LSE) /* LSE used as RTC source clock */
/* Enable the LSE OSC */
RCC_LSEConfig(RCC_LSE_ON);
/* Wait till LSE is ready */
while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
{
}
/* Select the RTC Clock Source */
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
/*32.768khz (0xff+1)*(0x7f+1)=32.768k */
SynchPrediv = 0xFF;
AsynchPrediv = 0x7F;
#elif defined(RTC_CLOCK_SOURCE_HSE)
RCC_HSEConfig(RCC_HSE_ON);
/* Wait till HSE is ready */
while(RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET)
{
}
/*外部晶振8M, 32分频 8M/32=250K*/
RCC_RTCCLKConfig(RCC_RTCCLKSource_HSE_Div32);
/*250khz (2499+1)*(99+1)=250k */
SynchPrediv = 2499;
AsynchPrediv = 99;
#else
#error Please select the RTC Clock source inside the main.c file
#endif /* RTC_CLOCK_SOURCE_LSI */
/* Enable the RTC Clock */
RCC_RTCCLKCmd(ENABLE);
/* Wait for RTC APB registers synchronisation */
RTC_WaitForSynchro();
}
2.初始化RTC
void RTC_init(void)
{
RTC_InitTypeDef RTC_InitStructure;
RTC_TimeTypeDef RTC_TimeStruct;
/* Enable the PWR clock */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
/* Allow access to RTC */
PWR_BackupAccessCmd(ENABLE);
if(RTC_ReadBackupRegister(RTC_BKP_DR0) != RTC_FLAG_BKP)
{
/* RTC configuration */
RTC_Config();
/* Configure the RTC data register and RTC prescaler */
RTC_InitStructure.RTC_AsynchPrediv = AsynchPrediv;
RTC_InitStructure.RTC_SynchPrediv = SynchPrediv;
RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24;
/* Check on RTC init */
if (RTC_Init(&RTC_InitStructure) == ERROR)
{
printf("\n\r /!\\***** RTC Prescaler Config failed ********/!\\ \n\r");
}
/* Set the time to 00h 00mn 00s AM */
RTC_TimeStruct.RTC_H12 = RTC_H12_AM;
RTC_TimeStruct.RTC_Hours = 0x00;
RTC_TimeStruct.RTC_Minutes = 0x00;
RTC_TimeStruct.RTC_Seconds = 0x00;
RTC_SetTime(RTC_Format_BCD, &RTC_TimeStruct);
RTC_WriteBackupRegister(RTC_BKP_DR0, RTC_FLAG_BKP);
}
else
{
#ifdef RTC_CLOCK_SOURCE_LSI
RCC_LSICmd(ENABLE);
#endif
RTC_WaitForSynchro(); /*等待RTC与RTC_APB时钟同步*/
}
}
RTC初始化完成,应用就可以
RTC_GetTime
RTC_GetDate
RTC_SetTime
RTC_SetDate
获取和设置日期和时间了。
样例采用的是HSE时钟源,RTC的误差非常小(几天才几秒,取决于外部晶体精度),如果是HEI时钟源,误差可能1天几分钟甚至几十分钟。
STM32时钟详细介绍参见http://bbs.elecfans.com/forum.php?mod=viewthread&tid=388275
感谢您的关注,承接STM32 + MC20/EC20/M5311的开发项目(Q190109829)