STM32F103x strange behavior using HAL_RTC_GetTime() together with RTC interrupts (ALR and SEC flags)
- 2 replies
- 2958 views
Hello all,
I'm working on a project with the STM32F103C8T6 microcontroller, using STMCubeIDE STM32CubeIDE Version: 1.13.2, and the HAL STM32Cube FW 1.8.5. In the example program I've attached, I set an alarm for 00:00:00, and once the alarm interrupt triggers, I reprogram the alarm to go off again 20 seconds later.
I've obtained part of this example from the following website: https://medium.com/@jobenas_25464/power-management-and-rtc-alarms-in-stm32f103-d144a214cc40, and I've attempted some modifications, which I'll explain below.
In this project,attached below, I'm using the two interrupts provided by the RTC: the interrupt that occurs every second and the alarm interrupt (I also have the Timer 3 interrupt enabled for additional testing).
The interrupt priorities are set in the following order (from highest to lowest priority):
- SysTick interrupt.
- Alarm interrupt.
- Global RTC interrupt.
- Timer 3 interrupt.
I must clarify that the priority of the SysTick interrupt should be higher than any of the RTC interrupts since it is used as a time reference for calculating timeouts in various functions of the RTC module.

When I execute the HAL_RTC_GetTime() function inside the seconds callback, the alarm is triggered at the correct time, but it appears that during the interrupt handling process, one second is somehow lost. I'm trying to understand the reason behind this behavior, and it seems that the operations performed within the HAL_RTC_GetTime function might not be entirely appropriate when executed in this context.

void HAL_RTCEx_RTCEventCallback(RTC_HandleTypeDef *hrtc){
if(hrtc->Instance == RTC){
HAL_RTC_GetTime(hrtc, &now_Time, RTC_FORMAT_BIN);
(void)snprintf (message_buffer, (size_t)sizeof(message_buffer), "Current Hour %d:%d:%d\r\n", now_Time.Hours, now_Time.Minutes, now_Time.Seconds);
HAL_UART_Transmit(&huart1, (uint8_t *)message_buffer, strlen (message_buffer), HAL_MAX_DELAY);
secondsUpdate++;
seconds_flag = 1;
}
}
/* loop on main */
while (1)
{
if(seconds_flag ==1){
// HAL_RTC_GetTime(&hrtc, &now_Time, RTC_FORMAT_BIN);
// (void)snprintf (message_buffer, (size_t)sizeof(message_buffer), "Current Hour %d:%d:%d\r\n", now_Time.Hours, now_Time.Minutes, now_Time.Seconds);
// HAL_UART_Transmit(&huart1, (uint8_t *)message_buffer, strlen (message_buffer), HAL_MAX_DELAY);
seconds_flag =0;
}
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}Since I personally prefer not to run code within an interrupt, what I've done is set a flag to 1 when the second interrupt occurs, and in the while loop, I read the time and reset this flag to 0. In this case, the alarm interrupt doesn't trigger.

void HAL_RTCEx_RTCEventCallback(RTC_HandleTypeDef *hrtc){
if(hrtc->Instance == RTC){
// HAL_RTC_GetTime(hrtc, &now_Time, RTC_FORMAT_BIN);
// (void)snprintf (message_buffer, (size_t)sizeof(message_buffer), "Current Hour %d:%d:%d\r\n", now_Time.Hours, now_Time.Minutes, now_Time.Seconds);
// HAL_UART_Transmit(&huart1, (uint8_t *)message_buffer, strlen (message_buffer), HAL_MAX_DELAY);
secondsUpdate++;
seconds_flag = 1;
}
}
while (1)
{
if(seconds_flag ==1){
HAL_RTC_GetTime(&hrtc, &now_Time, RTC_FORMAT_BIN);
(void)snprintf (message_buffer, (size_t)sizeof(message_buffer), "Current Hour %d:%d:%d\r\n", now_Time.Hours, now_Time.Minutes, now_Time.Seconds);
HAL_UART_Transmit(&huart1, (uint8_t *)message_buffer, strlen (message_buffer), HAL_MAX_DELAY);
seconds_flag =0;
}
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}If I don't use the HAL_RTC_GetTime() function in either the callback or the while loop, the alarm seems it is triggered correctly, although I cannot determine if one second is being lost.
I would like to know if I'm doing something wrong, and if others are experiencing the same issue.
Does anyone have any idea of what might be happening? Could it be a bug in the HAL layer?
