2024-11-21 05:14 AM - edited 2024-11-26 08:15 AM
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.
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.
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.
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:
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.
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.
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.