EXTI
EXTI (External interrupt) 就是指外部中断,通过 GPIO 检测输入脉冲,引起中断事件,打断原来的代码执行流程,进入到中断服务函数中进行处理,处理完后,再返回到中断之前的代码中执行。
STM32 的所有 GPIO 都可以用作外部中断源的输入端,利用这个特性,我们可以把按键轮询检测 改为由中断 来处理,大大提高软件执行的效率。
Cortex 内核具有强大的异常响应系统,它把能够打断当前代码执行流程的事件分为异常(exception)和中断(interrupt),并把它们用一个表管理起来,编号为 0~15 的称为内核异常,而 16 以上的则称为外部中断(外,相对内核而言),这个表就称为中断向量表。
而 STM32 对这个表重新进行了编排,把编号从-3 至 6 的中断向量定义为系统异常,编号为负 的内核异常不能被设置优先级,如复位(Reset)、不可屏蔽中断 (NMI)、硬错误(Hardfault)。从编号 7 开始的为外部中断,这些中断的优先级都是可以自行设置的。详细的 STM32 中断向量表见图 ,STM32 中断向量表STM32 的中断如此之多,配置起来并不容易,因此,我们需要一个强大而方便的中断控制器 NVIC (Nested Vectored Interrupt Controller)。NVIC 是属于Cortex 内核的器件,不可屏蔽中断 (NMI)和外部中断都由它来处理,而SYSTICK 不是由 NVIC 来控制的。
NVIC
当我们要使用 NVIC 来配置中断时,自然想到 ST 库肯定也已经把它封装成库函数了。查找库帮助文档,发现在 Modules->STM32F10x_StdPeriph_Driver->misc 查找到一个 NVIC_Init() 函数,对 NVIC 初始化,首先要定义并填充一个NVIC_InitTypeDef 类型的结构体。
这个结构体有四个成员
前面两个结构体成员都很好理解,首先要用 NVIC_IRQChannel 参数来选择将要配置的中断向量,用 NVIC_IRQChannelCmd 参数来进行使能(ENABLE)或关闭(DISABLE)该中断。在NVIC_IRQChannelPreemptionPriority 成员要配置中断向量的抢占优先级,在 NVIC_IRQChannelSubPriority 需要配置中断向量的响应优先级。对于中断的配置,最重要的便是配置其优先级,但 STM32 的同一个中断向量为什么需要设置两种优先级?这两种优先级有什么区别?
抢占优先级和响应优先级
STM32 的中断向量具有两个属性,一个为抢占属性,另一个为响应属性,其属性编号越小,表明它的优先级别越高。抢占,是指打断其它中断的属性,即因为具有这个属性,会出现嵌套中断(在执行中断服务函数 A 的过程中被中断 B 打断,执行完中断服务函数 B 再继续执行中断服务函数 A),抢占属性由 NVIC_IRQChannelPreemptionPriority 的参数配置。而响应属性则应用在抢占属性相同的情况下,当两个中断向量的抢占优先级相同时,如果两个中断同时到达,则先处理响应优先级高的中断,响应属性由 NVIC_IRQChannelSubPriority 的参数配置。
例如,现在有三个中断向量
若内核正在执行 C 的中断服务函数,则它能被抢占优先级更高的中断 A 打断,由于 B 和 C 的抢占优先级相同,所以 C 不能被 B 打断。但如果 B 和 C 中断是同时到达的,内核就会首先响应响应优先级别更高的 B 中断
NVIC 的优先级组
在配置优先级的时候,还要注意一个很重要的问题,中断种类的数量。NVIC 只可以配置 16 种 中断向量的优先级,也就是说,抢占优先级和响应优先级的数量由一个 4 位的数字来决定,把这个 4 位数字的位数 分配成抢占优先级部分和响应优先级部分。有 5 组分配方式:
第 0 组:
所有 4 位用来配置抢占优先级,即 NVIC 配置的 2 4 =16 种中断向量都是只有抢占属性,没有响应属性。
第 1 组:
最高 1 位用来配置抢占优先级,低 3 位用来配置响应优先级。表示有 21=2 种级别的抢占优先级(0 级,1 级),有 23=8 种响应优先级,即在 16种中断向量之中,有 8 种中断,其抢占优先级都为 0 级,而它们的响应优先级分别为 0~7,其余 8 种中断向量的抢占优先级则都为 1 级,响应优先级别分别为 0~7。
第 2 组:
2 位用来配置抢占优先级,2 位用来配置响应优先级。即 22=4 种抢占优先级,22=4 种响应优先级。
第 3 组:
高 3 位用来配置抢占优先级,最低 1 位用来配置响应优先级。即有 8 种抢占优先级,2 种响应 2 优先级。
第 4 组:
所有 4 位用来配置响应优先级。即 16 种中断向量具有都不相同的响应优先级。
要配置这些优先级组,可以采用库函数 NVIC_PriorityGroupConfig(),可输入的参数为NVIC_PriorityGroup_0 ~ NVIC_PriorityGroup_4,分别为以上介绍的 5 种分配组。
于是,有人觉得疑惑了,如此强大的 STM32,所有 GPIO 都能够配置成外部中断,USART、ADC 等外设也有中断,而 NVIC 只能配置 16 种中断向量,那在某个工程中使用了超过 16 个的中断怎么办呢?注意 NVIC 能配置的是 16种 中断向量,而不是 16 个,当工程之中有超过 16 个中断向量时,必然有 2 个以上的中断向量是使用相同的中断种类,而具有相同中断种类的中断向量不能互相嵌套。
STM2 单片机的所有 I/O 端口都可以配置为 EXTI 中断模式,用来捕捉外部信号,可以配置为下降沿中断,上升沿中断和上升下降沿中断这三种模式。它们以下图的方式连接到 16 个外部中断/事件线上
EXTI 外部中断
STM32 的所有 GPIO 都引入到 EXTI 外部中断线上,使得所有的 GPIO 都能作为外部中断的输入源。GPIO 与 EXTI 的连接方式见图
观察这个图知道,PA0~PG0 连接到 EXTI0 、PA1~PG1 连接到EXTI1、 ……、 PA15~PG15 连接到 EXTI15。这里大家要注意的是:PAx~PGx端口的中断事件都连接到了 EXTIx,即同一时刻 EXTx 只能相应一个端口的事件触发,不能够同一时间响应所有 GPIO 端口的事件,但可以分时复用。它可以配置为上升沿触发,下降沿触发或双边沿触发。EXTI 最普通的应用就是接上一个按键,设置为下降沿触发,用中断来检测按键。
来源:oschina
链接:https://my.oschina.net/u/4383286/blog/4440596