在嵌入式系统中,中断是一个非常重要的概念,而外部中断是中断的一种类型。为了更好地理解外部中断,我们先来简单了解一下中断和外部中断的关系。

一、中断是什么

1.中断的简介

中断是一种机制,它允许计算机或微控制器在执行程序的过程中,被某些事件打断,然后去处理这些事件。这些事件可以是内部的(比如程序运行过程中出现错误),也可以是外部的(比如外部设备发出的信号)。当一个中断发生时,处理器会暂停当前正在执行的程序,保存当前的状态,然后跳转到一个特定的程序(中断服务程序)去处理这个中断事件。处理完成后,再恢复原来的状态,继续执行原来的程序。

2.中断的执行流程

在嵌入式系统中,主程序负责初始化系统并执行主要任务,按顺序依次处理各项功能。当中断发生时,处理器会暂停主程序,保存当前状态,然后跳转到中断服务程序(ISR)来处理中断事件。中断服务程序执行完毕后,恢复主程序状态并继续执行。、

如果在处理一个中断时,另一个更高优先级的中断被触发,就会发生嵌套中断。处理器会暂停当前中断服务程序,保存其状态,转而处理更高优先级的中断。待嵌套中断处理完成后,恢复先前中断服务程序的状态并继续执行,直至最终返回主程序,确保系统能够高效、有序地响应各种事件。

3.NVIC中断向量控制器

NVIC(Nested Vectored Interrupt Controller)即嵌套向量中断控制器,是ARM Cortex-M系列微控制器中的一个重要组件,用于管理和控制中断。

  1. 中断管理:NVIC管理系统中的所有中断请求,支持嵌套中断,允许高优先级的中断打断低优先级的中断处理,确保重要任务及时响应。

  2. 优先级控制:NVIC采用二进制优先级位配置中断优先级,不同内核的优先级位数不同,如Cortex-M0和Cortex-M0+有2位,而Cortex-M3、Cortex-M4、Cortex-M7等有8位优先级位,支持更精细的优先级设置,STM32则是Cortex-M3内核,有8位优先级。

  3. 中断向量表:NVIC使用中断向量表来存储中断处理程序的入口地址,当中断发生时,NVIC根据中断向量表找到对应的中断处理程序并执行。

  4. 中断分组:NVIC支持中断优先级分组,用户可以根据需求动态调整抢占和响应优先级的位数比例,提供分组灵活性。

  5. 中断使能/禁止:NVIC提供中断使能寄存器和禁止寄存器,允许开发者根据需要使能或禁止特定的中断。

  6. 软件触发中断:NVIC支持通过软件触发中断,允许开发者在需要时手动触发中断。

  7. 中断状态信息:NVIC提供中断控制器状态寄存器,开发者可以获取中断状态信息,如当前活动的中断等。

  8. 中断嵌套:NVIC支持中断嵌套,即在处理一个中断时,如果另一个更高优先级的中断发生,NVIC会暂停当前中断处理,转而处理更高优先级的中断。

二、EXTI外部中断

外部中断是中断的一种,它是由系统外部的信号源引发的。这些信号源可以是各种外部设备,比如按键、传感器、通信接口等。当这些外部设备发出信号时,处理器会通过外部中断引脚接收到这个信号,然后触发中断。例如,当你按下一个按键时,按键会通过外部中断引脚向处理器发出一个信号,告诉处理器“我被按下了”,处理器就会暂停当前的任务,去处理这个按键事件。

总结一句话就是:外部中断是中断的一种,由系统外部的信号源引发,属于中断机制的一部分,用于处理外部设备产生的事件。

知道了外部中断是什么,那我们就来看看STM32中的外部中断

通过上图可知:

外部中断(EXTI)的配置通常包括以下几个步骤:

1. GPIO配置:首先,需要将相关的GPIO引脚配置为输入模式,并设置为上拉或下拉,以确保引脚在没有外部信号时处于已知状态。

2. EXTI配置:接着,配置EXTI控制器以指定中断的触发条件,例如上升沿、下降沿或双边沿触发。

3. SYSCFG/AFIO配置:在某些微控制器上,需要通过系统配置控制器(SYSCFG)或替代功能输入输出(AFIO)模块将GPIO引脚映射到EXTI线路上。

4. NVIC配置:在嵌套向量中断控制器(NVIC)中使能对应的中断,并设置中断的优先级。

5. 编写中断服务函数:最后,实现中断服务函数(ISR),在其中编写当中断发生时要执行的代码。

接下来我们用代码展示这一过程:

// 使能TIM2的APB1总线时钟和GPIOA的APB2总线时钟
// TIM2用于定时计数,GPIOA用于连接外部触发信号
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);

// 配置GPIOA的第0号引脚为上拉输入模式
// 用于连接外部触发信号,上拉模式确保无信号输入时保持高电平
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);

// 配置TIM2的外部时钟源模式2
//选择时基单元的时钟 外部时钟源(TIM2时钟,是否分频,触发极性(低电平或下降沿),外部触发滤波器)
TIM_ETRClockMode2Config(TIM2,TIM_ExtTRGPSC_OFF,TIM_ExtTRGPolarity_NonInverted,0x09);

// 配置TIM2的时基单元
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;    // 时钟分频因子,不分频
TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; // 向上计数模式
TIM_TimeBaseInitStructure.TIM_Period=10-1;                     // 自动重装载值,计数10次
TIM_TimeBaseInitStructure.TIM_Prescaler=1-1;                   // 预分频器,不分频
TIM_TimeBaseInitStructure.TIM_RepetitionCounter=0;             // 重复计数器值,高级定时器有效
TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);

// 清除TIM2的更新标志位,防止初始化时误触发中断
TIM_ClearFlag(TIM2,TIM_FLAG_Update);

// 使能TIM2的更新中断,当计数器溢出/下溢时产生中断
TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);

// 配置NVIC中断优先级分组为组2(2位抢占优先级,2位响应优先级)
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

// 配置TIM2中断在NVIC中的优先级
NVIC_InitTypeDef NVIC_InitSturcture;
NVIC_InitSturcture.NVIC_IRQChannel=TIM2_IRQn;             // TIM2中断通道
NVIC_InitSturcture.NVIC_IRQChannelCmd=ENABLE;             // 使能中断通道
NVIC_InitSturcture.NVIC_IRQChannelPreemptionPriority=2;   // 抢占优先级为2
NVIC_InitSturcture.NVIC_IRQChannelSubPriority=1;          // 响应优先级为1
NVIC_Init(&NVIC_InitSturcture);

// 启动TIM2定时器,开始计数
TIM_Cmd(TIM2,ENABLE);
Logo

openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。

更多推荐