//******************************************************************** // Ver 1.0 // 2021.11.19 1、新建文件。 //******************************************************************** #include "config.h" RTC_Str RTC_Info; /******************************************************************************/ /* Local function prototypes ('const') */ /******************************************************************************/ const uint8_t Leap_Month_Base[] = {3, 6, 0, 3, 5, 1, 3, 6, 2, 4, 0, 2}; const uint8_t NonLeap_Month_Base[] = {4, 0, 0, 3, 5, 1, 3, 6, 2, 4, 0, 2}; const uint8_t Cnst_Month_Tbl[12] = {0x31, 0x28, 0x31, 0x30, 0x31, 0x30, 0x31, 0x31, 0x30, 0x31, 0x30, 0x31}; RTC_TimeTypeDef RTC_Times; RTC_DateTypeDef RTC_Dates; void RTC_ReadDateTime(RTC_TIME_Str *pTime) { RTC_TimeTypeDef tRTC_TimeStructure; RTC_DateTypeDef tRTC_DateStructure; RTC_GetTime(RTC_Format_BIN, &tRTC_TimeStructure); RTC_GetDate(RTC_Format_BIN, &tRTC_DateStructure); pTime->year = 2000 + tRTC_DateStructure.RTC_Year; pTime->month = tRTC_DateStructure.RTC_Month; pTime->day = tRTC_DateStructure.RTC_Date; pTime->hour = tRTC_TimeStructure.RTC_Hours; pTime->min = tRTC_TimeStructure.RTC_Minutes; pTime->sec = tRTC_TimeStructure.RTC_Seconds; pTime->week = tRTC_DateStructure.RTC_WeekDay; } ErrorStatus RTC_SetDateTime(RTC_TIME_Str *pTime) { RTC_TimeTypeDef tRTC_TimeStructure; RTC_DateTypeDef tRTC_DateStructure; ErrorStatus tStatus = ERROR; tRTC_DateStructure.RTC_Year = pTime->year - 2000; tRTC_DateStructure.RTC_Month = pTime->month; tRTC_DateStructure.RTC_Date = pTime->day; tRTC_TimeStructure.RTC_Hours = pTime->hour; tRTC_TimeStructure.RTC_Minutes = pTime->min; tRTC_TimeStructure.RTC_Seconds = pTime->sec; tRTC_DateStructure.RTC_WeekDay = RTC_CalWeek(pTime); PWR_BackupAccessCmd(ENABLE); tStatus = RTC_SetDate(RTC_Format_BIN, &tRTC_DateStructure); if(tStatus != ERROR) { tStatus = RTC_SetTime(RTC_Format_BIN, &tRTC_TimeStructure); } if(tStatus != ERROR) { RTC_WriteBackupRegister(RTC_BKP_DR0, BKP_VAR_INIT); } PWR_BackupAccessCmd(DISABLE); return (SUCCESS); } void RTC_SetBootFlag(INT32U Value) { PWR_BackupAccessCmd(ENABLE); RTC_WriteBackupRegister(RTC_BKP_DR0, Value); PWR_BackupAccessCmd(DISABLE); } INT32U RTC_ReadBootFlag(void) { return(RTC_ReadBackupRegister(RTC_BKP_DR0)); } void RTC_BeiJinTimeToTimestamp(void) { struct tm BJ_Time; RTC_ReadDateTime(&RTC_Info.Time); BJ_Time.tm_year = RTC_Info.Time.year - 1900; BJ_Time.tm_mon = RTC_Info.Time.month - 1; BJ_Time.tm_mday = RTC_Info.Time.day; BJ_Time.tm_hour = RTC_Info.Time.hour; BJ_Time.tm_min = RTC_Info.Time.min; BJ_Time.tm_sec = RTC_Info.Time.sec; RTC_Info.Timestamp = mktime(&BJ_Time); //RTC_Info.Timestamp -= 8 * 60 * 60; } void RTC_TimestampToBeiJinTime(void) { struct tm *BJ_Time; //RTC_Info.Timestamp += (8 * 60 * 60); BJ_Time = localtime(&RTC_Info.Timestamp); RTC_Dates.RTC_Year = BJ_Time->tm_year + 1900; RTC_Dates.RTC_Month = BJ_Time->tm_mon + 1; RTC_Dates.RTC_Date = BJ_Time->tm_mday; RTC_Dates.RTC_WeekDay = BJ_Time->tm_wday; RTC_Times.RTC_Hours = BJ_Time->tm_hour; RTC_Times.RTC_Minutes = BJ_Time->tm_min; RTC_Times.RTC_Seconds = BJ_Time->tm_sec; } /** ****************************************************************************** ** \brief RTC 平、闰年检测 ** ** \param [in] u8year 年十进制低两位 ** ** \retval 1 闰年 ** \retval 0 平年 ******************************************************************************/ uint8_t RTC_CheckLeapYear(uint16_t u16year) { if ((((u16year % 4) == 0) && ((u16year % 100) != 0)) || ((u16year % 400) == 0)) { return 1; } else { return 0; } } /** ****************************************************************************** ** \brief RTC根据日期计算周数 ** ** \param [in] pu8Date日期 ** ** \retval week 周数 ** ******************************************************************************/ uint8_t RTC_CalWeek(RTC_TIME_Str* pTime) { uint8_t u8week; if ((RTC_CheckLeapYear(pTime->year) == 1)) { u8week = ((pTime->year - 2000) + (pTime->year - 2000) / 4 + Leap_Month_Base[pTime->month - 1] + pTime->day + 2) % 7; } else { u8week = ((pTime->year - 2000) + (pTime->year - 2000) / 4 + NonLeap_Month_Base[pTime->month - 1] + pTime->day + 2) % 7; } return u8week; } void RTC_Init(void) { EXTI_InitTypeDef EXTI_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; RTC_InitTypeDef RTC_InitStructure; RTC_InfoInit(); PWR_BackupAccessCmd(ENABLE); RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI); RCC_RTCCLKCmd(ENABLE); //RTC_WaitForSynchro(); RTC_Bkp0Value = RTC_ReadBootFlag(); if (((RTC_Bkp0IapFlag != BKP_VAR_INIT) && (RTC_Bkp0IapFlag != BKP_VAR_IAP)) || //RTC未初始化,且非进入IAP模式 (RTC_WaitForSynchro() == ERROR)) { RTC_InitStructure.RTC_SynchPrediv = 0x18F; RTC_InitStructure.RTC_AsynchPrediv = 0x63; RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24; RTC_Init1(&RTC_InitStructure); RTC_Info.Time.year = 2022; RTC_Info.Time.month = 8; RTC_Info.Time.day = 3; RTC_Info.Time.hour = 12; RTC_Info.Time.min = 0; RTC_Info.Time.sec = 0; RTC_SetDateTime(&RTC_Info.Time); } /*else if (RTC_ReadBackupRegister(RTC_BKP_DR0) == BKP_VAR_IAP) { RTC_WriteBackupRegister(RTC_BKP_DR0, BKP_VAR_INIT); }*/ PWR_BackupAccessCmd(DISABLE); EXTI_ClearITPendingBit(EXTI_Line17); EXTI_InitStructure.EXTI_Line = EXTI_Line17; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStructure); NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn; NVIC_InitStructure.NVIC_IRQChannelPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } void RTC_SetAlarmValue(RTC_ALARM_Str *AlarmTime) { RTC_AlarmTypeDef tRTC_AlarmStructure; PWR_BackupAccessCmd(ENABLE); RTC_AlarmCmd(RTC_Alarm_A, DISABLE); tRTC_AlarmStructure.RTC_AlarmTime.RTC_Hours = AlarmTime->alarmhour; tRTC_AlarmStructure.RTC_AlarmTime.RTC_Minutes = AlarmTime->alarmmin; tRTC_AlarmStructure.RTC_AlarmTime.RTC_Seconds = AlarmTime->alarmsec; tRTC_AlarmStructure.RTC_AlarmDateWeekDaySel = RTC_AlarmDateWeekDaySel_Date; tRTC_AlarmStructure.RTC_AlarmDateWeekDay = AlarmTime->alarmweek; tRTC_AlarmStructure.RTC_AlarmMask = RTC_AlarmMask_Seconds; RTC_SetAlarm(RTC_Format_BIN, RTC_Alarm_A, &tRTC_AlarmStructure); RTC_ITConfig(RTC_IT_ALRA, ENABLE); RTC_AlarmCmd(RTC_Alarm_A, ENABLE); PWR_BackupAccessCmd(DISABLE); } void RTC_AlarmCycle(INT32U tSec) { RTC_TimeTypeDef tRTC_TimeStructure; RTC_AlarmTypeDef tRTC_AlarmStructure; RTC_GetTime(RTC_Format_BIN, &tRTC_TimeStructure); tSec = tSec + tRTC_TimeStructure.RTC_Seconds; PWR_BackupAccessCmd(ENABLE); RTC_AlarmCmd(RTC_Alarm_A, DISABLE); tRTC_AlarmStructure.RTC_AlarmMask = RTC_AlarmMask_DateWeekDay | RTC_AlarmMask_Hours | RTC_AlarmMask_Minutes; tRTC_AlarmStructure.RTC_AlarmDateWeekDaySel = RTC_AlarmDateWeekDaySel_WeekDay; tRTC_AlarmStructure.RTC_AlarmDateWeekDay = RTC_Weekday_Monday; tRTC_AlarmStructure.RTC_AlarmTime.RTC_H12 = tRTC_TimeStructure.RTC_H12; tRTC_AlarmStructure.RTC_AlarmTime.RTC_Hours = 0; tRTC_AlarmStructure.RTC_AlarmTime.RTC_Minutes = 0; tRTC_AlarmStructure.RTC_AlarmTime.RTC_Seconds = tSec % 60; RTC_SetAlarm(RTC_Format_BIN, RTC_Alarm_A, &tRTC_AlarmStructure); RTC_ClearFlag(RTC_FLAG_ALRAF); RTC_ClearITPendingBit(RTC_IT_ALRA); EXTI_ClearITPendingBit(EXTI_Line17); RTC_ITConfig(RTC_IT_ALRA, ENABLE); RTC_AlarmCmd(RTC_Alarm_A, ENABLE); PWR_BackupAccessCmd(DISABLE); } void RTC_IRQHandler(void) { //static INT16U tSec = 0; if (RTC_GetITStatus(RTC_IT_ALRA) != RESET) { RTC_ClearITPendingBit(RTC_IT_ALRA); EXTI_ClearITPendingBit(EXTI_Line17); } /*tSec ++; if (tSec > 60) { tSec = 0; if (BATT_FLAG_STA == STA_IDLE) { BATT_StorageCnt ++; } }*/ }