cancel
Showing results for 
Search instead for 
Did you mean: 

RTC good accuracy design

st_user1
Associate
Posted on December 18, 2016 at 20:25

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.

1 REPLY 1
Walid FTITI_O
Senior II
Posted on December 20, 2016 at 11:03

H

i

r

Tadayoni.S.Moham

,

To find response to your question, I recommend that you refer to the application note

http://www.st.com/content/ccc/resource/technical/document/application_note/ff/c1/4f/86/4e/29/42/d1/CD00167pdf/files/CD00167pdf/jcr:content/translations/en.CD00167pdf

. For code related check , you would refer to the ready-to-use example inside the standard library (or Hal library if you would to migrate to the the STM32cube ).

-Walid F'