<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          stm32的RTC操作

          作者: 時(shí)間:2016-12-03 來(lái)源:網(wǎng)絡(luò) 收藏
          分為兩個(gè)文件:
          rtc.c

          /*******************************************************************************
          * 文件名 :rtc.c
          * 描述 :wit_yuan
          * 論壇 :
          **********************************************************************************/
          #include "rtc.h"
          #include "stdio.h"
          #include "misc.h"
          uint8_t const *WEEK_STR[] = {"日", "一", "二", "三", "四", "五", "六"};
          uint8_t const *zodiac_sign[] = {"豬", "鼠", "牛", "虎", "兔", "龍", "蛇", "馬", "羊", "猴", "雞", "狗"};

          /* 秒中斷標(biāo)志,進(jìn)入秒中斷時(shí)置1,當(dāng)時(shí)間被刷新之后清0 */
          __IO uint32_t TimeDisplay;
          extern struct rtc_time systemtime;
          /*
          * 函數(shù)名:NVIC_Configuration
          * 描述 :配置RTC秒中斷的主中斷優(yōu)先級(jí)為1,次優(yōu)先級(jí)為0
          * 輸入 :無(wú)
          * 輸出 :無(wú)
          * 調(diào)用 :外部調(diào)用
          */
          void RTC_NVIC_Configuration(void)
          {
          NVIC_InitTypeDef NVIC_InitStructure;

          /* Configure one bit for preemption priority */
          NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

          /* Enable the RTC Interrupt */
          NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;
          NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
          NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
          NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
          NVIC_Init(&NVIC_InitStructure);
          }

          /*
          * 函數(shù)名:RTC_Configuration
          * 描述 :配置RTC
          * 輸入 :無(wú)
          * 輸出 :無(wú)
          * 調(diào)用 :外部調(diào)用
          */
          void RTC_Configuration(void)
          {
          RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
          PWR_BackupAccessCmd(ENABLE);
          BKP_DeInit();
          RCC_LSEConfig(RCC_LSE_ON);
          while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
          {}
          RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
          RCC_RTCCLKCmd(ENABLE);
          RTC_WaitForSynchro();
          RTC_WaitForLastTask();
          RTC_ITConfig(RTC_IT_SEC, ENABLE);
          RTC_WaitForLastTask();
          RTC_SetPrescaler(32767);
          RTC_WaitForLastTask();
          }

          /*
          * 函數(shù)名 :Time_Regulate
          * 描述 :返回用戶在超級(jí)終端中輸入的時(shí)間值,并將值儲(chǔ)存在
          * RTC 計(jì)數(shù)寄存器中。
          * 輸出 :用戶在超級(jí)終端中輸入的時(shí)間值,單位為 s
          * 調(diào)用 :內(nèi)部調(diào)用
          * editted : 2014-07-05
          * author : wit_yuan
          */
          extern struct rtc_time systemtime;

          uint32_t Time_Regulate(struct rtc_time *tm)
          {
          tm->tm_year = systemtime.tm_year + 2000;
          tm->tm_mon = systemtime.tm_mon;
          tm->tm_mday = systemtime.tm_mday;
          tm->tm_hour = systemtime.tm_hour;
          tm->tm_min = systemtime.tm_min;
          tm->tm_sec = systemtime.tm_sec;
          /* Return the value to store in RTC counter register */
          return(((systemtime.tm_hour) * 3600 + (systemtime.tm_min) * 60 + systemtime.tm_sec));
          }


          /*
          * 函數(shù)名:Time_Adjust
          * 描述 :時(shí)間調(diào)節(jié)
          * 輸入 :無(wú)
          * 輸出 :無(wú)
          * 調(diào)用 :外部調(diào)用
          */
          void Time_Adjust(struct rtc_time *tm)
          {
          /* Wait until last write operation on RTC registers has finished */
          RTC_WaitForLastTask();
          /* Get time entred by the user on the hyperterminal */
          Time_Regulate(tm);

          /* Get wday */
          GregorianDay(tm);
          /* Change the current time */
          RTC_SetCounter(mktimev(tm));
          /* Wait until last write operation on RTC registers has finished */
          RTC_WaitForLastTask();
          }


          /*
          * 函數(shù)名:Time_Display
          * 描述 :顯示當(dāng)前時(shí)間值
          * 輸入 :-TimeVar RTC計(jì)數(shù)值,單位為 s
          * 輸出 :無(wú)
          * 調(diào)用 :內(nèi)部調(diào)用
          */
          void Time_Display(uint32_t TimeVar,struct rtc_time *tm)
          {
          volatile uint32_t THH = 0, TMM = 0, TSS = 0;
          uint32_t BJ_TimeVar;
          /*把標(biāo)準(zhǔn)時(shí)間轉(zhuǎn)換為北京時(shí)間*/
          BJ_TimeVar =TimeVar + 8*60*60;

          to_tm(BJ_TimeVar, tm);/*把定時(shí)器的值轉(zhuǎn)換為北京時(shí)間*/
          }
          /*
          * 函數(shù)名:Time_Show
          * 描述 :在超級(jí)終端中顯示當(dāng)前時(shí)間值
          * 輸入 :無(wú)
          * 輸出 :無(wú)
          * 調(diào)用 :外部調(diào)用
          */
          void Time_Show(void)
          {

          }


          uint8_t USART_Scanf(uint32_t value)
          {
          uint32_t index = 0;
          uint32_t tmp[2] = {0, 0};

          while (index < 2)
          {
          while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET)
          {}
          tmp[index++] = (USART_ReceiveData(USART1));
          if ((tmp[index - 1] < 0x30) || (tmp[index - 1] > 0x39))
          {
          index--;
          }
          }
          index = (tmp[1] - 0x30) + ((tmp[0] - 0x30) * 10);
          if (index > value)
          {
          return 0xFF;
          }
          return index;
          }

          void Time_Config(struct rtc_time *tm)
          {
          if (BKP_ReadBackupRegister(BKP_DR1) != 0xA5A5)
          {
          RTC_Configuration();
          Time_Adjust(tm);
          BKP_WriteBackupRegister(BKP_DR1, 0xA5A5);
          }
          else
          {
          if (RCC_GetFlagStatus(RCC_FLAG_PORRST) != RESET)
          {
          }
          else if (RCC_GetFlagStatus(RCC_FLAG_PINRST) != RESET)
          {
          }
          RTC_WaitForSynchro();

          RTC_ITConfig(RTC_IT_SEC, ENABLE);

          RTC_WaitForLastTask();
          }
          #ifdef RTCClockOutput_Enable
          RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
          PWR_BackupAccessCmd(ENABLE);
          BKP_TamperPinCmd(DISABLE);
          BKP_RTCOutputConfig(BKP_RTCOutputSource_CalibClock);
          #endif
          RCC_ClearFlag();
          //Time_Show();
          }

          /*********************************************************
          * funciton : drv_set_time
          * description : set the rtc time
          * time : 2015-08-22 pm
          * author : wit_yuan
          ***********************************************************/
          void drv_set_time(struct rtc_time *tm)
          {
          RTC_Configuration();
          Time_Adjust(tm);
          BKP_WriteBackupRegister(BKP_DR1, 0xA5A5);
          RCC_ClearFlag();
          }

          /*********************************************************
          * funciton : wit_get_time
          * description : get the rtc time
          * time : 2015-07-07 am
          * author : wit_yuan
          ***********************************************************/

          void drv_get_time(struct rtc_time *tm)
          {
          uint32_t TimeVar;
          //struct rtc_time tm;
          uint32_t BJ_TimeVar;
          TimeVar = RTC_GetCounter();
          *tm = systemtime;
          BJ_TimeVar =TimeVar + 8 * 60 * 60;
          to_tm(BJ_TimeVar, tm);/*把定時(shí)器的值轉(zhuǎn)換為北京時(shí)間*/
          // printf("%d年%d月%d日 %d時(shí)%d分%d秒 n",tm.tm_year,tm.tm_mon,tm.tm_mday,tm.tm_hour,tm.tm_min,tm.tm_sec);
          // return tm;
          }



          void RTC_IRQHandler(void)
          {
          if (RTC_GetITStatus(RTC_IT_SEC) != RESET)
          {
          RTC_ClearITPendingBit(RTC_IT_SEC);
          TimeDisplay = 1;
          if (TimeDisplay == 1)
          {
          TimeDisplay = 0;
          }
          RTC_WaitForLastTask();
          }
          }


          void init_rtc(void )
          {
          RTC_NVIC_Configuration();
          Time_Config(&systemtime);
          }


          /*****************************END OF FILE****2015-08-23 guide by wit_yuan**************************/

          本文引用地址:http://www.ex-cimer.com/article/201612/325188.htm
          2、date.c

          #include "date.h"

          #define FEBRUARY 2
          #define STARTOFTIME 1970
          #define SECDAY 86400L
          #define SECYR (SECDAY * 365)
          #define leapyear(year) ((year) % 4 == 0)
          #define days_in_year(a) (leapyear(a) ? 366 : 365)
          #define days_in_month(a) (month_days[(a) - 1])

          static int month_days[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

          /*
          * This only works for the Gregorian calendar - i.e. after 1752 (in the UK)
          */
          /*計(jì)算公歷*/
          void GregorianDay(struct rtc_time * tm)
          {
          int leapsToDate;
          int lastYear;
          int day;
          int MonthOffset[] = { 0,31,59,90,120,151,181,212,243,273,304,334 };

          lastYear=tm->tm_year-1;

          /*計(jì)算從公元元年到計(jì)數(shù)的前一年之中一共經(jīng)歷了多少個(gè)閏年*/
          leapsToDate = lastYear/4 - lastYear/100 + lastYear/400;
          /*如若計(jì)數(shù)的這一年為閏年,且計(jì)數(shù)的月份在2月之后,則日數(shù)加1,否則不加1*/
          if((tm->tm_year%4==0) &&
          ((tm->tm_year%100!=0) || (tm->tm_year%400==0)) &&
          (tm->tm_mon>2)) {
          /*
          * We are past Feb. 29 in a leap year
          */
          day=1;
          } else {
          day=0;
          }
          day += lastYear*365 + leapsToDate + MonthOffset[tm->tm_mon-1] + tm->tm_mday ; /*計(jì)算從公元元年元旦到計(jì)數(shù)日期一共有多少天*/

          tm->tm_wday=day%7;
          }

          /* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
          * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
          * => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
          *
          * [For the Julian calendar (which was used in Russia before 1917,
          * Britain & colonies before 1752, anywhere else before 1582,
          * and is still in use by some communities) leave out the
          * -year/100+year/400 terms, and add 10.]
          *
          * This algorithm was first published by Gauss (I think).
          *
          * WARNING: this function will overflow on 2106-02-07 06:28:16 on
          * machines were long is 32-bit! (However, as time_t is signed, we
          * will already get problems at other places on 2038-01-19 03:14:08)

          *ADD by fire:本函數(shù)在工程中的輸入?yún)?shù)為北京時(shí)間,
          所以在轉(zhuǎn)換成時(shí)間戳?xí)r最后要從北京時(shí)間轉(zhuǎn)換為標(biāo)準(zhǔn)時(shí)間的時(shí)間戳
          */
          u32 mktimev(struct rtc_time *tm)
          {
          if (0 >= (int) (tm->tm_mon -= 2)) { /* 1..12 -> 11,12,1..10 */
          tm->tm_mon += 12; /* Puts Feb last since it has leap day */
          tm->tm_year -= 1;
          }

          return (((
          (u32) (tm->tm_year/4 - tm->tm_year/100 + tm->tm_year/400 + 367*tm->tm_mon/12 + tm->tm_mday) +
          tm->tm_year*365 - 719499
          )*24 + tm->tm_hour /* now have hours */
          )*60 + tm->tm_min /* now have minutes */
          )*60 + tm->tm_sec-8*60*60; /* finally seconds */
          /*Add by fire: -8*60*60 把輸入的北京時(shí)間轉(zhuǎn)換為標(biāo)準(zhǔn)時(shí)間,
          再寫(xiě)入計(jì)時(shí)器中,確保計(jì)時(shí)器的數(shù)據(jù)為標(biāo)準(zhǔn)的UNIX時(shí)間戳*/
          }

          void to_tm(u32 tim, struct rtc_time * tm)
          {
          register u32 i;
          register long hms, day;

          day = tim / SECDAY;
          hms = tim % SECDAY;
          /* Hours, minutes, seconds are easy */
          tm->tm_hour = hms / 3600;
          tm->tm_min = (hms % 3600) / 60;
          tm->tm_sec = (hms % 3600) % 60;
          /* Number of years in days */ /*算出當(dāng)前年份,起始的計(jì)數(shù)年份為1970年*/
          for (i = STARTOFTIME; day >= days_in_year(i); i++) {
          day -= days_in_year(i);
          }
          tm->tm_year = i;
          /* Number of months in days left */ /*計(jì)算當(dāng)前的月份*/
          if (leapyear(tm->tm_year)) {
          days_in_month(FEBRUARY) = 29;
          }
          for (i = 1; day >= days_in_month(i); i++) { //程序編寫(xiě)時(shí)間是2013年8月
          day -= days_in_month(i);
          }
          days_in_month(FEBRUARY) = 28;
          tm->tm_mon = i;
          /* Days are what is left over (+1) from all that. *//*計(jì)算當(dāng)前日期*/
          tm->tm_mday = day + 1;//+ 1; //2013年8月3日修改,實(shí)現(xiàn)功能
          /*
          * Determine the day of week
          */
          GregorianDay(tm);

          }

          對(duì)外接口:
          函數(shù):init_rtc(),drv_set_time(),drv_get_time().
          變量:extern struct rtc_time systemtime;


          關(guān)鍵詞: stm32RTC操

          評(píng)論


          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();