2025-04-16 6:30 AM
Hello everyone. While studying the RTC module on the STM32F103, I encountered a strange behavior of interrupts from the RTC module.
I configured two interrupts: every second - RTC_IRQn, and an interrupt on the alarm RTC_Alarm_IRQn. Additionally, I tried to change the priority of these interrupts.
RTC_HandleTypeDef hrtc;
RTC_TimeTypeDef sTime = { 0 };
RTC_DateTypeDef DateToUpdate = { 0 };
RTC_AlarmTypeDef sAlarm = { 0 };
void HAL_RTCEx_RTCEventCallback(RTC_HandleTypeDef *hrtc) {
HAL_RTC_GetTime(hrtc, &sTime, RTC_FORMAT_BIN);
HAL_RTC_GetDate(hrtc, &DateToUpdate, RTC_FORMAT_BIN);
printf("%d:%d:%d, %d-%d-20%d\r\n", sTime.Hours, sTime.Minutes,
sTime.Seconds, DateToUpdate.Date, DateToUpdate.Month,
DateToUpdate.Year);
}
void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc) {
printf("Alarm triggered\r\n");
//HAL_GPIO_WritePin(Alarm_GPIO_Port, Alarm_Pin, GPIO_PIN_SET);
}
void HAL_RTC_MspInit(RTC_HandleTypeDef* hrtc)
{
if(hrtc->Instance==RTC)
{
/* USER CODE BEGIN RTC_MspInit 0 */
/* USER CODE END RTC_MspInit 0 */
HAL_PWR_EnableBkUpAccess();
/* Enable BKP CLK enable for backup registers */
__HAL_RCC_BKP_CLK_ENABLE();
/* Peripheral clock enable */
__HAL_RCC_RTC_ENABLE();
/* RTC interrupt Init */
HAL_NVIC_SetPriority(RTC_IRQn, 10, 0);
HAL_NVIC_EnableIRQ(RTC_IRQn);
HAL_NVIC_SetPriority(RTC_Alarm_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(RTC_Alarm_IRQn);
/* USER CODE BEGIN RTC_MspInit 1 */
/* USER CODE END RTC_MspInit 1 */
}
}
while (1){
printf("I'm ok\r\n");
HAL_GPIO_TogglePin(LD2_GPIO_Port,LD2_Pin);
HAL_Delay(1000);
}
It turned out that if the RTC_Alarm_IRQn interrupt has a higher priority than the second interrupt, everything works fine except for a similar problem (STM32F103x strange behavior using HAL_RTC_GetTime() together with RTC interrupts).
But if the second interrupt has a higher priority than RTC_Alarm_IRQn, the RTC_Alarm_IRQn interrupt does not fire and remains in the NVIC module processing queue forever. Additionally, SysTick stops incrementing. I tried to increase SysTick priority to 0. But the behavior did not change. Only the second interrupt continues to be executed.
void HAL_RTC_MspInit(RTC_HandleTypeDef* hrtc)
{
if(hrtc->Instance==RTC)
{
/* USER CODE BEGIN RTC_MspInit 0 */
/* USER CODE END RTC_MspInit 0 */
HAL_PWR_EnableBkUpAccess();
/* Enable BKP CLK enable for backup registers */
__HAL_RCC_BKP_CLK_ENABLE();
/* Peripheral clock enable */
__HAL_RCC_RTC_ENABLE();
/* RTC interrupt Init */
HAL_NVIC_SetPriority(RTC_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(RTC_IRQn);
HAL_NVIC_SetPriority(RTC_Alarm_IRQn, 10, 0);
HAL_NVIC_EnableIRQ(RTC_Alarm_IRQn);
/* USER CODE BEGIN RTC_MspInit 1 */
/* USER CODE END RTC_MspInit 1 */
}
}
I reread the RM0008 document, but did not find anything indicating such behavior as mine. I assumed that the NVIC module should queue the alarm interrupt and then process it. But I do not even get into the alarm interrupt handler. It feels like such behavior can occur if the controller never exits the one-second interrupt. But I looked in the debugger and did not see any infinite loops or anything like that.
In which direction should I dig?