当前位置: 首页 > news >正文

中断服务函数和回调函数的理解

STM32的HAL库设计中,通常将中断处理过程分为**中断服务函数(ISR)回调函数(Callback)**两个层次,这样做主要出于以下几个原因:

1. 软件分层设计

  • 中断服务函数(ISR): 通常放在stm32fxxx_it.c文件中,负责基础的中断管理,如中断标志位清除、中断源确认、底层寄存器操作。这部分代码一般由HAL库自动生成,用户无需修改。
  • 回调函数(Callback): 位于用户代码区,由用户编写,用户可在回调函数中实现具体的应用逻辑,比如数据处理、状态更新等。

这种分层设计有助于代码清晰、易于维护。

2. 用户代码与库代码的解耦

  • ISR由库提供,而Callback由用户定义。通过回调函数,用户无需直接修改库代码即可实现自己的中断处理逻辑,确保库更新时用户代码不受或少受影响。

3. 增强灵活性和通用性

  • 用户可以在回调函数中自定义不同的行为,而无需深入了解底层的寄存器细节,适用于不同应用场景。
  • 库本身对外提供了统一接口,简化了开发难度。

4. 可读性与可维护性提高

  • HAL库使用统一的命名规则,比如HAL_UART_RxCpltCallback()(接收完成回调)或HAL_GPIO_EXTI_Callback()(外部中断回调),有利于提高代码的可读性,方便协作和代码维护。

举例说明:

例如在使用串口接收中断时,HAL库会自动在ISR中调用HAL_UART_IRQHandler(),然后在其中触发HAL_UART_RxCpltCallback()回调函数。用户只需要实现该回调函数即可,而无需关心底层中断如何清除标志或数据如何从寄存器取出。

// ISR自动调用(库代码)
void USART1_IRQHandler(void)
{
  HAL_UART_IRQHandler(&huart1);
}

// 用户实现的回调函数(用户代码)
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
  if (huart->Instance == USART1)
  {
    // 用户接收数据处理代码
  }
}

HAL_CAN_RxFifo0MsgPendingCallback() 回调函数与以下 中断服务函数(ISR) 相关:

void CAN1_RX0_IRQHandler(void)
{
    HAL_CAN_IRQHandler(&hcan1);
}

调用链条详细解释:

  1. 当CAN控制器接收到新报文并放入 FIFO 0 时,会触发 CAN RX FIFO 0中断CAN1_RX0_IRQHandler())。

  2. 中断触发后,会调用HAL库统一处理函数:

    HAL_CAN_IRQHandler(&hcan1);
    
  3. HAL_CAN_IRQHandler()内部,会检测是否有新消息进入FIFO0:

    if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_FMP0) != RESET &&
        __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FMP0) != RESET)
    {
        // 调用用户回调函数,通知用户层有新消息待处理
        HAL_CAN_RxFifo0MsgPendingCallback(hcan);
    }
    
  4. 最终用户通过实现HAL_CAN_RxFifo0MsgPendingCallback()回调函数来处理接收到的数据:

    void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
    {
        CAN_RxHeaderTypeDef RxHeader;
        uint8_t RxData[8];
        HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &RxHeader, RxData);
    
        // 用户处理接收数据的逻辑
    }
    

总结:

中断服务函数库中断处理函数用户回调函数
CAN1_RX0_IRQHandler()HAL_CAN_IRQHandler()HAL_CAN_RxFifo0MsgPendingCallback()

用户只需实现HAL_CAN_RxFifo0MsgPendingCallback()即可,无需直接修改库提供的ISR。

相关文章:

  • 介绍一下TiDB、RocksDb、levelDB、LSM 树、SSTable。
  • 2025年R1 快开门式压力容器操作证考试题目及答案解析
  • 【“缘起”:万物依条件而生】
  • dart学习记录4(循环、分钟、错误处理)
  • 【AI News | 20250320】每日AI进展
  • MyBatis 执行流程详解:一级缓存与二级缓存深度解析
  • QT并发编程进阶--线程安全与同步技巧详解
  • css-grid布局
  • 日期类的实现
  • 基于复杂的商业和政策信息构建GraphRAG,并结合通义千问大模型进行问答的应用场景
  • 美团Leaf分布式ID实战:深入解析雪花算法原理与应用
  • 网络空间安全(38)Windows/Linux权限
  • 算法刷题记录——LeetCode篇(1) [第1~100题](持续更新)
  • yarn install 出现certificate has expired报错问题
  • 读博士论文(未完待续)
  • (九)Dart 中的 Map(映射)
  • FPGA设计中时间单位科普
  • VS Code使用过程记录
  • Redisson 分布式锁原理
  • MCP(1)
  • 中疾控:适龄儿童要及时、全程接种百白破疫苗
  • 每日475.52元!最高检公布最新侵犯公民人身自由的赔偿金标准
  • 上海合作组织减贫和可持续发展论坛开幕,沈跃跃宣读习近平主席贺信
  • 人民日报评论员:党政机关要带头过紧日子
  • 上海青少年书法学习园开园:少年以巨笔书写《祖国万岁》
  • 2025全球城市科技传播能力指数出炉,上海位列第六