gd32的rtc用起来真是不好用,对晶振要求太高,不容易起振。本文章旨在解决外部LSE不起振时,使用LSI并保证精度的解决方案。
struct RTC_MONITOR
{
uint8_t monitor_on;//0:on,1:off
uint8_t rtcclk_source;//0:lse,1:lsi
uint8_t rtc_backsecond;
uint8_t rtc_second;
uint32_t timer_period;
uint32_t sysrun_bytimer;
uint32_t sysrun_bytimers;
uint32_t sysrun_byrtc;
uint8_t get_second;
uint8_t get_minute;
uint8_t get_hour;
uint8_t get_day;
uint8_t get_month;
uint32_t get_year;
uint32_t get_counter;
};
struct RTC_MONITOR rtc_monitor;
int main(void)
{
//init hardware
RTC_Configuration();
init_rtc_monitor();
while(1)
{
rtc_monitor_on();
}
}
uint32_t lwoff_timeout,rsf_timeout,lsifrequency;
void RTC_Configuration(void)
{
uint32_t WaitForOscSource;
/*Enables the clock to Backup and power interface peripherals */
RCC_APB1PeriphClock_Enable(RCC_APB1PERIPH_BKP | RCC_APB1PERIPH_PWR,ENABLE);
/* RTC clock source configuration ------------------------------------------*/
/* Allow access to BKP Domain */
PWR_BackupAccess_Enable(ENABLE);
/*Enable 40 kHz internal oscillator */
RCC_LSI_Enable(ENABLE);//´ò¿ªLSI
while(RCC_GetBitState(RCC_FLAG_LSISTB)==RESET);//µÈ´ýÖ±µ½LSIÎȶ¨
//read back
rtc_monitor.get_day = BKP_ReadBackupRegister(BKP_DR3);
rtc_monitor.get_month = BKP_ReadBackupRegister(BKP_DR2);
rtc_monitor.get_year = BKP_ReadBackupRegister(BKP_DR4);
rtc_monitor.get_second = BKP_ReadBackupRegister(BKP_DR5);
rtc_monitor.get_minute = BKP_ReadBackupRegister(BKP_DR6);
rtc_monitor.get_hour = BKP_ReadBackupRegister(BKP_DR7);
rtc_monitor.get_counter = RTC_GetCounter();
if(BKP_ReadBackupRegister(BKP_DR1)==CONFIGURATION_RESET)
{
/* Backup Domain Reset */
//rtc clk init
BKP_DeInit();
PWR_BackupAccess_Enable(ENABLE);
while((PWR->CTLR & PWR_CTLR_BKPWE) == RESET);
/*Enable 32.768 kHz external oscillator */
RCC_LSEConfig(RCC_LSE_EN);
for(WaitForOscSource=0;WaitForOscSource<5000;WaitForOscSource++)
{
}
RCC_RTCCLKConfig(RCC_RTCCLKSOURCE_LSE);
/* RTC Enabled */
RCC_RTCCLK_Enable(ENABLE);
//RTC_WaitLWOFF();
lwoff_timeout = LSE_STARTUP_TIMEOUT;
/* Loop until RTOFF flag is set */
while (((RTC->CTLR2 & RTC_FLAG_LWOFF) == (uint16_t)RESET)&&(lwoff_timeout))
{
lwoff_timeout--;
}
/*Wait for RTC registers synchronisation */
//RTC_WaitRSF();
/* Clear RSF flag */
RTC->CTLR2 &= ~((uint16_t)RTC_FLAG_RSF);
/* Loop until RSF flag is set */