外部中断的存在使得微控制器能够及时响应外部事件,避免频繁的轮询操作,从而提高系统的实时性、效率和低功耗性能。
1. 什么是外部中断?
外部中断是指微控制器接收到外部引脚的信号变化时触发的中断。STM32F103系列微控制器支持多个外部中断线路(EXTI),每条线路可以与特定的GPIO引脚连接,并配置不同的触发模式(上升沿、下降沿或双边沿)。
外部中断的基本组成部分包括:
- GPIO 引脚:物理引脚,通过配置可以触发中断。
- EXTI 线路:用于连接GPIO引脚和中断控制器。
- NVIC(嵌套向量中断控制器):管理所有中断的优先级和响应
2. 外部中断和按键相结合
在上一篇按键输入的博客里面,可以看在为了检测到按键的输入,必须要在while循环里面时刻检测IO口电平的变化,那么就存在一种可能,随着程序复杂性的增加,如果你没有检测到电平的变化,那么这次按键就白按了,这显然不是我们想看到的情景,所以我们寻求一种方法在不借助轮询检测的基础上,能够时刻检测到按键的变化,争取不错过每一次心动的感觉。
结合的方法也很简单,如上文所说,外部中断的本质上使检测电平的变化,按键按下也会带来电平的变化,所以确认过眼神,遇上对的人。
3. 配置步骤
3.1 GPIO初始化
首先需要将对应的GPIO引脚配置为输入模式,以检测外部信号。以下代码展示了如何初始化PA0引脚为浮空输入模式:
cpp
void GPIO_Config(void) {
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // 使能GPIOA时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; // 选择PA0引脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; // 配置为浮空输入模式
GPIO_Init(GPIOA, &GPIO_InitStructure); // 初始化GPIOA的PA0
}
3.2 AFIO配置
AFIO(Alternate Function I/O)用于将特定的GPIO引脚映射到外部中断线路。以下代码将PA0引脚映射到EXTI0线路,并配置中断触发条件为上升沿触发:
cpp
void EXTI_Config(void) {
EXTI_InitTypeDef EXTI_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); // 使能AFIO时钟
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0); // 连接PA0到EXTI线路0
EXTI_InitStructure.EXTI_Line = EXTI_Line0; // 选择EXTI线路0
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; // 设置为中断模式
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; // 上升沿触发
EXTI_InitStructure.EXTI_LineCmd = ENABLE; // 使能EXTI线路
EXTI_Init(&EXTI_InitStructure); // 初始化EXTI配置
}
3.3 NVIC配置
NVIC负责管理中断的优先级及响应。以下代码展示了如何使能EXTI0中断,并配置其优先级:
cpp
void NVIC_Config(void) {
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; // 选择EXTI0中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00; // 设置抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00; // 设置响应优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // 使能中断通道
NVIC_Init(&NVIC_InitStructure); // 初始化NVIC配置
}
3.4 中断处理函数
触发中断后,可以在中断处理函数添加需要处理的函数。
cpp
void EXTI0_IRQHandler(void)
{
if (EXTI_GetITStatus(EXTI_Line0) != RESET)
{
// 这里可以添加中断触发后的处理代码
EXTI_ClearITPendingBit(EXTI_Line0); // 清除中断标志
}
}
4. 响应优先级和抢占优先级
响应优先级 决定了在同一优先级的中断中,哪个中断会被首先响应。它是中断控制器处理同一级别中断请求的顺序。通常,中断优先级是一个数字,较低的数字表示较高的优先级。高响应优先级 的中断可以在当前处理中断中继续执行,而低响应优先级的中断可能需要等待。
抢占优先级 决定了当一个中断正在处理中时,另一个优先级更高的中断是否可以打断(抢占)当前正在处理中断。抢占优先级的配置能够帮助处理更紧急的任务,而不被当前的中断所阻塞。高抢占优先级 的中断可以中断任何低抢占优先级的中断。低抢占优先级的中断则需要等待高抢占优先级的中断完成后才能被处理。
所以说抢占优先级,用于决定中断是否可以中断其他中断。响应优先级,用于在同一级别中决定中断的处理顺序。
5. 中断线映射
在复杂的系统中,可能存在多个外设产生的中断信号。如果没有合理的中断线映射,这些中断信号可能会冲突或覆盖彼此的处理逻辑。中断线映射的目的是为了灵活和有效地管理中断源和响应,确保系统能够按预期运行。不同的外部设备和内部模块可能生成多个中断请求。通过中断线映射,可以将这些中断源映射到不同的中断线,以确保系统可以灵活地管理和处理各种中断。
6. 注意
引脚配置:确保配置的GPIO引脚与EXTI线路正确映射。
中断优先级:合理设置中断优先级,避免优先级冲突。
中断处理:中断服务程序应简短高效,避免长时间占用CPU资源。