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

相关推荐
不悔哥5 天前
开源OV-Watch:怎么做一个智能手表
单片机·开源·嵌入式
XiHongShi20165 天前
STM32F407 RTC定时器例程,建议保存
stm32·单片机·学习
优信电子5 天前
AIT1001 非接触式红外测温模块 STM32 驱动开发实战:从引脚到代码全解析
stm32·嵌入式·温度传感器·红外测温·非接触式测温·ait1001
深圳老胡5 天前
STM32F407 控制 L6470 步进电机驱动 —— 控制过程简介
笔记·stm32·单片机·嵌入式硬件·代码规范
wuyk5555 天前
《WiFi 嵌入式物联网开发全套实战》| 第 16 章 ESP32 AP+STA 双模共存原理与工程坑点
网络·stm32·物联网
女神下凡5 天前
嵌入式设计的各种存储芯片的硬件/软件设计规范,非常全面。
arm开发·单片机·嵌入式硬件
梅梅9665 天前
一款mipi转lvds的lcd调试(LT8912B)
单片机·计算机外设·电脑·显示器·pd芯片
开发笔记-阿牛5 天前
蓝牙音乐灯拆解,又一次拆到蓝牙音乐灯芯片CK6865L
人工智能·单片机·嵌入式硬件·音视频·音频
从零开始的嵌入式之旅5 天前
day47
arm开发·经验分享·笔记·嵌入式硬件
恒锐丰科技林技术员5 天前
EG1164 高压大电流升压同步整流芯片解析
经验分享·嵌入式硬件·硬件工程