RTC.c 5.39 KB
Newer Older
hu's avatar
hu committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251

#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 ;
}