STM32中中断的回调函数是如何执行的?(窗口看门狗为例)

cpp 复制代码
void HAL_WWDG_IRQHandler(WWDG_HandleTypeDef *hwwdg)
{
  /* Check if Early Wakeup Interrupt is enable */
  if (__HAL_WWDG_GET_IT_SOURCE(hwwdg, WWDG_IT_EWI) != RESET)
  {
    /* Check if WWDG Early Wakeup Interrupt occurred */
    if (__HAL_WWDG_GET_FLAG(hwwdg, WWDG_FLAG_EWIF) != RESET)
    {
      /* Clear the WWDG Early Wakeup flag */
      __HAL_WWDG_CLEAR_FLAG(hwwdg, WWDG_FLAG_EWIF);

#if (USE_HAL_WWDG_REGISTER_CALLBACKS == 1)
      /* Early Wakeup registered callback */
      hwwdg->EwiCallback(hwwdg);
#else
      /* Early Wakeup callback */
      HAL_WWDG_EarlyWakeupCallback(hwwdg);
#endif /* USE_HAL_WWDG_REGISTER_CALLBACKS */
    }
  }
} 

这段代码是如何执行HAL_WWDG_EarlyWakeupCallback(hwwdg); 的?

在STM32的HAL库中,WWDG(窗口看门狗)外设的中断处理函数HAL_WWDG_IRQHandler负责处理窗口看门狗的中断事件。特别是,它处理的是早期唤醒中断(Early Wakeup Interrupt, EWI)。以下是这段代码如何执行HAL_WWDG_EarlyWakeupCallback(hwwdg);的详细解释:

  1. 中断处理函数定义:

    |---|-------------------------------------------------------|
    | | void HAL_WWDG_IRQHandler(WWDG_HandleTypeDef *hwwdg) |

    这个函数是WWDG的中断服务程序(ISR),当WWDG产生中断时被调用。它接受一个指向WWDG_HandleTypeDef结构体的指针hwwdg,该结构体包含了WWDG的配置和状态信息。

  2. 检查中断源:

    |---|--------------------------------------------------------------|
    | | if (__HAL_WWDG_GET_IT_SOURCE(hwwdg, WWDG_IT_EWI) != RESET) |

    首先,使用__HAL_WWDG_GET_IT_SOURCE宏检查是否启用了早期唤醒中断(EWI)。如果启用了EWI,该宏返回非零值(通常是非零值表示SET,而零值表示RESET)。

  3. 检查中断标志:

    |---|------------------------------------------------------------|
    | | if (__HAL_WWDG_GET_FLAG(hwwdg, WWDG_FLAG_EWIF) != RESET) |

    如果EWI中断源被启用,接着检查WWDG的早期唤醒中断标志(EWIF)是否被设置。这也是通过__HAL_WWDG_GET_FLAG宏来完成的。如果EWIF被设置,表明发生了早期唤醒事件。

  4. 清除中断标志:

    |---|-------------------------------------------------|
    | | __HAL_WWDG_CLEAR_FLAG(hwwdg, WWDG_FLAG_EWIF); |

    一旦确认EWIF标志被设置,使用__HAL_WWDG_CLEAR_FLAG宏来清除该标志。清除标志是必需的,以便系统可以正确响应后续的中断。

  5. 调用回调函数:

    • 如果启用了回调函数注册 (USE_HAL_WWDG_REGISTER_CALLBACKS == 1):

      |---|------------------------------|
      | | hwwdg->EwiCallback(hwwdg); |

      如果定义了USE_HAL_WWDG_REGISTER_CALLBACKS宏,并且其值为1,那么HAL库支持回调函数的注册。在这种情况下,HAL_WWDG_IRQHandler会调用hwwdg结构体中注册的EwiCallback函数。这个函数是由用户提供的,用于处理早期唤醒事件。

    • 如果没有启用回调函数注册 (USE_HAL_WWDG_REGISTER_CALLBACKS != 1):

      |---|----------------------------------------|
      | | HAL_WWDG_EarlyWakeupCallback(hwwdg); |

      如果未启用回调函数注册,HAL_WWDG_IRQHandler会调用HAL_WWDG_EarlyWakeupCallback。这是一个在HAL库中定义的弱回调函数,用户可以在自己的代码中重写这个函数来处理早期唤醒事件。

总结来说,HAL_WWDG_IRQHandler通过一系列的检查和条件分支,最终决定调用哪个回调函数来处理早期唤醒事件。这取决于是否启用了HAL库的回调函数注册特性。如果启用了回调函数注册,将调用用户注册的EwiCallback;否则,将调用默认的HAL_WWDG_EarlyWakeupCallback。

STM32(hal库)的启用回调函数注册是什么意思,有什么用?

STM32(HAL库)中的启用回调函数注册是一种编程机制,它允许用户在应用层定义特定的函数,并将这些函数的指针注册到HAL库中的相应位置。当HAL库或底层硬件发生特定事件时,它会调用这些注册的回调函数,从而允许用户的应用层代码响应这些事件。

启用回调函数注册的意义和用途主要包括以下几点:

  1. 提高代码的灵活性和可扩展性 :
    • 通过回调函数注册机制,用户可以在不修改HAL库源代码的情况下,为特定事件添加自定义的处理逻辑。
    • 这使得代码更加模块化,易于维护和扩展。
  2. 实现事件驱动编程 :
    • 回调函数通常用于处理异步事件,如中断、定时器到期、外设操作完成等。
    • 当这些事件发生时,HAL库会调用相应的回调函数,从而允许用户的应用层代码及时响应并处理这些事件。
  3. 解耦库函数和应用层函数 :
    • 回调函数注册机制实现了库函数和应用层函数的解耦。
    • 库函数负责处理底层硬件和标准的操作逻辑,而应用层函数则负责处理用户特定的业务逻辑。
    • 这种解耦使得库函数更加通用和可重用,同时允许用户根据具体需求定制应用层函数。
  4. 简化中断处理 :
    • 在STM32的HAL库中,许多外设的中断处理函数都预定义了回调函数的接口。
    • 用户只需将自己的处理逻辑封装在回调函数中,并将其注册到HAL库中,即可实现中断处理。
    • 这简化了中断处理的流程,减少了用户编写中断服务程序的工作量。
  5. 提高代码的可读性和可维护性 :
    • 通过回调函数注册机制,用户可以将与特定事件相关的处理逻辑集中在一个或多个回调函数中。
    • 这使得代码更加清晰和易于理解,同时也方便了后续的维护和修改。

STM32(HAL库)中的启用回调函数注册是一种强大的编程机制,它提高了代码的灵活性和可扩展性,实现了事件驱动编程,解耦了库函数和应用层函数,简化了中断处理,并提高了代码的可读性和可维护性。

相关推荐
起个网名真难~1 天前
STM32F103_Bootloader_从零到UART升级成功_博客原稿
stm32·单片机·嵌入式硬件
二本咕咕-机械转码1 天前
FreeRTOS深入解析(一)_链表与并发保护——哨兵循环链表、排序键游标、临界区与关调度
单片机·算法·链表
Zwawa1 天前
串口命令如何从字符串长成协议:帧头、长度、校验和与状态机
c语言·单片机·嵌入式
小李不想当小白1 天前
BKP备份寄存器与RTC实时时钟(STM32标准库学习笔记)
笔记·stm32·单片机·嵌入式硬件·学习·嵌入式
Zw-awa1 天前
串口命令如何从字符串长成协议:帧头、长度、校验和与状态机
stm32
La Pulga1 天前
【FreeRTOS源码学习笔记】链表的实现
数据结构·笔记·stm32·mcu·链表·嵌入式·freertos
铅笔小新z1 天前
【stm32】WWDG(窗口看门狗)
stm32·单片机·嵌入式硬件
comyccccc1 天前
平衡车底板设计:精准布局与高效布线学习笔记
单片机·嵌入式硬件
La Pulga1 天前
【FreeRTOS源码学习笔记】任务创建
笔记·stm32·mcu·学习·嵌入式·freertos·实时操作系统
芯片人0071 天前
GEK100系列芯片进入上市公司上海移远通信供应链
人工智能·单片机·嵌入式硬件·物联网·芯片