<rtc.h> #include "stm32f10x.h" #ifndef _RTC_H #define _RTC_H typedef struct { vu8 hour; vu8 mintue; vu8 second; vu16 year; vu8 month; vu8 day; vu8 week; }_calendar_obj; // extern _calendar_obj Calendar; u8 RTC_Init(void); u8 Is_Leap_Year(u16 _year); _calendar_obj RTC_GetCalendar(void); u8 RTC_GetWeek(u16 _year,u8 _month,u8 _day); u8 RTC_SetCalendar(u16 _year,u8 _month,u8 _day,u8 _hour,u8 _min,u8 _second); #endif <rtc.c> #include "rtc.h" const u8 month_table[]={31,28,31,30,31,30,31,31,30,31,30,31}; const u8 week_table[]={0,3,3,6,1,4,6,2,5,0,3,5}; _calendar_obj Calendar; void delay_ms(u16 time) { u16 i=0; while(time--) { i=12000; while(i--); } } u8 Is_Leap_Year(u16 _year) { if((_year%4 && _year%100!=0) | (_year%400==0)) return 0; else return 1; } u8 RTC_Init(void) { u16 temp=0; //enable RTC_CLK outside if(BKP_ReadBackupRegister(BKP_DR1)!=0x5050) { RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR|RCC_APB1Periph_BKP,ENABLE); PWR_BackupAccessCmd(ENABLE); BKP_DeInit(); RCC_LSEConfig(RCC_LSE_ON); while(RCC_GetFlagStatus(RCC_FLAG_HSERDY)==RESET) { temp++; delay_ms(10); } if(temp>250) return 0; RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); RCC_RTCCLKCmd(ENABLE); RTC_WaitForLastTask(); RTC_ITConfig(RTC_IT_SEC,ENABLE); RTC_WaitForLastTask(); RTC_SetPrescaler(32767); RTC_WaitForLastTask(); RTC_SetCalendar(2015,10,10,10,10,10); RTC_ExitConfigMode(); BKP_WriteBackupRegister(BKP_DR1,0x5050); } else { RTC_WaitForSynchro(); RTC_ITConfig(RTC_IT_SEC,ENABLE); RTC_WaitForLastTask(); } return 1; } _calendar_obj RTC_GetCalendar(void) { static u16 daycount=0; u32 timecount=RTC_GetCounter(); u32 daynum=timecount/86400; //day u16 temp=0; //Calendar year if(daycount!=daynum) //>1 { daycount=daynum; temp=1970; while(daynum>365) { if(Is_Leap_Year(temp)) { if(daynum>=366) daynum=daynum-366; else break; } else daynum=daynum-365; temp++; } Calendar.year=temp; // set year temp=0; //reset temp // Calendar month while(daynum>=28) { if(Is_Leap_Year(Calendar.year) && temp==1) { if(daynum>=29) daynum=daynum-29; else break; } else { if(daynum>=month_table[temp]) daynum=daynum-month_table[temp]; else break; } temp++; } Calendar.month=temp+1; //set month Calendar.day=daynum+1; //set day } daynum=timecount%86400; Calendar.hour=daynum/3600; //set hour Calendar.mintue=(daynum%3600)/60; //set mintue Calendar.second=(daynum%3600)%60; //set second return Calendar; } u8 RTC_SetCalendar(u16 _year,u8 _month,u8 _day,u8 _hour,u8 _min,u8 _second) { u16 i; u32 seccount=0; //second total if(_year<1970 || _year>2099) return 1; //valid year //calculate year for(i=1970;i<_year;i++) { if(Is_Leap_Year(i)) seccount=seccount+3600*24*366; //3600*24*366=31622400 else seccount=seccount+3600*24*365; //3600*24*365=31536000 } //calculate month _month=_month-1; for(i=0;i<_month;i++) { seccount=seccount+(u32)month_table[i]*3600*24; if(Is_Leap_Year(_year) && i==1) //February,add 1 day { seccount=seccount+3600*24; } } //calculate day seccount=seccount+(u32)(_day-1)*3600*24; seccount+=(u32)_hour*3600; seccount+=(u32)_min*60; seccount+=_second; //set Calendar RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR|RCC_APB1Periph_BKP,ENABLE); PWR_BackupAccessCmd(ENABLE); RTC_SetCounter(seccount); RTC_WaitForLastTask(); return 0; } u8 RTC_GetWeek(u16 _year,u8 _month,u8 _day) { u16 temp; u8 yearH,yearL; yearH=_year/100; // 2016/100=20 yearL=_year%100; // 2016%100=16 if(yearH>19) yearL+=100; temp=yearL+yearL/4; temp=temp+_day+week_table[_month-1]; if(yearL%4==0 && _month<3) temp=temp-1; return temp%7; }
时间: 2024-10-05 05:41:40