关于中断与NVIC可以看
STM32:关于NVIC的工作与优先级分组方式-CSDN博客
什么是外部中断?
外部中断,是一种机制,是一系列的环节,英文名叫Extern Interrupt,EXTI,由命名可以知道这大概是干什么的,外部中断,顾名思义就是中断信号来自CPU外部的中断。
通常是,通过监测指定GPIO口的电平信号,当其指定的GPIO口发生电平变化,EXTI向NVIC发出中断申请,NVIC裁决是否中断主程序,让CPU执行EXTI对应的中断程序。
EXTI的中断通道有16个GPIO_PIN,外加四个外设,PVD输出,RTC时钟,USB唤醒,以太网唤醒。所有的GPIO都支持外部中断,但相同的pin不能同时触发中断。那么,什么是所谓相同的pin,为什么呢?
EXTI支持上升沿,下降沿触发,上升下降同时,与软件触发。可以触发中断响应与事件响应。
所有的GPIO都支持外部中断,但相同的pin不能同时触发中断,为什么?
相同的pin,指的是PA-0,PB-0,PC-0,这些数字相同的pin。所有的GPIO口在硬件设计上,都具备被配置为外部中断的能力。同时,外部中断控制器在设计时,采用了特定的中断线映射机制,将相同编号的pin映射在同一条中断线上。所以,相同的pin不能同时触发中断。
EXTI的基本结构
我在上面说了,EXTI是一系列动作形成的机制,这里,我介绍一下EXTI的结构。

AFIO的功能

所有的GPIO外设(注意,GPIO与GPIO外设是有区别的)都有16个引脚,每个GPIO外设有16条线,如果每个引脚都使用一条中断通道,再加上另外四个外设事件,那么EXTI的中断通道就不够用了。所以使用AFIO进行中断引脚选择。AFIO就是一个数据选择器,这就是为什么前面说相同的pin不能同时触发中断。还有一个功能是引脚重映射,此处不表。
共用中断函数怎么处理
二十个信号输入如果有对应的二十个信号输出,会占用过多NVIC的通道资源,所以将EXTI的9-5,15-10接入到了一个中断函数里,在实际使用时,可以在中断函数内部使用标志位来进行区分。
cs
#include "stm32f10x.h" // 包含STM32F10x系列的头文件
// 中断服务函数,处理多个EXTI中断
void EXTI9_5_IRQHandler(void) {
if (EXTI_GetITStatus(EXTI_Line5) != RESET) { // 检查EXTI Line5是否触发中断
// 清除EXTI Line5的中断挂起位
EXTI_ClearITPendingBit(EXTI_Line5);
// 处理EXTI Line5的中断
// ...
} else if (EXTI_GetITStatus(EXTI_Line6) != RESET) { // 检查EXTI Line6是否触发中断
// 清除EXTI Line6的中断挂起位
EXTI_ClearITPendingBit(EXTI_Line6);
// 处理EXTI Line6的中断
// ...
} else if (EXTI_GetITStatus(EXTI_Line7) != RESET) { // 检查EXTI Line7是否触发中断
// 清除EXTI Line7的中断挂起位
EXTI_ClearITPendingBit(EXTI_Line7);
// 处理EXTI Line7的中断
// ...
} else if (EXTI_GetITStatus(EXTI_Line8) != RESET) { // 检查EXTI Line8是否触发中断
// 清除EXTI Line8的中断挂起位
EXTI_ClearITPendingBit(EXTI_Line8);
// 处理EXTI Line8的中断
// ...
} else if (EXTI_GetITStatus(EXTI_Line9) != RESET) { // 检查EXTI Line9是否触发中断
// 清除EXTI Line9的中断挂起位
EXTI_ClearITPendingBit(EXTI_Line9);
// 处理EXTI Line9的中断
// ...
}
}
int main(void) {
// 配置GPIO和EXTI的代码
// ...
while (1) {
// 主循环中不需要轮询标志位,所有处理都在中断服务函数中完成
}
}
EXTI的底层结构
右下角的输入线连接到边沿检测电路,该电路负责检测输入信号的边沿变化。边沿检测电路的输出连接到上升沿触发器和下降沿触发器,这两个触发器分别用于检测上升沿和下降沿信号。此外,软件中断事件寄存器也连接到同一个或门,这意味着软件可以通过设置该寄存器来触发中断事件。
当边沿检测电路检测到符合触发条件的边沿时,或者软件中断事件寄存器被设置时,或门会生成一个触发信号。这个触发信号随后分为两路:一路向上进入请求挂起寄存器,另一路与事件屏蔽寄存器的输出一起进入另一个或门。
进入请求挂起寄存器的信号用于触发中断。当触发信号到达请求挂起寄存器时,它会设置一个中断标志位,表示有中断请求需要处理。这个标志位可以被中断控制器读取,从而决定是否触发中断服务程序。
另一路信号与事件屏蔽寄存器的输出通过或门连接。事件屏蔽寄存器的作用是控制哪些事件信号可以被传递。如果事件屏蔽寄存器允许该事件通过,那么或门会将触发信号和事件屏蔽信号结合起来,生成最终的事件触发信号。这里的或门相当于一个开关,只有当事件屏蔽寄存器允许时,事件信号才能通过。
总结来说,EXTI模块通过边沿检测电路和软件中断事件寄存器生成触发信号,然后通过请求挂起寄存器和事件屏蔽寄存器分别控制中断和事件的触发。这种架构使得EXTI能够灵活地处理多种触发方式,并且可以分别控制中断和事件的使能。
总结
通过上述对EXTI模块的深入剖析,我们全面了解了其从输入信号检测到中断或事件触发的完整流程。EXTI模块作为嵌入式系统中处理外部中断的关键组件,其灵活的触发方式和高效的信号处理机制,为系统响应外部事件提供了强有力的保障。
在实际的嵌入式开发中,掌握EXTI的工作原理和配置方法,能够帮助我们更高效地利用系统资源,实现对外部事件的快速响应和精准处理。无论是简单的按键中断,还是复杂的外部设备信号处理,EXTI模块都发挥着不可或缺的作用。
希望本文的讲解能够为你的嵌入式学习之旅提供有益的参考,帮助你在开发实践中更好地运用EXTI模块,提升系统的性能和稳定性。如果你在实际应用中遇到任何问题,欢迎随时交流探讨,共同进步!