最近学STM32F407,学到定时器的一些操作,ISR、IRQ、中断事件类型什么的,有些乱,所以就特地花时间整理了一下,于是有了这一篇笔记。
先介绍一些名词
ISR:Interrupt Service Routine,中断服务例程/中断服务程序,每个中断号对应一个ISR
IQR:Interrupt Request,中断请求
U / UEV:Update Event,更新事件,这是中断事件类型中的一种。基础定时器只有更新事件
中断事件类型 / 事件
中断事件标志位 / 中断标志位
中断事件使能标志位 / 中断使能控制位
下面正式开始:
除了高级定时器,每个定时器都只有一个中断号,也就是只有一个ISR。(一个ISR不一定只对应一个定时器)
发生中断时,会自动执行相应的ISR。所有ISR里都会调用一个相同的函数,HAL_TIM_IRQHandler(),这是定时器中断处理通用函数。(被调用时,传给这个函数的参数不一样,所以可以区分是哪个定时器调用的)
下图有两个ISR。
第一个是定时器6的ISR,对应的中断号是54,中断名称为TIM6_DAC,这个中断号代表了TIM6全局中断,DAC1和DAC2下溢错误中断。
第二个是定时器7的ISR,对应的中断号是55,中断名称为TIM7,这个中断号代表了TIM7全局中断。
因为中断号代表的中断不同,所以它们的ISR的名称也不一样。
基础定时器只能发出一种中断事件类型,来触发中断或DMA请求。但是对于通用定时器和高级定时器,它们有多个中断事件类型。
对于同一个定时器,不管是什么事件,都是触发同一个ISR,进入同一个定时器中断处理通用函数,传给这个函数的参数也一样。那么,怎么来判断这次中断是由什么事件触发的呢?这就是下面要讲的事情了。
在文件stm32f4xx_hal_tim.h中,定义了定时器所有中断事件类型的宏
在定时器中断处理通用函数里,程序会根据中断事件标志位和中断事件使能标志位来判断中断事件类型。(对于一般的外设,一个中断事件类型有一个中断事件标志位和一个中断事件使能标志位)
然后清除中断挂起标志位,并调用相应的回调函数,每一种中断事件对应一种回调函数。
这些回调函数都是在HAL库中定义的弱函数,而且函数代码为空。用户需要处理某个中断事件时,只需要重新实现相应的回调函数即可。
如果判断中断事件类型是捕获/比较通道x事件,在捕获/比较通道x事件里面还会判断这个事件是输入捕获事件还是输出比较事件。