1.中断的基本介绍
1.1.中断的基本概念
在处理器中,中断是一个过程,即CPU在正常执行程序的过程中,遇到外部/内部的紧急时间需要处理,暂时中止当前程序的执行,转而去处理紧急的时间,等待紧急事件处理完毕后再返回被打断的程序处继续往下执行。
举例来说就是,当你在看电视的时候,电话突然响了,那么你就会暂停看电视这一行为,转而去接电话,而接电话这一行为就是我们日常生活中的中断现象。
中断可以提高CPU的效率,同时对突发事件做出实时处理。实现程序的并行化,实现嵌入式系统进程之间的切换。
1.2.中断的处理过程
中断的处理过程包括进入中断和退出中断
进入中断过程中,处理器会自动保护现场,将进入中断前的各个寄存器的数值压入栈中,进行现场保护;处理器完成中断程序以后,会返回主程序的运行中,处理器会从栈中将保护的数值重新拿出,执行出栈操作,从而回到正常的处理器执行过程中。
1.3.stm32f1系列中断体系结构
上图即为stm32f1系列中断体系结构,其中NVIC为嵌套向量中断控制器,位于cortex-M3内核之中,是arm公司设计的,专门用于管理中断的控制器,对于所有的内核中断,包括复位、总线错误、滴答定时器等,以及所有的外部中断,包括EXTI外部中断、串口中断、定时器中断等等都是通过NVIC来进行控制的。我们第二节来详细介绍NVIC嵌套向量中断控制器。
2.中断向量控制器
NVIC主要有以下三个功能
- 中断管理
- 支持异常及中断向量化处理
- 支持嵌套中断
2.1.中断管理
cortex-M3支持256个中断(通过8个寄存器来控制,每个寄存器32位。刚好支持256个中断)。其中包括16个内核中断和240个外部中断。但是stm32f1并没有使用cortex-M3的所有中断,而是只使用了一部分,另外的部分进行保留。
在cortex-M3处理器中,每个外部中断都能够被使能或者禁止,并且可以被设置为挂起状态或者清除状态。
2.2.中断和异常向量表
CM3内核支持256级中断,stm32f1虽然没用这么多中断,但是stm32f1中的中断也有很多。当中断发生时,如何快速相应中断就成为了一件非常重要的事情。
我们知道,CPU的程序运行到哪个地方,都是通过指令地址计数器PC控制的,当PC指向哪个地方,哪个地方的程序就会进行运行。所以这样就为中断的响应提供了一个思路。
所以每当异常或者中断放生时,处理器会把PC设置为一个特定地址,这一地址就称为异常向量。每一类异常源都有对应一个特定的入口地址,这些地址按照优先级排列以后就组成一张异常向量表,每次异常出现时,CPU都会快速进行异常向量表的定位,从而进行中断的快速相应。
上图为中断及异常向量表的部分截图。
注:异常一般是指内核中断,中断一般是指外部中断
2.3.嵌套中断
中断嵌套是指,当一个中断程序正在运行时,又有新的更高级的优先级的中断源申请中断,CPU再次暂停当前中断程序,转而去处理新的中断程序,处理完成后依次返回。
上图就为中断嵌套程序的响应过程。
如果要介绍中断嵌套,那么就要提到中断优先级,其中中断优先级包括抢占优先级和响应优先级,抢占优先级在前,响应优先级在后。在NVIC中有一个专门的寄存器:中断优先级寄存器NVIC_IPRx用来配置外部中断的优先级,IPR的宽度为8位,原则上可以可配置255级优先级,但是,CM3芯片都会精简设计,只使用IPRx中的高4位。
在IPR中的4位,又分为抢占优先级和响应优先级,这两个优先级各占及各位又要根据SCB->AIRCR中的中断分组设置来决定,在一个项目中,当优先级分组确定以后,整个工程项目都要使用这个优先级分组,不再改变。
中断优先级总结
- 抢占优先级的级别高于响应优先级。而数值越小所代表的优先级越高。同一时刻发生的中断,优先处理优先级较高的中断。
- 高优先级的抢占优先级是可以打断正在进行的低抢占优先级中断的。而抢占优先级相同的中断,高优先级的响应优先级不可以打断低响应优先级的中断。
- 抢占优先级相同就看响应优先级,同样数值越小优先级越高。
- 如果两个中断的抢占优先级和响应优先级都是一样的话,则看哪个中断先发生就先执行。如果同时发生则优先处理编号较小的那个。
3.外部中断控制器
stm32有很多的外部中断,我们以GPIO的外部中断(EXTI)为例,EXTI一般用于控制由GPIO口高低电平变化而引发的外部中断。
3.1.EXTI(Extern Interrupt)外部中断
- EXTI可以监测指定GPIO口的电平信号,当其指定的GPIO口产生电平变化时,EXTI将立即向NVIC发出中断申请,经过NVIC裁决后即可中断CPU的主程序,使CPU执行EXTI对应的中断程序。
- 支持的触发方式:上升沿、下降沿、双边沿、软件触发
- 支持的GPIO口:所有GPIO口,但相同的Pin不能同时触发中断。
- 通道数:16个GPIO_Pin,外加PVD输出、RTC闹钟、USB唤醒、以太网唤醒。
- 触发响应方式:中断事件响应。
3.2.EXTI基本结构
每个GPIO都有16根数据线连接出来,但是,不可能每个GPIO口都要接入到EXTI控制器中,所以会经过AFIO的中断引脚选择,这个AFIO我们后续再继续说,所以通过这个中断引脚选择,以后,就可以将每个GPIO组选择到的信号线连接到EXTI中,并且加上PVD、RTC、USB、ETH这四个信号线就组成EXTI的20个输入信号。这20个输入信号经过EXTI以后就可以分成两个部分,一部分通向NVIC用于引发中断,另一部分可以通过20根数据线进入其他外设来引发触发事件响应。
3.3.AFIO中断引脚选择器详解
由于不可能每个GPIO口都接入到EXTI控制器中,所以会经过AFIO中断引脚选择,这个AFIO主要是用于引脚复用功能的选择和重定义。在stm32中,AFIO主要完成两个任务:复用功能引脚重映射、中断引脚选择。
下面是AFIO的基本结构:
从图中我们可以看到,每个GPIO组的相同编号的IO口是无法实现同时中断的,所以我们上面说所有的GPIO口,相同的Pin无法同时触发中断,这一点编程的时候要注意。
3.4.EXTI外部中断/事件框图
- 首先通过①来进行输入线电平的变化;
- 通过②边沿检测电路来检测上升沿或者下降沿或者上升、下降沿都可以产生中断(本文前面提到过,上升沿、下降沿或者双边沿都可以产生中断);
- 通过③这个或门来检测,因为不光有GPIO电平的变化,还有就是通过软件或者事件来进行的触发,这两个触发方式只要有一个触发,就会通过或门进入;
- 通过⑤挂起请求寄存器来决定是否将中断申请挂起,如果有优先级高的中断正在执行的时候,挂起寄存器就会将此次申请的中断记录下来并且挂起,如果优先级高的中断响应完成后,就可以执行挂起中断中优先级最高的中断。
- 通过④中断屏蔽寄存器来确定此次中断是否被屏蔽,如果中断未屏蔽,那么就会将信号传递到NVIC中断控制器中来响应此次中断。
- 或者通过⑥来触发其他硬件设备来完成必要的动作。
4.外部中断控制LED灯亮灭代码实现
4.1.cubemx配置
cubemx的配置和原来GPIO的配置是相同的,不同之处在于引脚的配置和中断的配置,具体不同点如下:
- 配置端口
- 配置NVIC
4.2.按键中断具体代码实现
以上就是通过PA2口的外部中断来实现PA1口LED灯亮灭的具体函数,可以动手来试一试。
5.EXTI的相关寄存器(了解即可)
和EXTI有关的寄存器主要有以下几个寄存器
- 中断屏蔽寄存器(EXTI_IMR)
- 事件屏蔽寄存器(EXTI_EMR)
- 上升沿触发选择寄存器(EXTI_RTSR)
- 下降沿触发选择寄存器(EXTI_FTSR)
- 软件中断事件寄存器(EXTI_SWIER)
- 挂起寄存器(EXTI_PR)
由于EXTI有19个外部线连接(包括16个GPIO组)、PVD、RTC、USB(互联型产品还包括以太网唤醒),所以每个EXTI寄存器的位都是由19个位组成的。
5.1.中断屏蔽寄存器
中断屏蔽寄存器主要是用来屏蔽来自线x上的中断请求的。
如果将中断屏蔽寄存器上的对应位置0,则该位上的中断请求就会被屏蔽,那么中断请求就无法输送到NVIC。
5.2.事件屏蔽寄存器
事件屏蔽寄存器的作用和中断屏蔽寄存器的作用相似,都是用来屏蔽中断的,但是事件屏蔽寄存器是用来屏蔽线x上的事件的。同样,置0则屏蔽中断。
5.3.上升沿触发选择寄存器和下降沿触发选择寄存器
这两个寄存器主要是用来进行外部边沿唤醒中断使用的,当选择下降沿或者上升沿触发外部中断的时候,这两个寄存器就会进行配置。
5.4.软件中断事件寄存器
软件中断事件寄存器主要是和软件中断事件有关的寄存器,我们平常不太使用这一寄存器,了解即可。
5.5.挂起寄存器
挂起寄存器主要是用来进行中断挂起的,我们前面提到过,如果优先级高的中断正在执行,当优先级较低的中断发出信号的时候,是无法打断高优先级的中断的,因此需要将此中断暂时进行挂起,这个中断挂起寄存器就是用来进行中断挂起的。
以上就是关于中断的相关知识点,欢迎大家批评指正并进行补充。