EXTI 外部中断
1. 简介
EXTI(Extern Interrupt)外部中断
EXTI 可以监测指定 GPIO 口的电平信号,当其指定的 GPIO 口产生电平变化的时候,EXTI 立即向 NVIC 发出中断申请,经过 NVIC 裁决后即可中断 CPU 主程序,使得 CPU 执行 EXTI 对应的中断程序。
其中 EXTI 支持四种不同的触发方式
1.1 EXTI 特性
- EXTI 支持所有 GPIO 口,但是相同 Pin 的 IO 口不可以同时触发中断(比如PA0,PB0不能同时触发中断)。
- EXTI 支持的通道数:16个GPIO_Pin、PVD输出、RTC时钟、USB唤醒、以太网唤醒(合计20个中断线路)。
- 触发相应方式:中断响应、事件相应(事件响应不会触发中断,而是触发别的外设操作)。

2. EXIT 外部中断
2.1 开启RCC时钟
由于NVIC和EXTI是默认开启时钟的外设,因此不需要开启这两个外设的时钟;需要开启的有GPIO时钟以及AFIO时钟。
| RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOx, ENABLE); // GPIO
RCC_APB2PeriphClockCmd (RCC_APB2Periph_AFIO, ENABLE); // AFIO
|
2.2 配置GPIO口工作模式
由于使用EXTI外部中断,因此需要使目标 GPIO 口工作在上拉输入 (GPIO_Mode_IPU) 的模式下。
| GPIO_InitTypeDef GOIO_InitStrucuture;
GOIO_InitStrucuture.GPIO_Mode = GPIO_Mode_IPU; // GPIO 上拉输入
GOIO_InitStrucuture.GPIO_Pin = GPIO_Pin_x; // 配置需要使用的 Pin 口
GOIO_InitStrucuture.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GOIO_InitStrucuture);
|
2.3 配置 AFIO
通过 AFIO 将需要使用的 GPIO 口连接到 EXTI。
GPIO_EXTILineConfig (GPIO_PortSourceGPIOx, GPIO_PinSourcex);
// 将 GPIOx 连接至 AFIO 的 x 中断线路上
通过这个函数可以将指定的 GPIO 端口与指定的 EXTI 线路相连
2.4 配置EXIT
选择中断触发方式。
| EXTI_InitTypeDef EXTI_InitStructure; // EXTI初始化结构体
EXTI_InitStructure.EXTI_Line = EXTI_Linex; // 选择需要配置的中断线,这个与配置AFIO时所配置的中断线相同
EXTI_InitStructure.EXTI_LineCmd = ENABLE; // 选择指定中断线的状态
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; // 指定模式(EXTI_Mode_Interrupt : 中断模式)
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; // 指定触发信号的有效边沿
EXTI_Init(&EXTI_InitStructure);
|
EXTI 的几种触发模式 .EXTI_Trigger
EXTI_Trigger_Rising
—— 上升沿触发
EXTI_Trigger_Falling
—— 下降沿触发
EXTI_Trigger_Rsing_Falling
—— 双边沿触发
2.5 配置 NVIC
给中断分配一个合适的优先级。
| NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
// 配置NCIV优先级分组(抢占优先级、响应优先级)
// 该函数在每一个芯片中只能使用一次
NVIC_TypeDef NVIC_InitStructure; // NCIV初始化结构体
NVIC_InitStructure.NCIV_IRQChannel = EXTI15_10_IRQn; // 指定中断通道开启或者关闭
NVIC_InitStructure.NCIV_IRQChannelCmd = ENABLE; // 指定通道使能还是失能(ENABLE,DISABLE)
NVIC_InitStructure.NCIV_IRQChannelPreemptionPriority = 1; // 指定抢占优先级的优先级
NVIC_InitStructure.NCIV_IRQChannelSubPriority = 1; // 指定响应优先级的优先级
NVIC_Init(&NVIC_InitStructure);
|
NVIC优先级的几种分组
NVIC_PriorityGroup |
抢占优先级 |
相应优先级 |
NVIC_PriorityGroup_0 |
0 |
0-15 |
NVIC_PriorityGroup_1 |
0-1 |
0-7 |
NVIC_PriorityGroup_2 |
0-3 |
0-3 |
NVIC_PriorityGroup_3 |
0-7 |
0-1 |
NVIC_PriorityGroup_4 |
0-15 |
0 |
2.5 EXTI中断函数
在 EXTI 配置完毕后,当达到中断触发条件后就会自动执行中断函数中的代码。
| //中断函数
void EXTI15_10_IRQHandler(void){
if (EXTI_GetITStatus(EXTI_Linex) == SET ) { // 判断中断标志位,判断是否为想要触发中断的通道
/*
* 需要执行的函数
*/
EXTI_ClearITPendingBit(EXTI_Linex); // 清除中断标志位,防止程序重复申请中断造成死循环
}
}
|