Skip to main content
Scott Dev
Senior
December 15, 2018
Question

RTC running fast on STM32L433

  • December 15, 2018
  • 13 replies
  • 3704 views

Hi

I have setup the RTC on the STM32L433 and the clock is running about 5 second fast in 24 hours. I am using a 32.768KHz crystal, which is directly next to the processor . I have set the

RTC->PREDIV_A to 0x 7f, and RTC->PREDIV_A to 0x ff, and selected the LSE clock, cant think what it can be, anyone help?

Thanks

Scott

    This topic has been closed for replies.

    13 replies

    Tesla DeLorean
    Guru
    December 15, 2018

    Double check the measured frequency. Should be able to benchmark via a connected TIM, or if available on an MCO pin.

    Check loading, check trim settings.

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    Uwe Bonnes
    Chief
    December 15, 2018

    5 second in a day is about 60 ppm. Crystal tolerance is oftne 50 ppm plus some load capacitance mismatch and your number can be explained.

    Tesla DeLorean
    Guru
    December 15, 2018

    You can use TIM16

    Example here for measuring LSI here, but can select LSE

    STM32Cube_FW_L4_V1.13.0\Projects\NUCLEO-L432KC\Examples\RTC\RTC_LSI\Src\main.c

    The math here is broken, destroys accuracy

      /* Frequency computation */

      uwLsiFreq = (uint32_t) SystemCoreClock / uwPeriodValue;

      uwLsiFreq *= 8;

    Use

      uwLsiFreq = (SystemCoreClock * 8) / uwPeriodValue;

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    Scott Dev
    Scott DevAuthor
    Senior
    December 16, 2018

    Thanks Clive.

    I will have to download the examples, do I have to install the latest cubemx , which wil instalkl the examples?

    Scott

    Tesla DeLorean
    Guru
    December 16, 2018

    They should be in the repository if you have previously installed the L4 libraries. You can alternately pull the CubeL4 ZIP file an unpack and use that.

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    Peter Mather
    Associate III
    December 16, 2018

    Use HAL_RTCEx_SetSmoothCalib to tune the frequency. Here is my clock set up. Note Prediv setting are different to allow sub second reading

    The calibration value (Option.RTC_calibrate in my code) can be between -511 and + 512. n specifies the number of extra clock pulses to be "created" or "removed" every 2^20 real clock pulses. If my maths are correct therefore a change of +/-1 should equate to about 0.0824 seconds per day.

    /* RTC init function */
    static void myMX_RTC_Init(void)
    {
    int up=RTC_SMOOTHCALIB_PLUSPULSES_RESET;
    int calibrate= -Option.RTC_Calibrate;
     /* USER CODE BEGIN RTC_Init 0 */
     
     /* USER CODE END RTC_Init 0 */
     
     RTC_TimeTypeDef sTime;
     RTC_DateTypeDef sDate;
     
     /* USER CODE BEGIN RTC_Init 1 */
     
     /* USER CODE END RTC_Init 1 */
     
     /**Initialize RTC Only
     */
     hrtc.Instance = RTC;
     hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
     hrtc.Init.AsynchPrediv = 7;
     hrtc.Init.SynchPrediv = 4095;
     hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
     hrtc.Init.OutPutRemap = RTC_OUTPUT_REMAP_NONE;
     hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
     hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
     if (HAL_RTC_Init(&hrtc) != HAL_OK)
     {
     _Error_Handler(__FILE__, __LINE__);
     }
     if (HAL_RTC_GetTime(&hrtc, &sTime, RTC_FORMAT_BIN) != HAL_OK)
     {
     _Error_Handler(__FILE__, __LINE__);
     }
     
     if (HAL_RTC_GetDate(&hrtc, &sDate, RTC_FORMAT_BIN) != HAL_OK)
     {
     _Error_Handler(__FILE__, __LINE__);
     }
     RtcGetTime();
     if(sDate.Year<18){
     
     /**Initialize RTC and set the Time and Date
     */
    	 sTime.Hours = 0x0;
    	 sTime.Minutes = 0x0;
    	 sTime.Seconds = 0x0;
    	 sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
    	 sTime.StoreOperation = RTC_STOREOPERATION_RESET;
    	 if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD) != HAL_OK)
    	 {
    		 _Error_Handler(__FILE__, __LINE__);
    	 }
     
    	 sDate.WeekDay = RTC_WEEKDAY_MONDAY;
    	 sDate.Month = RTC_MONTH_JANUARY;
    	 sDate.Date = 0x1;
    	 sDate.Year = 0x0;
     
    	 if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BCD) != HAL_OK)
    	 {
    		 _Error_Handler(__FILE__, __LINE__);
    	 }
     }
     if(Option.RTC_Calibrate>0){
    	 up=RTC_SMOOTHCALIB_PLUSPULSES_SET;
    	 calibrate=512-Option.RTC_Calibrate;
     }
     HAL_RTCEx_SetSmoothCalib(&hrtc, RTC_SMOOTHCALIB_PERIOD_32SEC, up, calibrate);
     
    }

    Scott Dev
    Scott DevAuthor
    Senior
    December 16, 2018

    Thanks Peter

    I will look into this. I am only using the 32.768KHz as the external crystal, what does it calibrate it against? Wouldnt it need a known frequency to calibrate against?

    Scott

    Tesla DeLorean
    Guru
    December 16, 2018

    Typically an HSE supplied source, or you measuring it via MCO pin output on a test fixture.

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    Peter Mather
    Associate III
    December 16, 2018

    "Wouldnt it need a known frequency to calibrate against?"

    The real world :)

    "the clock is running about 5 second fast in 24 hours"

    You would start with a value of -5/0.0824  = -61

    this converts to

    HAL_RTCEx_SetSmoothCalib(&hrtc, RTC_SMOOTHCALIB_PERIOD_32SEC, RTC_SMOOTHCALIB_PLUSPULSES_RESET, 61);

    I you were 5 seconds slow it would be

    HAL_RTCEx_SetSmoothCalib(&hrtc, RTC_SMOOTHCALIB_PERIOD_32SEC, RTC_SMOOTHCALIB_PLUSPULSES_SET, 512-61);

    Scott Dev
    Scott DevAuthor
    Senior
    December 16, 2018

    Thanks everyone for your help. I am still learning parts of the stm32, and never new about the MCO pin, and the SetSmoothCalib (I only use the HAL for initilialisation then use the registers). Looking at the processor I am using , the MCO pin seems to be on PA8, which unfortunatly I dont use (I will have to make sure my other boards has this going to a pad for testing). I then can measure the correct frequency. I assume if I have x amount of boards with one design, and components the same, then I should only really have to do this on one board and the rest should (well, approx) be the same?

    One thing, I dont have any load capacitors on the crystal. The dev board I started on didnt, so I assumed this is the way to go. Is this correct?

    Thanks again, I will look into these.:thumbs_up:

    waclawek.jan
    Super User
    December 16, 2018

    > SetSmoothCalib (I only use the HAL for initilialisation then use the registers)

    HAL is open source so you can look at that function. Its sole purpose is to write concatenation of the input parameters to RTC_CALR register. Before doing so it performs the usual RTC unlock and checks for RECALPF flag (which would be set only if previous write to the same register would have occurred closer than 3 ticks of the synchronous part of RTC counter).

    Read the RTC smooth digital calibration subchapter in RM.

    > One thing, I dont have any load capacitors on the crystal. The dev board I started on didnt, so I assumed this is the way to go. Is this correct?

    It's not impossible that the tracks capacitances are enough, but it also may be the source of the deviation. Don't be afraid to experiment, a few pF at a time. And don't forget to read AN2867.

    JW

    sarp daltaban
    Associate II
    October 23, 2019

    I have the same exact problem using STM32F413VGTX.

    5 secs per 24 hours.

    Have you found a solution so far?

    Bests

    VaZso
    Associate III
    December 20, 2020

    I have recently ran into this issue, so I had to find out how this works as data sheet does not really provide much information.

    I am using an STM32F4 series MCU.

    First of all, I have a 32 kHz quartz, so at first, the two dividers are have to set correctly for being in the correct range.

    Basically, it can add 1 pulse per 2^11 clock cycles if "RTC_SMOOTHCALIB_PLUSPULSES" is set.

    Also, it can subtract given pulses in the specified "smoothcalib" period, which is 32 seconds for me.

    So, I have a quartz with a 32768 theoretical frequency.

    It provides 1048576 pulses per the 32 seconds period where it can generate 512 additional pulses based on 2^11 per 1 cycle during this 32 seconds period.

    Generally, it does not really make sence, but the 512 pulses written above comes from here.

    That means, it you enable plus impulses and subtract 512 pulses, then it behaves if you were not doing anything, so by decreasing 512, the clock will receive more and more pulses, thus, it will be faster than original state.

    In this 32 seconds period, it can subtract up to 32767 pulses, which means the clock can be adjusted about +42 to - 2700 seconds per day.

    Also, in a whole day, 32 seconds are exactly happen 2700 times.

    Thus, it can subtract n*2700/32768 seconds per day, where n is the value can be given to subtract as "SmouthCalibMinusPulsesValue" parameter.

    That means the modification of this value by +-1 will have a theoretical effect of +-0.0823974609375 seconds per day.

    So, here is the number written above comes from.

    Sorry if I wrote something you knew, just wanted to make it more clear.

    Also, what I have ran into second time is the HAL-generated RTC initialization code still halts the RTC clock for some hundred milliseconds by every restart, so the clock will be behind more than it should depending on the number of restarts.

    So a check is also needed to ensure unnecessary initialization when RTC clock is running.