HAL库里,__HAL_TIM_CLEAR_IT和__HAL_TIM_CLEAR_FLAG的区别

文章分析了HAL库中关于TIM中断标志位清除的两个宏定义的区别,指出__HAL_TIM_CLEAR_IT可能的误用,并建议在清除中断标志位时优先使用__HAL_TIM_CLEAR_FLAG以避免潜在的bug。
摘要由CSDN通过智能技术生成

        在HAL的学习过程中,我需要清除中断标志位以防止中断函数重复触发,此时我发现这两个宏定义很像,在仔细阅读了源码后,以下是我的看法。

1、宏定义解释

/** @brief Clear the TIM interrupt pending bits.
  * @param  __HANDLE__ TIM handle
  * @param  __INTERRUPT__ specifies the interrupt pending bit to clear.
  *          This parameter can be one of the following values:
  *            @arg TIM_IT_UPDATE: Update interrupt
  *            @arg TIM_IT_CC1:   Capture/Compare 1 interrupt
  *            @arg TIM_IT_CC2:  Capture/Compare 2 interrupt
  *            @arg TIM_IT_CC3:  Capture/Compare 3 interrupt
  *            @arg TIM_IT_CC4:  Capture/Compare 4 interrupt
  *            @arg TIM_IT_COM:   Commutation interrupt
  *            @arg TIM_IT_TRIGGER: Trigger interrupt
  *            @arg TIM_IT_BREAK: Break interrupt
  * @retval None
  */
#define __HAL_TIM_CLEAR_IT(__HANDLE__, __INTERRUPT__)      ((__HANDLE__)->Instance->SR = ~(__INTERRUPT__))
/** @brief  Clear the specified TIM interrupt flag.
  * @param  __HANDLE__ specifies the TIM Handle.
  * @param  __FLAG__ specifies the TIM interrupt flag to clear.
  *        This parameter can be one of the following values:
  *            @arg TIM_FLAG_UPDATE: Update interrupt flag
  *            @arg TIM_FLAG_CC1: Capture/Compare 1 interrupt flag
  *            @arg TIM_FLAG_CC2: Capture/Compare 2 interrupt flag
  *            @arg TIM_FLAG_CC3: Capture/Compare 3 interrupt flag
  *            @arg TIM_FLAG_CC4: Capture/Compare 4 interrupt flag
  *            @arg TIM_FLAG_COM:  Commutation interrupt flag
  *            @arg TIM_FLAG_TRIGGER: Trigger interrupt flag
  *            @arg TIM_FLAG_BREAK: Break interrupt flag
  *            @arg TIM_FLAG_CC1OF: Capture/Compare 1 overcapture flag
  *            @arg TIM_FLAG_CC2OF: Capture/Compare 2 overcapture flag
  *            @arg TIM_FLAG_CC3OF: Capture/Compare 3 overcapture flag
  *            @arg TIM_FLAG_CC4OF: Capture/Compare 4 overcapture flag
  * @retval The new state of __FLAG__ (TRUE or FALSE).
  */
#define __HAL_TIM_CLEAR_FLAG(__HANDLE__, __FLAG__)        ((__HANDLE__)->Instance->SR = ~(__FLAG__))

        __HAL_TIM_CLEAR_IT  的官方解释是  Clear the TIM interrupt pending bits.清除TIM中断待定位。

        __HAL_TIM_CLEAR_FLAG  的官方解释是  Clear the specified TIM interrupt flag.清除指定的TIM中断标志。

        两个宏定义的参数都为定时器的句柄和所需的中断源。

        我们从他们各自的宏定义可以看出来其实都是对定时器的状态寄存器SR进行操作。

        ((__HANDLE__)->Instance->SR = ~(__INTERRUPT__))

         ((__HANDLE__)->Instance->SR = ~(__FLAG__))

        但比较奇怪的是,我们点开中断源的更详细的宏定义可以发现,__HAL_TIM_CLEAR_IT 貌似是想对中断使能寄存器DIER进行操作?

        这是 __HAL_TIM_CLEAR_IT 的中断源的宏定义

/** @defgroup TIM_Interrupt_definition TIM interrupt Definition
  * @{
  */
#define TIM_IT_UPDATE                      TIM_DIER_UIE                         /*!< Update interrupt            */
#define TIM_IT_CC1                         TIM_DIER_CC1IE                       /*!< Capture/Compare 1 interrupt */
#define TIM_IT_CC2                         TIM_DIER_CC2IE                       /*!< Capture/Compare 2 interrupt */
#define TIM_IT_CC3                         TIM_DIER_CC3IE                       /*!< Capture/Compare 3 interrupt */
#define TIM_IT_CC4                         TIM_DIER_CC4IE                       /*!< Capture/Compare 4 interrupt */
#define TIM_IT_COM                         TIM_DIER_COMIE                       /*!< Commutation interrupt       */
#define TIM_IT_TRIGGER                     TIM_DIER_TIE                         /*!< Trigger interrupt           */
#define TIM_IT_BREAK                       TIM_DIER_BIE                         /*!< Break interrupt             */

        这是 __HAL_TIM_CLEAR_FLAG 的中断源的宏定义

/** @defgroup TIM_Flag_definition TIM Flag Definition
  * @{
  */
#define TIM_FLAG_UPDATE                    TIM_SR_UIF                           /*!< Update interrupt flag         */
#define TIM_FLAG_CC1                       TIM_SR_CC1IF                         /*!< Capture/Compare 1 interrupt flag */
#define TIM_FLAG_CC2                       TIM_SR_CC2IF                         /*!< Capture/Compare 2 interrupt flag */
#define TIM_FLAG_CC3                       TIM_SR_CC3IF                         /*!< Capture/Compare 3 interrupt flag */
#define TIM_FLAG_CC4                       TIM_SR_CC4IF                         /*!< Capture/Compare 4 interrupt flag */
#define TIM_FLAG_COM                       TIM_SR_COMIF                         /*!< Commutation interrupt flag    */
#define TIM_FLAG_TRIGGER                   TIM_SR_TIF                           /*!< Trigger interrupt flag        */
#define TIM_FLAG_BREAK                     TIM_SR_BIF                           /*!< Break interrupt flag          */
#define TIM_FLAG_CC1OF                     TIM_SR_CC1OF                         /*!< Capture 1 overcapture flag    */
#define TIM_FLAG_CC2OF                     TIM_SR_CC2OF                         /*!< Capture 2 overcapture flag    */
#define TIM_FLAG_CC3OF                     TIM_SR_CC3OF                         /*!< Capture 3 overcapture flag    */
#define TIM_FLAG_CC4OF                     TIM_SR_CC4OF                         /*!< Capture 4 overcapture flag    */

        我不确定这是不是HAL库的一个小bug,毕竟中断源的命名和实际操作的寄存器出现了偏差,我们接下来阅读一下芯片手册。

2、阅读芯片手册

        这是中断使能寄存器DIER的详细位声明。我们可以看到位0是更新中断,位1-4是输入捕获中断,位8以上的都是与DMA有关的,详情可以看芯片手册。

        这是状态寄存器SR的详细位声明。我们可以看到位0也是更新中断,位1-4也是输入捕获中断,位8以上的与重复捕获标记有关,详情可以看芯片手册。

        如果对中断源的宏定义继续深入的查看,会发现实际上就是0x01进行左移,如左移一位就是输入捕获1的中断标记。因此对更新中断和输入捕获1-4的标记进行清0的话实际上用哪个函数都可以,因为实际上都是对SR寄存器进行赋1。

        但如果跟重复捕获有关的话,需要用__HAL_TIM_CLEAR_FLAG去操作SR寄存器。

3、总结

        __HAL_TIM_CLEAR_IT 也许是想对中断使能寄存器DIER进行操作,但源码写错了,变成了对状态寄存器SR进行操作。这只是我的一个猜想。我们从DIER的中文名也可以猜想出来,对这个寄存器进行操作的时候,是对中断的使能和失能,而并不是进行清除中断标志位,防止重复进入中断。

        __HAL_TIM_CLEAR_FLAG 是对状态寄存器SR进行操作。是为了清除中断标志位的,如当发生输入捕获的时候,SR的位置被硬件置1,此时需要软件手动清0,防止重复进入中断函数。

        所以,大家如果是想清除中断标志位就直接使用 __HAL_TIM_CLEAR_FLAG 函数即可,__HAL_TIM_CLEAR_IT 我建议少用或者不用,可能对因为寄存器的错误赋值而出现不希望出现的Bug。

        最后,如果本文有误,欢迎大家讨论和指正,有误的话我会第一时间改正。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值