GPIO 和 EXTIx 的映射关系
GPIOx0(x=A~G)对应 EXTI0 ;
GPIOx1(x=A~G)对应 EXTI1 ;
GPIOx2(x=A~G)对应 EXTI2 ;
···
GPIOx15(x=A~G)对应 EXTI15 ;
如下图所示,
#注意:不同芯片的 IO 数量不同,因此 IO 组数也不同。对于STM32F407而言,IO 组数为 A~G。
相关函数及功能
有关中断的函数有很多,下文叙述与中段直接相关的函数。
HAL_GPIO_EXTI_IRQHandler()
void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
该函数是中断通用入口函数。STM32F407的所用中断都要用它来处理中断请求,这也是“中断通用入口函数”的含义。
该函数的完整描述如下,
void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
{
if(__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != RESET)
{
__HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);
HAL_GPIO_EXTI_Callback(GPIO_Pin);
}
}
可见,该函数内部调用了三个函数,如下文所述,
“ __HAL_GPIO_EXTI_GET_IT(GPIO_Pin) ” 该函数用于获取指定GPIO引脚的外部中断标志位;
“ __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin) ” 该函数用于清除与指定引脚相关联的外部中断线的中断标志位,从而允许中断服务例程在下一次相同的中断事件发生时再次被调用。
“ HAL_GPIO_EXTI_Callback(GPIO_Pin) ” 该函数是中断回调函数,这个函数的主要作用是提供一个用户自定义的接口,用于处理外部中断事件,在这个回调函数中,用户可以编写具体的中断服务逻辑,如读取传感器数据、控制外设状态或执行其他需要响应中断的任务。
上文中的代码实现的功能(也就是中断通用入口函数的功能)如下文所述,
①如果检测到该引脚(GPIO_Pin)的中断标志位不为0(即!= RESET
),表示相应的外部中断事件已经发生,则执行 if 语句内的代码(也就是继续执行其他两个函数所表达的功能);
②清除与指定引脚(GPIO_Pin)相关联的外部中断线的中断标志位,从而允许中断服务例程在下一次相同的中断事件发生时可以再次被调用。
③执行回调函数中的用户编写的具体的中断服务逻辑。
EXTIx 和 中断服务函数 的关系
STM32F407中共有7个中断服务例程,即 EXTIx_TRQHandler() (x=0~5、9_5、10_15)。
中断服务历程( EXTIx_TRQHandler() )和 中段线( EXTIx )的对应关系如下,
中断线(编号) | 中断服务例程 |
EXTI0 | EXTI0_IRQHandler() |
EXTI1 | EXTI1_IRQHandler() |
EXTI2 | EXTI2_IRQHandler() |
EXTI3 | EXTI3_IRQHandler() |
EXTI4 | EXTI4_IRQHandler() |
EXTI5 | EXTI9_5_IRQHandler() |
EXTI6 | |
EXTI7 | |
EXTI8 | |
EXTI9 | |
EXTI10 | EXTI15_10_IRQHandler() |
EXTI11 | |
EXTI12 | |
EXTI13 | |
EXTI14 | |
EXTI15 |
因此,我们使用中断时,必须先根据上表的映射关系,确定我们要具体使用那个中断服务例程。
中断服务例程(EXTIx_TRQHandler() )和 中断服务函数(HAL_GPIO_EXTI_IRQHandler
)的关系如下文所述:
HAL_GPIO_EXTI_IRQHandler
是一个通用的中断服务处理函数,它被设计为在HAL库中处理所有外部中断(EXTIx)的中断请求。当外部中断发生时,相应的中断服务例程(如 EXTI0_IRQHandler
)会被调用,并在其中调用 HAL_GPIO_EXTI_IRQHandler
函数。这个通用函数会检查是哪一个外部引脚的中断被触发,清除中断标志位,并调用用户定义的回调函数 HAL_GPIO_EXTI_Callback
来执行具体的中断处理逻辑。
简单来说,EXTIx_IRQHandler
是特定于外部中断的中断服务例程,而 HAL_GPIO_EXTI_IRQHandler
是一个封装了中断处理通用流程的函数,它可以在不同的中断服务例程中被调用,以实现对不同外部中断的统一处理。
总结
中断处理流程如下图所示,