cancel
Showing results for 
Search instead for 
Did you mean: 

RTC is running extremely slowly (3 times too slow)

Heinz_Baumer
Associate III

Hello.

 

I'm having a problem with an STM32H503.

I need to use the RTC, which is running on the internal 32kHz LSI clock.

The clock configuration was created with CubeMX.

 

When I check the RTC, I see that it has only advanced by 21 seconds in 60 seconds. That's a deviation of 285%.

The processor is running on the HSI clock, which is divided by 2, so 32MHz.

Does anyone know why the RTC is running 3 times too slow?

 

Init of the RCC:

    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_LSI;
    RCC_OscInitStruct.HSIState            = RCC_HSI_ON;
    RCC_OscInitStruct.HSIDiv              = RCC_HSI_DIV2;
    RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
    RCC_OscInitStruct.LSIState            = RCC_LSI_ON;
    RCC_OscInitStruct.PLL.PLLState        = RCC_PLL_NONE; // RCC_PLL_OFF;

    if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
    {
        Error_Handler();
    }

    /** Initializes the CPU, AHB and APB buses clocks
     */
    RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
                                  | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2
                                  | RCC_CLOCKTYPE_PCLK3;
    RCC_ClkInitStruct.SYSCLKSource   = RCC_SYSCLKSOURCE_HSI;
    RCC_ClkInitStruct.AHBCLKDivider  = RCC_SYSCLK_DIV1;
    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
    RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
    RCC_ClkInitStruct.APB3CLKDivider = RCC_HCLK_DIV1;

    if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
    {
        Error_Handler();
    }

 

Init of the RTC:

    hrtc.Instance            = RTC;
    hrtc.Init.HourFormat     = RTC_HOURFORMAT_24;
    hrtc.Init.AsynchPrediv   = 127;
    hrtc.Init.SynchPrediv    = 999; // 255;
    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;
    hrtc.Init.OutPutPullUp   = RTC_OUTPUT_PULLUP_NONE;
    hrtc.Init.BinMode        = RTC_BINARY_NONE;
    if (HAL_RTC_Init(&hrtc) != HAL_OK)
    {
        Error_Handler();
    }
    privilegeState.rtcPrivilegeFull         = RTC_PRIVILEGE_FULL_NO;
    privilegeState.backupRegisterPrivZone   = RTC_PRIVILEGE_BKUP_ZONE_NONE;
    privilegeState.backupRegisterStartZone2 = RTC_BKP_DR0;
    privilegeState.backupRegisterStartZone3 = RTC_BKP_DR0;
    if (HAL_RTCEx_PrivilegeModeSet(&hrtc, &privilegeState) != HAL_OK)
    {
        Error_Handler();
    }

    /** Enable the WakeUp
      * should be 100ms
     */
    if (HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, (100) , RTC_WAKEUPCLOCK_RTCCLK_DIV16, 0) != HAL_OK)
    {
        Error_Handler();
    }

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
waclawek.jan
Super User

If you increase the prescaler cca 3x, the counter is going to run cca 3x slower

 hrtc.Init.SynchPrediv    = 999; // 255;

Okay, it's more like 4x, but the point is the same. LSI is very imprecise, that explains the 3x/4x difference.

JW

View solution in original post

3 REPLIES 3
waclawek.jan
Super User

If you increase the prescaler cca 3x, the counter is going to run cca 3x slower

 hrtc.Init.SynchPrediv    = 999; // 255;

Okay, it's more like 4x, but the point is the same. LSI is very imprecise, that explains the 3x/4x difference.

JW

Heinz_Baumer
Associate III

Thank you.
I've tryed to get milliseconds resolution with the RTC

waclawek.jan
Super User

Well, you can, but if you still want the RTC itself to measure real time (at least roughly), you have to change the asynchronous prescaler's value simultaneously with the synchronous one, so that multiplying them (after adding 1) results in the oscillator's frequency. Say the LSI runs at 40kHz, so you have to set the asynchronouos prescaler to 40-1 while synchronous to 1000-1.

With a precise 32.768kHz LSE you can't achieve exact 1ms, though. With LSI, the result is as imprecise as LSI itself is.

JW