中断的基本知识
中断的概念
在处理器中,中断相当于是对于突发事件的处理过程。当遇到内部或外部的紧急事件需要马上处理时,暂时终止当前程序,优先处理紧急事件。等紧急事件处理完毕后,再返回被打断的程序继续执行。
暂停保护现场,继续恢复现场。
为什么要使用中断,中断有什么意义
传统的程序执行是顺序执行的,按照代码的顺序一行行的执行,这种执行方式的问题是程序执行某个任务时,即使发生了突发事件,程序也要等当前任务结束后才能处理突发事件。这就导致了处理延时,影响系统的响应速度。
中断能够对突发事件进行及时处理,实现程序的并行化,进而提高了cpu的运行效率。当发生突发事件后,中断会立即打断当前正在执行的程序,转而执行中断服务程序(ISR)来处理突发事件。
并行化:指通过使用中断机制,使得当发生突发事件时,可以立即处理该事件,而不需要等待当前正在执行的程序完成。
中断的处理过程
通过一张图来具体的分析一下中断的处理过程,图示如下。
由上图可以清楚的看到整个中断的处理过程。
首先,主程序运行过程中,突发事件发生,触发中断。处理器会自动保存现场到堆栈(内存)里。等入栈结束后,也就是保存现场完成 ,就可以执行中断服务程序(ISR)。ISR执行完毕后,即处理完突发事件后,退出中断。处理器开始恢复中断前的现场,即出栈。等出栈完成后继续执行被打断的程序(出栈的过程也可被打断,使得随时可以响应新的中断而不再进行)
总结一下:正常执行的主程序->产生一个中断信号->压栈保护现场->根据中断向量表跳转到相应的中断服务程序->执行中断服务程序->出栈恢复现场并继续执行原程序。
下图是一张中断体系结构的图。
根据这个图我们可以看出两个处理中断的模块,分别是NVIC(内核中的中断处理)和EXTI(外部中断处理)。
解释一下中断和异常的区别:
中断是由外部原因引起,而异常是由CPU内部引起。中断主要是为了支持程序的并行化。而异常的引入表示CPU执行指令时本身出了问题。异常是在正常代码序列之外引起程序流控制更改的事件,发生异常时执行的软件代码称为异常处理程序,异常处理程序是已编译程序映像中的程序代码的一部分。
NVIC
嵌套向量中断控制器
它的主要功能如下:
负责中断处理(CPU的助理)
中断管理
支持异常和中断向量化处理
支持嵌套中断
1.管理中断事件:每一个中断事件都有执行或禁止两种状态,由NVIC负责将中断事件标记为清除和挂起两种状态。处理器的中断可以是电平形式的,也可以是脉冲形式的,这样中断控制器就可以处理任何中断源(当中断执行完成时,NVIC会将中断事件置为清除状态)
2.支持中断向量化处理(向量表):当中断事件发生时,CPU会把程序计数器PC设置为一个特定地址(中断服务程序的入口地址),进而跳转到中断服务程序去执行。这就是一个中断向量,每一个中断事件都会对应一个服务程序的入口地址,将这些地址按照优先级排序后(数字越小,优先级越高),组成的一张表就是中断向量表。
3.支持中断嵌套:要想使用中断嵌套,首先需要在NVIC中给每个中断事件配置优先级,中断嵌套使得某个中断能够打断正在执行的较低优先级中断,从而及时响应更高优先级的中断请求。
3个固定的优先级,都是负值,不能改变。四个可编程优先级,用两个bit位表示,00,01,10,11(0、1、2、3)
同样优先级的中断同时发生,中断向量号较小的那个优先响应(响应优先级)
EXTI外部中断控制器
下面是一张外部中断控制器的图
EXTI的主要特性如下:
1.支持26个输入事件
2.所有事件输入都允许唤醒系统的可能性。
3.在外设中没有关联的唤醒标志的事件,在EXTI中有一个标志,并从EXTI生成一个中断到CPU。事件可用于生成CPU唤醒事件。
可配置的事件有以下特点:
1.可选择的主动触发边沿
2.中断挂起状态寄存器位独立于上升沿和下降沿,单个中断和事件生成掩码,用于调节CPU唤醒、中断和事件生成。
注:EXTI多路复用器允许选择GPIO作为中断和唤醒,GPIO通过16条EXTI多路复用线连接到前16个EXTI事件,不同端口组的相同引脚共享同一个EXTI线。当多个相同引脚同时中断时,会产生无法区分的问题。
下图是外部中断的处理流程图
编号①是信号输入线,用于输入中断请求。编号②是边沿检测电路,用于检测是上升沿还是下降沿。编号③是一个或门电路,信号来源是外部事件或者软件中断/事件寄存器产生。编号④是一个与门电路,信号来源是编号③送来的信号和中断屏蔽寄存器的值,如果中断屏蔽寄存器为0,也不会将信号送到NVIC,只有编号③送来了中断信号且中断屏蔽寄存器允许产生中断,才会将中断信号送入NVIC。编号⑤是一个与门电路,信号来源是编号③送来的信号和事件屏蔽寄存器的值,如果事件屏蔽寄存器为0,不会将信号送到脉冲发生器,只有编号③送来了信号且事件屏蔽寄存器允许产生事件,才会将信号送入脉冲发生器(编号⑥)
相关实验练习
外部中断实验(按键中断)
编程思路:
1.时钟使能
2.在stm32cubemx中配置GPIO引脚为中断功能
3.设置相应的中断优先级
4.使能中断
5.编写中断服务程序
根据开发板的原理图显示,按键按下时为低电平
下面是cubemx配置
1.配置PC9按键为中断,PC7风扇为输出
2.配置PC9为下降沿
3.NVIC使能EXTI中断
程序编写:
根据追函数的方式先找到中断向量表,根据中断向量表找到中断服务程序。
根据中断服务程序找到中断回调函数
重写回调函数实现功能(按下按键开/关风扇)
volatile uint8_t a=0;
void HAL_GPIO_EXTI_Falling_Callback(uint16_t GPIO_Pin)
{
if(GPIO_Pin==GPIO_PIN_9)
{
a=1;
}
}
在main函数中实现功能
while (1)
{
extern volatile uint8_t a;
if(a==1)
{
HAL_Delay(100);
if(HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_9)==0)
{
a=0;
HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_6);
}
}
}