硬汉嵌入式论坛

 找回密码
 立即注册
查看: 611|回复: 4
收起左侧

[RTC] RTC闹钟A中断以后,清除了中断标志,依然会一直触发中断?

[复制链接]

15

主题

23

回帖

68

积分

初级会员

积分
68
发表于 2023-8-8 15:37:33 | 显示全部楼层 |阅读模式


void RTC_Alarm_IRQHandler(void) 函数是A和B共同的中断函数,程序只初始化了闹钟A,通过寄存器可以查看配置成功了。
void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)  函数是闹钟A中断的回调函数,在这个函数体内部清除了A的中断标志,通过寄存器查看清除成功了。

现在实际运行的情况是:闹钟A没有触发之前,RTC_Alarm_IRQHandler函数不会触发,但是闹钟A一旦触发,RTC_Alarm_IRQHandler就会一直进入,第一次因为没有清除A的中断标志,HAL_RTC_AlarmAEventCallback会执行一次,然后就一直进入RTC_Alarm_IRQHandler而不进入HAL_RTC_AlarmAEventCallback。

请问大佬们,如果A的中断标志被清除了,且闹钟A没有产生中断,那么RTC_Alarm_IRQHandler这个函数不是应该不再进入了?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106847
QQ
发表于 2023-8-8 16:43:32 | 显示全部楼层
RTC的中断标志位都看下,一直进中断,说明一直有触发。

单步调试进去看下

[C] 纯文本查看 复制代码
void HAL_RTC_AlarmIRQHandler(RTC_HandleTypeDef *hrtc)
{
  /* Clear the EXTI's line Flag for RTC Alarm */
#if defined(DUAL_CORE)
  if(HAL_GetCurrentCPUID() == CM7_CPUID)
  {
    __HAL_RTC_ALARM_EXTI_CLEAR_FLAG();
  }
  else
  {
    __HAL_RTC_ALARM_EXTID2_CLEAR_FLAG();
  }
#else  /* SINGLE_CORE */
  __HAL_RTC_ALARM_EXTI_CLEAR_FLAG();
#endif /* DUAL_CORE */

#if defined(TAMP)
  /* Get interrupt status */
  uint32_t tmp = hrtc->Instance->MISR;

  if((tmp & RTC_FLAG_ALRAF) != 0u)
  {
    /* Clear the AlarmA interrupt pending bit */
    __HAL_RTC_ALARM_CLEAR_FLAG(hrtc, RTC_FLAG_ALRAF);

    /* Call Alarm A Callback */
#if (USE_HAL_RTC_REGISTER_CALLBACKS == 1)
    hrtc->AlarmAEventCallback(hrtc);
#else  /* (USE_HAL_RTC_REGISTER_CALLBACKS == 1) */
    HAL_RTC_AlarmAEventCallback(hrtc);
#endif /* (USE_HAL_RTC_REGISTER_CALLBACKS == 1) */
  }

  if((tmp & RTC_MISR_ALRBMF) != 0u)
  {
    /* Clear the AlarmB interrupt pending bit */
    hrtc->Instance->SCR = RTC_SCR_CALRBF;

    /* Call Alarm B Callback */
#if (USE_HAL_RTC_REGISTER_CALLBACKS == 1)
    hrtc->AlarmBEventCallback(hrtc);
#else  /* (USE_HAL_RTC_REGISTER_CALLBACKS == 1) */
    HAL_RTCEx_AlarmBEventCallback(hrtc);
#endif /* (USE_HAL_RTC_REGISTER_CALLBACKS == 1) */
  }
#else
  /* Get the AlarmA interrupt source enable status */
  if(__HAL_RTC_ALARM_GET_IT_SOURCE(hrtc, RTC_IT_ALRA) != 0U)
  {
    /* Get the pending status of the AlarmA Interrupt */
    if(__HAL_RTC_ALARM_GET_FLAG(hrtc, RTC_FLAG_ALRAF) != 0U)
    {
      /* Clear the AlarmA interrupt pending bit */
      __HAL_RTC_ALARM_CLEAR_FLAG(hrtc, RTC_FLAG_ALRAF);

#if (USE_HAL_RTC_REGISTER_CALLBACKS == 1)
      hrtc->AlarmAEventCallback(hrtc);
#else  /* (USE_HAL_RTC_REGISTER_CALLBACKS == 1) */
      HAL_RTC_AlarmAEventCallback(hrtc);
#endif /* (USE_HAL_RTC_REGISTER_CALLBACKS == 1) */
    }
  }

  /* Get the AlarmB interrupt source enable status */
  if(__HAL_RTC_ALARM_GET_IT_SOURCE(hrtc, RTC_IT_ALRB) != 0U)
  {
    /* Get the pending status of the AlarmB Interrupt */
    if(__HAL_RTC_ALARM_GET_FLAG(hrtc, RTC_FLAG_ALRBF) != 0U)
    {
      /* Clear the AlarmB interrupt pending bit */
      __HAL_RTC_ALARM_CLEAR_FLAG(hrtc, RTC_FLAG_ALRBF);

      /* AlarmB callback */
#if (USE_HAL_RTC_REGISTER_CALLBACKS == 1)
      hrtc->AlarmBEventCallback(hrtc);
#else  /* (USE_HAL_RTC_REGISTER_CALLBACKS == 1) */
      HAL_RTCEx_AlarmBEventCallback(hrtc);
#endif /* (USE_HAL_RTC_REGISTER_CALLBACKS == 1) */
    }
  }
#endif /* TAMP */

  /* Change RTC state */
  hrtc->State = HAL_RTC_STATE_READY;
}

回复

使用道具 举报

4

主题

46

回帖

58

积分

初级会员

积分
58
发表于 2023-8-8 17:35:11 | 显示全部楼层
HAL_RTC_AlarmIRQHandler,这个函数自己会清除,不需要你手动清除,应用程序只需要知道这个事发生了并在回调函数中置为相应的变量或者发送相应的消息即可.
给个参考
[C] 纯文本查看 复制代码
//RTC闹钟中断服务函数
void RTC_Alarm_IRQHandler(void)
{
    //进入中断,调用ThreadX方法告知系统
    _tx_thread_context_save();
    //调用RTC中断处理函数
    HAL_RTC_AlarmIRQHandler(&handleRTC);
    //退出中断,调用ThreadX方法告知系统
    _tx_thread_context_restore();
}

//RTC WAKE UP中断服务函数
void RTC_WKUP_IRQHandler(void)
{
    //进入中断,调用ThreadX方法告知系统
    _tx_thread_context_save();
    //调用RTC中断处理函数
    HAL_RTCEx_WakeUpTimerIRQHandler(&handleRTC); 
    //退出中断,调用ThreadX方法告知系统
    _tx_thread_context_restore();
}
    
//RTC闹钟A中断处理回调函数
void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
{
    if(rtcAlarmCallBackFuncPtrA != NULL)
    {
        rtcAlarmCallBackFuncPtrA();
    }
}

//RTC闹钟B中断处理回调函数
void HAL_RTCEx_AlarmBEventCallback(RTC_HandleTypeDef *hrtc)
{
    if(rtcAlarmCallBackFuncPtrB != NULL)
    {
        rtcAlarmCallBackFuncPtrB();
    }
}

//RTC WAKE UP中断处理
void HAL_RTCEx_WakeUpTimerEventCallback(RTC_HandleTypeDef *hrtc)
{
    if(rtcWakeupCallBackFunc != NULL)
    {
        rtcWakeupCallBackFunc();
    }
}
回复

使用道具 举报

15

主题

23

回帖

68

积分

初级会员

积分
68
 楼主| 发表于 2023-8-9 08:23:32 | 显示全部楼层
dengxiaojundink 发表于 2023-8-8 17:35
HAL_RTC_AlarmIRQHandler,这个函数自己会清除,不需要你手动清除,应用程序只需要知道这个事发生了并在回调函 ...

RTC_Alarm_IRQHandler   这个中断怎么清除呢?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106847
QQ
发表于 2023-8-10 00:13:19 | 显示全部楼层
l4568527193 发表于 2023-8-9 08:23
RTC_Alarm_IRQHandler   这个中断怎么清除呢?

二楼贴的代码里面已经有CLEAR_FLAG

使用HAL库,如果使用他们的中断处理,里面都已经做清除中断标志处理了,不需要用户再做。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-7 12:50 , Processed in 0.186523 second(s), 26 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表