cancel
Showing results for 
Search instead for 
Did you mean: 

How to use the RTC in STM32 microcontrollers for periodic wake-up and elapsed time calculation

Sarra.S
ST Employee

Introduction 

The real-time clock (RTC) can be used as a source to periodically wake-up the microcontroller, perform necessary tasks, and then return to low-power mode. Furthermore, the RTC can be used to calculate the elapsed time while the microcontroller is in stop mode, which can be useful for measuring the duration of tasks performed after waking up.

This article describes how to use an RTC to determine elapsed time and as a wake-up source. 

1. Prerequisites

1.1. Hardware: 

1.2. Software: 

2. The RTC wake-up timer

The RTC wake-up timer is a feature that allows the RTC to generate an interrupt after a specified interval to wake-up the microcontroller from low-power modes. The wake-up timer value is based on the RTC clock source and the selected wake-up clock divider.

3. Elapsed time calculation

The RTC can also be used to calculate the elapsed time while the microcontroller is in stop mode. The elapsed time is calculated by capturing the time before entering stop mode and after waking up. 

4. STM32CubeMX configuration 

4.1. RTC Configuration 

For this example, we’ll configure the RTC to wake-up the system every 5 seconds, and calculate the elapsed time.

Start a new project in STM32CubeMX, choosing the NUCLEO-U575ZI-Q in the board selector.

To activate the RTC, in the timers tab, configure the RTC clock source as follows:

  • Click [Activate Clock Source] 
  • In [WakeUp], select [Internal WakeUp], as we won’t be using an external pin as a wake-up signal

RTC configurationRTC configuration

 

The RTC (real-time clock) in STM32 microcontrollers requires a 1 Hz clock to keep accurate time. Its clock source derives from various sources such as LSE (Low-Speed external), LSI (Low-Speed internal), or HSE (High-Speed external) divided by 32. The prescalers are used to divide the input clock down to 1 Hz.

In this example, we use the internal LSI clock as the RTC clock source. Considering the LSI oscillator, which runs at 32,768 Hz, to achieve a 1 Hz clock for the RTC, we need to divide the 32 kHz clock to 1. 

So, in the parameters settings tab, set: 

The asynchronous prescaler to 127 (to divide the input clock by 128 (127+1)): It helps balance power consumption and the accuracy of the RTC.

The synchronous prescaler to 255 (to divide the input clock by 256 (255+1)): It’s necessary for accurate timekeeping. 

For the wake-up configuration, we have three parameters: 

Wake-up clock: Determines the interval after which the wake-up timer interrupt is generated.

Wake-up counter: Determines the frequency at which the wake-up counter is decremented.

Wake-up auto clr: Automatically clears the wake-up timer counter after the wake-up event.

For this example, the RTC clock is divided by 16, the wake-up counter is set to 0x2805, and the wake-up auto clr is set to 0. 

The value of the wake-up counter is calculated accordingly to achieve the 5 second wake-up interval. 

  • Enable the RTC interrupt 

RTC Interrupt EnableRTC Interrupt Enable

4.2. GPIO configuration 

In this example, we'll be using an LED (PA5) to indicate the wake-up event and another LED to indicate an error (PB7). Configure these pins in the GPIO configuration.

  • GPIO configurationGPIO configurationGenerate the code

4.3. Code configuration 

In private functions prototypes, add the function prototype of the elapsed time calculation 

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_RTC_Init(void);
uint32_t GetElapsedTime(RTC_TimeTypeDef start, RTC_TimeTypeDef end); 

Capture the start time before entering low-power mode.

// Capture the start time
  HAL_RTC_GetTime(&hrtc, &startTime, RTC_FORMAT_BIN);

Set the wake-up timer to 10,245 ticks (5 seconds) and enter low-power mode (stop mode).

HAL_SuspendTick();
HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, 0x2805, RTC_WAKEUPCLOCK_RTCCLK_DIV16, 0);
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);

Deactivate the wake-up timer after waking up and reconfigure the system clock.

HAL_RTCEx_DeactivateWakeUpTimer(&hrtc);
SystemClock_Config();
HAL_ResumeTick();

Capture the end time after waking up from low-power mode and calculate the elapsed time using the GetElapsedTime function.

HAL_RTC_GetTime(&hrtc, &endTime, RTC_FORMAT_BIN);
uint32_t elapsedTime = GetElapsedTime(startTime, endTime);

 Implement the elapsed time calculation function.

uint32_t GetElapsedTime(RTC_TimeTypeDef start, RTC_TimeTypeDef end) {
    uint32_t start_seconds = start.Hours * 3600 + start.Minutes * 60 + start.Seconds;
    uint32_t end_seconds = end.Hours * 3600 + end.Minutes * 60 + end.Seconds;
    return (end_seconds - start_seconds);
}

Implement the HAL_RTCEx_WakeUpTimerEventCallback function to handle the wake-up event.

void HAL_RTCEx_WakeUpTimerEventCallback(RTC_HandleTypeDef *hrtc) {
    HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
    __HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(hrtc, RTC_FLAG_WUTF);
}

Implement the Error_Handler function to handle errors.

void Error_Handler(void)
{
  __disable_irq();
  while (1)
  {
    HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_7);
  }
}

By following these steps, you can configure the RTC as a wake-up source and calculate the elapsed time while the MCU is in stop mode.

Related links

Version history
Last update:
‎2024-11-26 08:15 AM
Updated by: