RTC
LSE Ready卡死
使用st-link下載器對板子供電,供電能力不夠,導致外部LSE始終不能ready,但LSI可以。換外部電源供電之後,LSE也可以鎖定。第二天測試,又卡死,不是電源供電問題,懷疑是LSE不起振,板子上晶振離單片機距離有點遠,目前沒有安裝電池,測試不是沒有按照電池的問題。
#if 1
/* Enable LSE */
RCC_LSEConfig(RCC_LSE_ON);
/* Wait till LSE is ready */
while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
{}
/* Select LSE as RTC Clock Source */
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
#else
RCC_LSICmd(ENABLE);
while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET)
{}
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
#endif
RTC_WaitForSynchro卡死
首先將標準庫例子中RTC_Configuration中的下面三行代碼放到上面Time_init中,如果使用LSI則LSI初始化也應放出來,可能是由於沒有安裝電池的原因。
/**
* @brief Configures the RTC.
* @param None
* @retval None
*/
void RTC_Configuration(void)
{
#if 0 /*move to top for RTC_WaitForSynchro dead*/
/* Enable PWR and BKP clocks */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
/* Allow access to BKP Domain */
PWR_BackupAccessCmd(ENABLE);
#endif
/* Reset Backup Domain */
BKP_DeInit();
#if 0
#if EN_RTC_LSE
/* Enable LSE */
RCC_LSEConfig(RCC_LSE_ON);
/* Wait till LSE is ready */
while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
{}
/* Select LSE as RTC Clock Source */
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
#else
RCC_LSICmd(ENABLE);
while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET)
{}
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
#endif
#endif
/* Enable RTC Clock */
RCC_RTCCLKCmd(ENABLE);
/* Wait for RTC registers synchronization */
RTC_WaitForSynchro();
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
/* Enable the RTC Second */
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_SetPrescaler(32767); /* RTC period = RTCCLK/RTC_PR = (32.768 KHz)/(32767+1) */
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
}
void Time_init(void)
{
/*Enables the clock to Backup and power interface peripherals */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP | RCC_APB1Periph_PWR,ENABLE);
/*Allow access to Backup Registers*/
PWR_BackupAccessCmd(ENABLE);
#if EN_RTC_LSE
/* Enable LSE */
RCC_LSEConfig(RCC_LSE_ON);
/* Wait till LSE is ready */
while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
{}
/* Select LSE as RTC Clock Source */
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
#else
RCC_LSICmd(ENABLE);
while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET)
{}
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
#endif
/*delay_us(100);*//*delay because uart print error chars*/
/*uart_printf("%s line%d\r\n", __FUNCTION__, __LINE__);*/
if (BKP_ReadBackupRegister(BKP_DR1) != CONFIGURATION_DONE)
{
/* Backup data register value is not correct or not yet programmed (when
the first time the program is executed) */
/* RTC Configuration */
uart_printf("RTC configured....\r\n");
RTC_Configuration();
uart_printf("Please Set time and date from shell\r\n");
BKP_WriteBackupRegister(BKP_DR1, CONFIGURATION_DONE);
}
else
{
delay_us(2000);
/* Check if the Power On Reset flag is set */
if (RCC_GetFlagStatus(RCC_FLAG_PORRST) != RESET)
{
uart_printf("Power On Reset occurred....");
}
/* Check if the Pin Reset flag is set */
else if (RCC_GetFlagStatus(RCC_FLAG_PINRST) != RESET)
{
uart_printf("External Reset occurred....");
}
uart_printf("No need to configure RTC....\r\n");
/* Wait for RTC registers synchronization */
RTC_WaitForSynchro();
/* Enable the RTC Second */
RTC_ITConfig(RTC_IT_SEC, ENABLE);
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
}
/* Clear reset flags */
RCC_ClearFlag();
/* Check if how many days are elapsed in power down/Low Power Mode-
Updates Date that many Times*/
CheckForDaysElapsed();
s_time_date.Month = BKP_ReadBackupRegister(BKP_DR2);
s_time_date.Day = BKP_ReadBackupRegister(BKP_DR3);
s_time_date.Year = BKP_ReadBackupRegister(BKP_DR4);
}
但並沒有解決我的問題,懷疑是電路進入某種異常狀態,雖然沒有放後備電池,但總是檢測到RTC已經配置,我更改CONFIGURATION_DONE的值,讓RTC重新配置後,bug解除!!!