AnsweredAssumed Answered

RTC good accuracy design

Question asked by st_user1 on Dec 18, 2016
Latest reply on Dec 20, 2016 by FTITI.Walid

Hello my friends.

 

I want to design RTC board with best accuracy. My Mcu is STM32F103RB and it has Calibration option to enhance the Real Time Counter.

I know 2 paramaters are so important to design: 1. Crystal accuracy, 2.Environment Temperature.

About the first parameter i used the Tamper pin to check the signal frequency and i found the signal frequency is 512.006Hz. So, for this frequency i used calibration Value 12.

(512.006 - 512) / 512 * 10^6 = 11.71 ~ 12 -> 12 - 11.71 = 0.281.

About this calculation i must have the lost time about (0.281 * 86400 * 30) / 10^6 = 0.728 second per month. but after 12 days i have 12 second delay that it shows every day i have 1 second delay that means every month i have 30 seconds delay, according to the datasheet "STM32F101xx and STM32F103xx RTC calibration" this is the value of Crystal error without calibration.

This is my code to initialize RTC :

 

bool RTC_Init(void) {
      /* NVIC configuration */
      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 = 1;
      NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
      NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
      NVIC_Init(&NVIC_InitStructure);

      if (BKP_ReadBackupRegister(BKP_DR1) != 0xA5A5)
      {
            /* Backup data register value is not correct or not yet programmed (when
            the first time the program is executed) */

            /* RTC not yet configured.... */

            /* RTC Configuration */
            if (!RTC_Configuration())
                  return false;

            /* RTC configured.... */

            /* Adjust time by values entered by the user on the hyperterminal */
            RTC_Time_Adjust(defaultDate);

            BKP_WriteBackupRegister(BKP_DR1, 0xA5A5);
      }
      else
      {
      /* Check if the Power On Reset flag is set */
      if (RCC_GetFlagStatus(RCC_FLAG_PORRST) != RESET)
      {
            // Power On Reset occurred....
      }
      /* Check if the Pin Reset flag is set */
      else if (RCC_GetFlagStatus(RCC_FLAG_PINRST) != RESET)
      {
            // External Reset occurred....
      }

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

      RTC_getTodayDateTime(RTC_GetCounter());

      /* Enable the RTC Second */
      RTC_ITConfig(RTC_IT_SEC, ENABLE);
      /* Wait until last write operation on RTC registers has finished */
      RTC_WaitForLastTask();
   }

   #ifdef RTCClockOutput_Enable

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

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

   /* Disable the Tamper Pin */
   BKP_TamperPinCmd(DISABLE); /* To output RTCCLK/64 on Tamper pin, the tamper
   functionality must be disabled */

   /* Enable RTC Clock Output on Tamper Pin */
   BKP_RTCOutputConfig(BKP_RTCOutputSource_CalibClock);
   #endif

   /* Clear reset flags */
   RCC_ClearFlag();

   return true;
}

 

void RTC_SetTime(DATE date) {
   RTC_Configuration();
   RTC_Time_Adjust(date);
   BKP_WriteBackupRegister(BKP_DR1, 0xA5A5);
}


bool RTC_Configuration(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 */
   HAL_Delay(RTC_DELAY_SET_TIME_SEC * 1000);
   while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET){
         HAL_Delay(ERROR_SHOW_TIMER);
         return false;
   }

   /* 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();

   BKP_SetRTCCalibrationValue(12); /* ~512.006ppm*/

   return true;
}

 

is there something wrong in my initialization...?

 

and another question is how can i calibrate my MCU with both parameters of "Crystal accuracy and Environment Temperature" ...?

 

Thanks all.

Outcomes