经过一段时间的学习,我对HAL库自带的中断回调机制深恶痛绝,个人认为你可以把HAL库当成标准库去编写,形成你自己的编译风格,不用执行HAL库官方给的模板。
HAL库中断函数回调机制:
首先每个芯片的中断处理机制都是一样的,一样的中断头,一样的存储地址块
比如:HAL库中的void TIM5_IRQHandler(void)就与标准库的中断头一样
A.一触发中断就跳往对应中断的服务函数这里以定时器为例
按照HAL库格式,进去后执行
你也可以再加一个清除标志位在这里,不过前面那个函数里已经有清理函数了,再加一个做保险而已
B.进入HAL_TIM_IRQHandler(&g_timx_cap_chy_handle); /* 定时器HAL库共用处理函数 */
这是一部分,但由一通全,可知全貌
从上图可以看出他先去判断每个标志位,把点亮了的全部执行其对应回调函数callback并clear该标志位
所以用户只需在callback函数中编写自己的功能就行
而且他是一次性检查一个外设里,并列if遍寻所有标志位谁亮执行谁的callback,所以编写不同callback函数就行,他会一起执行
像下面这个定时器5的ic1和溢出中断,两个callback函数在一个HAL_TIM_IRQHandler(&g_timx_cap_chy_handle); /* 定时器HAL库共用处理函数 */判断执行并清除标志位
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) { if (htim->Instance == TIM5) { if ((g_timxchy_cap_sta & 0X80) == 0) /* 还没有成功捕获 */ { if (g_timxchy_cap_sta & 0X40) /* 捕获到一个下降沿 */ { g_timxchy_cap_sta |= 0X80; /* 标记成功捕获到一次高电平脉宽 */ g_timxchy_cap_val = HAL_TIM_ReadCapturedValue(&g_timx_cap_chy_handle, TIM_CHANNEL_1); /* 获取当前的捕获值 */ TIM_RESET_CAPTUREPOLARITY(&g_timx_cap_chy_handle, TIM_CHANNEL_1); /* 一定要先清除原来的设置 */ TIM_SET_CAPTUREPOLARITY(&g_timx_cap_chy_handle, TIM_CHANNEL_1, TIM_ICPOLARITY_RISING); /* 配置TIM5通道1上升沿捕获 */ } else /* 还未开始,第一次捕获上升沿 */ { g_timxchy_cap_sta = 0; /* 清空 */ g_timxchy_cap_val = 0; g_timxchy_cap_sta |= 0X40; /* 标记捕获到了上升沿 */ __HAL_TIM_DISABLE(&g_timx_cap_chy_handle); /* 关闭定时器5 */ __HAL_TIM_SET_COUNTER(&g_timx_cap_chy_handle, 0); /* 定时器5计数器清零 */ TIM_RESET_CAPTUREPOLARITY(&g_timx_cap_chy_handle, TIM_CHANNEL_1); /* 一定要先清除原来的设置!! */ TIM_SET_CAPTUREPOLARITY(&g_timx_cap_chy_handle, TIM_CHANNEL_1, TIM_ICPOLARITY_FALLING); /* 定时器5通道1设置为下降沿捕获 */ __HAL_TIM_ENABLE(&g_timx_cap_chy_handle); /* 使能定时器5 */ } } } } /* 定时器更新中断回调函数 */ void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if (htim->Instance == TIM5) { if ((g_timxchy_cap_sta & 0X80) == 0) /* 还未成功捕获 */ { if (g_timxchy_cap_sta & 0X40) /* 已经捕获到高电平了 */ { if ((g_timxchy_cap_sta & 0X3F) == 0X3F) /* 高电平太长了 */ { TIM_RESET_CAPTUREPOLARITY(&g_timx_cap_chy_handle, TIM_CHANNEL_1); /* 一定要先清除原来的设置 */ TIM_SET_CAPTUREPOLARITY(&g_timx_cap_chy_handle, TIM_CHANNEL_1, TIM_ICPOLARITY_RISING);/* 配置TIM5通道1上升沿捕获 */ g_timxchy_cap_sta |= 0X80; /* 标记成功捕获了一次 */ g_timxchy_cap_val = 0XFFFF; } else /* 累计定时器溢出次数 */ { g_timxchy_cap_sta++; } } } } }
标签:HAL,timxchy,cap,剖析,TIM,源码,chy,handle From: https://blog.csdn.net/2301_80317247/article/details/140315017