void rtc_write(void) { if(!rtc_ok) { // Enable the PWR clock RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); // Allow access to RTC PWR_BackupAccessCmd(ENABLE); // 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); // Enable the RTC Clock RCC_RTCCLKCmd(ENABLE); // Wait for RTC APB registers synchronisation RTC_WaitForSynchro(); // Enable The TimeStamp RTC_TimeStampCmd(RTC_TimeStampEdge_Falling, ENABLE); // TODO: can return ERROR RTC_InitTypeDef RTC_InitStructure; RTC_InitStructure.RTC_AsynchPrediv = 0x7F; RTC_InitStructure.RTC_SynchPrediv = 0xFF; RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24; RTC_Init(&RTC_InitStructure); } RTC_TimeTypeDef TimeRTC; RTC_DateTypeDef DateRTC; TimeRTC.RTC_H12 = RTC_H12_AM; // Always AM for 24H TimeRTC.RTC_Hours = rtc_hour; TimeRTC.RTC_Minutes = rtc_minute; TimeRTC.RTC_Seconds = rtc_second; RTC_SetTime(RTC_Format_BIN, &TimeRTC); (void)RTC->DR; DateRTC.RTC_WeekDay = rtc_day; DateRTC.RTC_Date = rtc_date; DateRTC.RTC_Month = rtc_month; DateRTC.RTC_Year = rtc_year; RTC_SetDate(RTC_Format_BIN, &DateRTC); // TODO: can return ERROR RTC_WriteBackupRegister(RTC_BKP_DR0, 0xCA7E); rtc_ok = true; }
/** * @brief Configure the RTC peripheral by selecting the clock source. * @param None * @retval None */ void RTC_Config(void) { /* Enable the PWR clock */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); /* Allow access to RTC */ PWR_BackupAccessCmd(ENABLE); #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); 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); SynchPrediv = 0xFF; AsynchPrediv = 0x7F; #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(); /* Enable The TimeStamp */ RTC_TimeStampCmd(RTC_TimeStampEdge_Falling, ENABLE); }
/*------------------------------------初始化RTC----------------------*/ static void RTC_Config(void) { //外设时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); //开启设置权限 PWR_BackupAccessCmd(ENABLE); //开启外设时钟源为外部时钟 RCC_LSEConfig(RCC_LSE_ON); //等待稳定 while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET); RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);//选择LSE //以下生成1HZ的节律 RTC_InitStructure.RTC_AsynchPrediv = 0x7F;//异步 RTC_InitStructure.RTC_SynchPrediv = 0xFF;//同步 RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24;//时间格式 RTC_Init(&RTC_InitStructure); //时能RTC RCC_RTCCLKCmd(ENABLE); /* Wait for RTC APB registers synchronisation */ RTC_WaitForSynchro(); /* Enable The TimeStamp */ RTC_TimeStampCmd(RTC_TimeStampEdge_Falling, ENABLE); }
/** * @brief Configure the RTC peripheral by selecting the clock source. * @param None * @retval None */ static void RTC_Config(void) { /* Enable the PWR clock */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); /* Allow access to RTC */ PWR_BackupAccessCmd(ENABLE); #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); /* ck_spre(1Hz) = RTCCLK(LSI) /(uwAsynchPrediv + 1)*(uwSynchPrediv + 1)*/ uwSynchPrediv = 0xFF; uwAsynchPrediv = 0x7F; #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); /* ck_spre(1Hz) = RTCCLK(LSE) /(uwAsynchPrediv + 1)*(uwSynchPrediv + 1)*/ uwSynchPrediv = 0xFF; uwAsynchPrediv = 0x7F; #else #error Please select the RTC Clock source inside the main.c file #endif /* RTC_CLOCK_SOURCE_LSI */ /* Configure the RTC data register and RTC prescaler */ RTC_InitStructure.RTC_AsynchPrediv = uwAsynchPrediv; RTC_InitStructure.RTC_SynchPrediv = uwSynchPrediv; RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24; /* Check on RTC init */ if (RTC_Init(&RTC_InitStructure) == ERROR) { /* Set the Back Color */ LCD_SetBackColor(LCD_COLOR_WHITE); /* Set the Text Color */ LCD_SetTextColor(LCD_COLOR_RED); LCD_DisplayStringLine(LCD_LINE_3,(uint8_t *) "RTC Prescaler Config failed " ); } /* Enable the RTC Clock */ RCC_RTCCLKCmd(ENABLE); /* Wait for RTC APB registers synchronisation */ RTC_WaitForSynchro(); /* Enable The TimeStamp */ RTC_TimeStampCmd(RTC_TimeStampEdge_Falling, ENABLE); }
/* ********************************************************************************************************* * 函 数 名: RTC_Config * 功能说明: 用于配置时间戳功能 * 形 参:无 * 返 回 值: 无 ********************************************************************************************************* */ void RTC_Config(void) { int RtcTimeout; /* RTC超时计数 */ RTC_TimeTypeDef RTC_TimeStructure; RTC_InitTypeDef RTC_InitStructure; RTC_DateTypeDef RTC_DateStructure; Mem_Set(&RTC_TimeStructure, 0x00, sizeof(RTC_TimeTypeDef)); Mem_Set(&RTC_InitStructure, 0x00, sizeof(RTC_InitTypeDef)); Mem_Set(&RTC_DateStructure, 0x00, sizeof(RTC_DateTypeDef)); RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);/* 使能PWR时钟 */ PWR_BackupAccessCmd(ENABLE);/* 允许访问RTC */ try_again: if(OBCBootInfo.BootRTC_Source == 0) /* 选择LSE作为时钟源 */ { RCC_LSEConfig(RCC_LSE_ON); /* 使能LSE振荡器 */ RtcTimeout = 0; /* 等待就绪 */ while((RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET) && ((RtcTimeout++) < RTC_TIMEOUT_US))//20 { bsp_DelayUS(1); /* STM32延迟函数 */ } if(RtcTimeout > RTC_TIMEOUT_US) //18 /* 判断是否有超时 */ { DEBUG_LOG("Init RTC Wrong: Oscillator time out! \r\n"); RCC_LSEConfig(RCC_LSE_OFF); OBCBootInfo.BootLSE_Error = 1; OBCBootInfo.BootRTC_Source = 1; /* 自动配置RTC为内部时钟 */ } if(OBCBootInfo.BootRTC_Source == 0) { DEBUG_LOG("Enable RTC with LSE \r\n"); RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); /* 选择RTC时钟源 */ uwSynchPrediv = 0xFF; uwAsynchPrediv = 0x7F; } } if(OBCBootInfo.BootRTC_Source == 1) /* 选择LSI作为时钟源 */ { RCC_LSICmd(ENABLE); /* 使能内部时钟 */ RtcTimeout = 0; /* 等待内部时钟稳定*/ while((RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET) && ((RtcTimeout++) < RTC_TIMEOUT_US)) { bsp_DelayUS(1); /* STM32延迟函数 */ } if(RtcTimeout > RTC_TIMEOUT_US) { DEBUG_LOG("All Oscillator time out! \r\n"); //RCC_LSICmd(DISABLE); OBCBootInfo.BootLSI_Error = 1; OBCBootInfo.BootRTC_Source = 2; /* 自动配置RTC为内部时钟 */ } if(OBCBootInfo.BootRTC_Source == 1) { DEBUG_LOG("Enable RTC with LSI \r\n"); RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI); /* 选择RTC时钟源 */ uwSynchPrediv = 0xFF; uwAsynchPrediv = 0x7F; } } if((OBCBootInfo.BootRTC_Source == 0)||(OBCBootInfo.BootRTC_Source == 1)) { RCC_RTCCLKCmd(ENABLE); /* 使能RTC时钟 */ RTC_WaitForSynchro(); /* 等待RTC APB寄存器同步 */ RTC_TimeStampCmd(RTC_TimeStampEdge_Falling, ENABLE); /* 使能时间戳 */ RTC_TimeStampPinSelection(RTC_TamperPin_PC13); RTC_InitStructure.RTC_AsynchPrediv = uwAsynchPrediv; /* 配置RTC数据寄存器和分频器 */ RTC_InitStructure.RTC_SynchPrediv = uwSynchPrediv; RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24; if (RTC_Init(&RTC_InitStructure) == ERROR) /* 检测RTC初始化 */ { DEBUG_LOG("RTC Init wrong \r\n"); if(OBCBootInfo.BootRTC_Source == 0) { OBCBootInfo.BootRTC_Source = 1; goto try_again; } } /* 设置年月日和星期 */ RTC_DateStructure.RTC_Year = 0x14; RTC_DateStructure.RTC_Month = RTC_Month_October; RTC_DateStructure.RTC_Date = 0x23; RTC_DateStructure.RTC_WeekDay = RTC_Weekday_Thursday; RTC_SetDate(RTC_Format_BCD, &RTC_DateStructure); /* 设置时分秒,以及显示格式 */ RTC_TimeStructure.RTC_H12 = RTC_H12_AM; RTC_TimeStructure.RTC_Hours = 0x00; RTC_TimeStructure.RTC_Minutes = 0x00; RTC_TimeStructure.RTC_Seconds = 0x00; RTC_SetTime(RTC_Format_BCD, &RTC_TimeStructure); } }