This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Back up battery for RTC of STM32F103RB

Dear friends,
I have a problem when reading counter register of RTC in STM32F103RB. After resetting the MCU, the value starts from zero. I have a 3V backup battery connected to VBAT pin. My code to config RTC is in below

void RTC_Config(void)
 {
/* Enable PWR and BKP clocks */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);

  /* Allow access to BKP Domain */
  PWR_BackupAccessCmd(ENABLE);

  /* Reset Backup Domain */
  BKP_DeInit();

  /* Enable LSE */
  RCC_LSEConfig(RCC_LSE_ON);
  /* Wait till LSE is ready */
  while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
  {}

  /* Select LSE as RTC Clock Source */
  RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);

  /* Enable RTC Clock */
  RCC_RTCCLKCmd(ENABLE);

  /* Wait for RTC registers synchronization */
  RTC_WaitForSynchro();

  /* Wait until last write operation on RTC registers has finished */
  RTC_WaitForLastTask();

  /* Enable the RTC Second */
  RTC_ITConfig(RTC_IT_SEC, ENABLE);

  /* Wait until last write operation on RTC registers has finished */
  RTC_WaitForLastTask();

  /* Set RTC prescaler: set RTC period to 1sec */
  RTC_SetPrescaler(32767); /* RTC period = RTCCLK/RTC_PR = (32.768 KHz)/(32767+1) */

  /* Wait until last write operation on RTC registers has finished */
  RTC_WaitForLastTask();
//----------------------------------------------------
 }


in main function:

rtc_val=RTC_GetCounter();

  • Solution:I missed to comment following lines

      /* Reset Backup Domain */
      //BKP_DeInit();
    
    
    Now RTC works fine!
    following is my complete code:
    
    
    //RTC.c
    #include "rtc.h"
    #include "main.h"
    #include "stm32f10x.h"
    #include "stm32f10x_rtc.h"
    #include <stdio.h>
    #include "math.h"
    #include <time.h>
     //---------------------------------------------------------------
    static struct skew
    {
      int8_t error;
      uint8_t ticks;
    } skew;
    
    /* The calendar "tm" structure from the standard libray "time.h" has the following definition: */
    //struct tm
    //{
    //      int tm_sec;         /* seconds,  range 0 to 59          */
    //      int tm_min;         /* minutes, range 0 to 59           */
    //      int tm_hour;        /* hours, range 0 to 23             */
    //      int tm_mday;        /* day of the month, range 1 to 31  */
    //      int tm_mon;         /* month, range 0 to 11             */
    //      int tm_year;        /* The number of years since 1900   */
    //      int tm_wday;        /* day of the week, range 0 to 6    */
    //      int tm_yday;        /* day in the year, range 0 to 365  */
    //      int tm_isdst;       /* daylight saving time             */
    //};
    
    struct tm calendar_time_cache;  // a cache of calendar time structure elements
    time_t unix_time_cache;                 // a cache of unix_time that was updated
    time_t time_zone_cache;                 // a cache of the time zone that was set
    
    /* Time utility functions */
    static struct tm Convert_UnixTime_To_CalendarTime(time_t unix_time);
    static time_t Convert_CalendarTime_To_UnixTime(struct tm calendar_time);
    static time_t Get_UnixTime(void);
    static struct tm Get_CalendarTime(void);
    static void Set_UnixTime(time_t unix_time);
    static void Set_CalendarTime(struct tm t);
    static void Refresh_UnixTime_Cache(time_t unix_time);
    
    //------------------------------------------------------------------------------------
    /* Convert Unix/RTC time to Calendar time */
    static struct tm Convert_UnixTime_To_CalendarTime(time_t unix_time)
    {
            struct tm *calendar_time;
            unix_time += time_zone_cache;
            calendar_time = localtime(&unix_time);
            calendar_time->tm_year += 1900;
            return *calendar_time;
    }
    
    /* Convert Calendar time to Unix/RTC time */
    static time_t Convert_CalendarTime_To_UnixTime(struct tm calendar_time)
    {
            calendar_time.tm_year -= 1900;
            time_t unix_time = mktime(&calendar_time);
            return unix_time;
    }
    
    /* Get Unix/RTC time */
    static time_t Get_UnixTime(void)
    {
            time_t unix_time = (time_t)RTC_GetCounter();
            return unix_time;
    }
    
    /* Get converted Calendar time */
    static struct tm Get_CalendarTime(void)
    {
            time_t unix_time = Get_UnixTime();
            unix_time += time_zone_cache;
            struct tm calendar_time = Convert_UnixTime_To_CalendarTime(unix_time);
            return calendar_time;
    }
    
    /* Set Unix/RTC time */
    static void Set_UnixTime(time_t unix_time)
    {
            RTC_WaitForLastTask();
            RTC_SetCounter((uint32_t)unix_time);
            RTC_WaitForLastTask();
    }
    
    /* Set Calendar time as Unix/RTC time */
    static void Set_CalendarTime(struct tm calendar_time)
    {
            Set_UnixTime(Convert_CalendarTime_To_UnixTime(calendar_time));
    }
    
    /* Refresh Unix/RTC time cache */
    static void Refresh_UnixTime_Cache(time_t unix_time)
    {
            if(unix_time != unix_time_cache)
            {
                    calendar_time_cache = Convert_UnixTime_To_CalendarTime(unix_time);
                    unix_time_cache = unix_time;
            }
    }
    //----------------------------------------------------------------------------------
    
    void set_time(struct tm calendar_time)
    {
    
      Set_CalendarTime(calendar_time);
    
    }
    
    struct tm get_time(void)
    {
    timestamp clock;
    uint32_t rtc_val;
    rtc_val=RTC_GetCounter();
    time_t rawtime=rtc_val;
    struct tm *info;
    /* Get GMT time */
    info = gmtime(&rawtime );
    return *info;
    }
    void RTC_Config(void)
     {
    /* Enable PWR and BKP clocks */
      RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
    
      /* Allow access to BKP Domain */
      PWR_BackupAccessCmd(ENABLE);
    
      /* Reset Backup Domain */
      //BKP_DeInit();
    
      /* Enable LSE */
      RCC_LSEConfig(RCC_LSE_ON);
      /* Wait till LSE is ready */
      while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
      {}
    
      /* Select LSE as RTC Clock Source */
      RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
    
      /* Enable RTC Clock */
      RCC_RTCCLKCmd(ENABLE);
    
      /* Wait for RTC registers synchronization */
      RTC_WaitForSynchro();
    
      /* Wait until last write operation on RTC registers has finished */
      RTC_WaitForLastTask();
    
      /* Enable the RTC Second */
      RTC_ITConfig(RTC_IT_SEC, ENABLE);
    
      /* Wait until last write operation on RTC registers has finished */
      RTC_WaitForLastTask();
    
      /* Set RTC prescaler: set RTC period to 1sec */
      RTC_SetPrescaler(32767); /* RTC period = RTCCLK/RTC_PR = (32.768 KHz)/(32767+1) */
    
      /* Wait until last write operation on RTC registers has finished */
      RTC_WaitForLastTask();
    //----------------------------------------------------
     }
    
    
    
    
    
       struct tm calendar_time;
       calendar_time.tm_sec=1;
       calendar_time.tm_min=1;
       calendar_time.tm_hour=15;
       calendar_time.tm_mday=21;
       calendar_time.tm_mon=5;
       calendar_time.tm_year=2016;
       set_time(calendar_time);
    
    
    while(1) { rtc=get_time(); sprintf(str,"%.2u:%.2u:%.2u",(rtc.tm_year-100),rtc.tm_mon,rtc.tm_mday); lcd_first_row(); lcd_print(str); delay_ms(10); lcd_second_row(); sprintf(str,"%.2u:%.2u:%.2u",rtc.tm_hour,rtc.tm_min,rtc.tm_sec); lcd_print(str);
    }