#include "r_typedefs.h" #include "dr7f701441.dvf.h" #include "RTC.h" volatile uint8_t g_RTCLeapYear; /*1:LeapYear , 0:Not a leap year*/ volatile RTC_Information_st_t g_stRTCInformation; static uint8_t Cal_RTC_Week(uint16_t Year, uint8_t Month, uint8_t Day); /* BCD Convert decimalism*/ /*The valid range of parameters is not judged*/ static uint8_t RTC_BCD_To_Dec(uint8_t u8RTCBCD) { uint8_t u8RTCData = ((u8RTCBCD >> 4U) * 10U) + (u8RTCBCD & 0X0FU); return u8RTCData; } /* decimalism Convert BCD */ static uint8_t RTC_Dec_To_BCD(uint8_t u8RTCDec) { uint8_t u8RTCData = (((u8RTCDec / 10U) % 10U) << 4U) + (u8RTCDec % 10U); return u8RTCData; } /**************************************************************************/ /** * \brief Determine if a year is leap year * \param Year: the year to be determined * \retval \arg 0: Not leap year * \arg 1: Leap year ******************************************************************************/ static uint8_t RTC_Determine_Leap_Year(uint16_t Year) { uint16_t u16RTCLeapYear = Year; /*u16RTCLeapYear = ((Year >> 4) & 0x0F) * 10 + (Year & 0x0F);*/ if (u16RTCLeapYear & 0x0003U) { u16RTCLeapYear = 0U; } else { u16RTCLeapYear = 1U; } return (uint8_t)u16RTCLeapYear; } static void RTC_Stop(void) { /*Stop sub-counter */ RTCA0CE = 0U; /*Wait sub-counter stop*/ while (RTCA0CEST != 0) { ; } } void RTC_Pre_Init(void) { RTC_Stop(); /* Stop RTCA*/ #if (RTC_MODE_SELECT == RTC_MODE_MAIN) RTCA0SLSB = 1U; /*Frequency selection mode*/ RTCA0SCMP = 4000000U - 1U; /*4M*/ #else RTCA0SLSB = 0U; /*32.768 kHz mode*/ RTCA0SUBU = 0U; /*Reserved Later modified,Error Correction*/ #endif RTCA0AMPM = 1U; /*fix 24Hour Format*/ /*Write start values*/ RTCA0YEAR = RTC_Dec_To_BCD(RTC_DEFAULT_YEAR); RTCA0MONTH = RTC_Dec_To_BCD(RTC_DEFAULT_MONTH); RTCA0DAY = RTC_Dec_To_BCD(RTC_DEFAULT_DATE); RTCA0HOUR = RTC_Dec_To_BCD(RTC_DEFAULT_HOUR); RTCA0MIN = RTC_Dec_To_BCD(RTC_DEFAULT_MINUTE); RTCA0SEC = RTC_Dec_To_BCD(RTC_DEFAULT_SECOND); /*Starts sub-counter*/ RTCA0CE = 1U; /*Wait sub-counter enable*/ while (RTCA0CEST != 1U) { ; } } void RTC_Set_Time(RTC_Information_st_t *pstRTCTime) { while (RTCA0WST != 0U) /*Check that all clock counters are running.*/ { ; } RTCA0WAIT = 1U; /*Stop all clock counters*/ while (RTCA0WST != 1U) /*Wait all clock counters stop*/ { ; } /*Write start values*/ RTCA0YEAR = RTC_Dec_To_BCD(pstRTCTime->u8RTCYear); RTCA0MONTH = RTC_Dec_To_BCD(pstRTCTime->u8RTCMonth); RTCA0DAY = RTC_Dec_To_BCD(pstRTCTime->u8RTCDayOfMonth); RTCA0HOUR = RTC_Dec_To_BCD(pstRTCTime->u8RTCHour); RTCA0MIN = RTC_Dec_To_BCD(pstRTCTime->u8RTCMinute); RTCA0SEC = RTC_Dec_To_BCD(pstRTCTime->u8RTCSecond); /*Start all clock counters*/ RTCA0WAIT = 0U; while (RTCA0WST != 0U) /*Check that all clock counters are running.*/ { ; } } /**************************************************************************/ /** * \brief Rreal time clock timing control * \attention Call this function every 100 ms. * \retval None ******************************************************************************/ void RTC_Timing_Service(void) { uint8_t Week = 0 ; while (RTCA0WST != 0U) /*Check that all clock counters are running.*/ { ; } RTCA0WAIT = 1U; /*Stop all clock counters*/ while (RTCA0WST != 1U) /*Wait all clock counters stop*/ { ; } /*Read data*/ g_stRTCInformation.u8RTCYear = RTC_BCD_To_Dec(RTCA0YEAR); g_stRTCInformation.u8RTCMonth = RTC_BCD_To_Dec(RTCA0MONTH); g_stRTCInformation.u8RTCDayOfMonth = RTC_BCD_To_Dec(RTCA0DAY); g_stRTCInformation.u8RTCHour = RTC_BCD_To_Dec(RTCA0HOUR); g_stRTCInformation.u8RTCMinute = RTC_BCD_To_Dec(RTCA0MIN); g_stRTCInformation.u8RTCSecond = RTC_BCD_To_Dec(RTCA0SEC); Week = Cal_RTC_Week(g_stRTCInformation.u8RTCYear, g_stRTCInformation.u8RTCMonth, g_stRTCInformation.u8RTCDayOfMonth); if (Week) { g_stRTCInformation.u8RTCWeek = Week ; } g_RTCLeapYear = RTC_Determine_Leap_Year(g_stRTCInformation.u8RTCYear); /*Start all clock counters*/ RTCA0WAIT = 0U; while (RTCA0WST != 0U) /*Check that all clock counters are running.*/ { ; } } void RTC_Init(void) { RTC_Timing_Service(); } /*计算 星期几*/ static uint8_t Cal_RTC_Week(uint16_t Year, uint8_t Month, uint8_t Day) { static uint8_t DefaultWeek = 6 ; //2000.1.1 static uint16_t OldYear = 0 ; static uint8_t OldMonth = 0 ; static uint8_t OldDay = 0 ; uint8_t u8Result = 0 ; uint32_t DiffDay = 0 ; uint16_t DiffYear = 0 ; uint16_t DiffMouth = 0 ; if ((Year != OldYear) || (Month != OldMonth) || (Day != OldDay)) { OldYear = Year ; OldMonth = Month ; OldDay = Day ; DiffYear = Year - 0 ; DiffMouth = Month - 1 ; while (DiffYear) { if (RTC_Determine_Leap_Year((DiffYear - 1))) { DiffDay += 366 ; } else { DiffDay += 365 ; } DiffYear -- ; } while (DiffMouth) { switch (DiffMouth + 1) { case 1 : case 3 : case 5 : case 7 : case 8 : case 10: case 12: DiffDay += 31 ; break ; case 4 : case 6 : case 9 : case 11 : DiffDay += 30 ; break ; case 2 : if (RTC_Determine_Leap_Year(Year)) { DiffDay += 29 ; } else { DiffDay += 28 ; } break ; } DiffMouth -- ; } DiffDay += (Day - 1) ; DiffDay %= 7 ; DiffDay += DefaultWeek ; if (DiffDay > 7) { DiffDay -= 7 ; } u8Result = (uint8_t)DiffDay ; } return u8Result ; }