中断是指CPU在正常执行程序时,遇到外部/内部的紧急事件需处理,暂停当前程序的执行,转而去处理紧急事件,待事件处理完毕后,返回被打断的程序继续执行,这个过程就称之为中断。
中断的意义:提高CPU的效率,并且能实时处理紧急事件;中断在多任务处理中,尤其重要。
一个完整的中断处理过程可分为4个步骤:中断请求、中断响应、中断服务和中断返回。
中断请求:中断源向CPU发出中断请求信号,此时的中断控制系统的中断请求寄存器置位,向CPU请求中断。
中断响应:CPU的中断系统根据情况判断中断请求是否暂停当前程序转而执行中断程序。具体的判断条件:
(1)中断源发出中断请求。
(2)系统允许中断提出中断请求,即中断没有屏蔽。
(3)无同级或更高的中断正在处理。
中断服务:为处理中断而写的程序称为中断程序。中断程序的入口地址称为中断向量,所有的中断向量汇成一张表,称为中断向量表。具体的中断向量表可以查看stm32的技术参考手册(寄存器)。
中断返回:中断程序执行结束后,返回被打断的主程序的断点。
在CPU中断响应后要去处理中断程序之前,断点的状态参数要放入堆栈中,即保护“现场”,中断程序执行结束后,将压入堆栈的状态参数送回到原来的寄存器,即出栈,才能准确地返回到断点。
异常与中断的概念相近,异常是指由内核产生的中断。如指令执行错误。
如果没有特殊说明,中断特指外部中断,外部中断:由外部设备或外部信号引发,例如按键按下、外部传感器信号变化等。外部中断用于响应外部事件,并及时处理相关任务。在使用STM32中,无须严格区分中断和异常。
中断管理:Cortex-M4内核支持256个中断,其中16个内部中断(异常)和240个外部中断,并且具有256级可编程的中断优先级设置。实际上,stm32只使用了其中的部分中断,STM32F407系列也只使用了10个内部中断和82个外部中断。当异常或中断发生时,内核响应中断就需要获取这些异常或中断服务程序的入口地址,把这些中断入口地址组成一张表,该表称为中断向量表。
中断嵌套:当一个中断程序运行时,又有新的更高优先级的中断源申请中断时,CPU会暂停当前的中断程序,转而去执行新的中断程序。
STM32通过Cortex-M4内部集成的NVIC(嵌套向量中断控制器)实现中断优先级管理。除了3个固定的高级优先级(Reset、NMI、硬件失效)不可编程外,其余优先级都可编程。stm32使用Cortex-M4的8位中断优先级寄存器(IPR)中的4位来配置优先级来配置中断优先级,即STM32中的NVIC支持16级中断优先级管理。
而IPR中的4 位,又分为抢占优先级和响应优先级。抢占优先级在前,响应优先级在后。
抢占优先级的级别高于响应优先级,高优先级的抢占优先级是可以打断正在进行的低抢占优先级中断的。
而抢占优先级相同的中断,高优先级的响应优先级不可以打断低响应优先级的中断。抢占优先级相同就看响应优先级,同样数值越小优先级越高。
在stm32中的片内外设(串口、定时器、I2C等)直接由NVIC负责,STM32的片外外设由NVIC和EXTI(外部中断/事件控制器,External interrupt/event controller)负责,即每个GPIO引脚都可以配置为一个外部中断触发源。
注:事件属于硬件触发执行的过程,而中断是由软件实现相应功能的。
每个GPIO都可以触发一个外部中断,供外部中断使用的中断线只有16条,那STM32是怎么把这16根中断线与I/O口对应上的?
GPIO的中断是以组为单元的,每一组编号相同的GPIO管脚连接到同一个信号选择器中,同组的外部中断就共用一条外部中断线。例如,PA0、PB0、PC0、PD0、PE0、PF0、PG0、PH0、PI0为一组,若使用PA0作为外部中断源,那么PB0、PC0、PD0、PE0、PF0、PG0、PH0、PI0就不能同时作为外部中断使用了。
就是配置相同编号的GPIO管脚哪一个作为外部中断,使用到系统控制配置器(SYSCFG)的外部中断配置寄存器
SYSCFG该器件具有一组配置寄存器。系统配置控制器的主要用途如下:
● 重映射存储器到代码起始区域。
● 管理连接到 GPIO 口的外部中断。
● 管理系统的可靠性特性。
(SYSCFG_EXTICR1)配置EXTIx(x=0到3)的外部中断源选择,(SYSCFG_EXTICR2)配置EXTIx(x=4到7)的外部中断源选择,(SYSCFG_EXTICR3)配置EXTIx(x=8到11)的外部中断源选择,(SYSCFG_EXTICR4)配置EXTIx(x=12到15)的外部中断源选择。
EXTI外部中断内部功能框图
输入线即外部的GPIO管脚,经过边沿检测电路,实现输入信号的上升沿检测或下降沿检测,若此时上升沿检测或下降沿这两个触发选择寄存器有触发信号,则发生外部硬件触发信号;或者软件中断事件寄存器产生软件触发信号,中断屏蔽寄存器没有屏蔽,且请求挂起寄存器没有挂起,就会发生一个中断,该中断信号发至NVIC中断控制器进行处理。若此时事件屏蔽寄存器没有屏蔽,则发生一个事件,该信号发送到其他模块。