异常类型
原话:
Cortex‐M3 在内核水平上搭载了一个异常响应系统,支持为数众多的系统异常和外部中断。
其中,编号为 1-15 的对应系统异常,大于等于 16 的则全是外部中断。
除了个别异常的优先级被定死外,其它异常的优先级都是可编程的。
所有能打断正常执行流的事件都称为异常。
- 异常的概念包含中断的概念,即中断是异常的子集。
- 异常与中断都是硬件支持的
异常表:
外部中断表:
这里的“外部中断”不是指STM32中的EXTI中断,而是所有中断。
每一个外设(分管部门):
外设中的每一个外设都有一个自己的中断开关,内核中的系统定时器等也有自己中断开关。能够产生中断的设备通过中断请求线(IRQ line)连到NVIC上面,所有能够产生中断的设备必须要有一根中断请求线。
NVIC(主管家):
NVIC专门管理中断的,每一个中断都要在NVIC中挂号(使NVIC监听器中断请求)。NVIC收到外设的中断请求,会将其中断请求发送给内核,内核收到NVIC的中断通知之后,就会去判断时哪个中断发生,然后查找FLASH中断向量表去获取相应的中断处理函数。
举例:
由简单GPIO电平引起的中断,由专门的部件管理中断,这个部件脚EXTI(外部中断管理控制器)。
某个GPIO需要产生中断,由EXTI使能之后,EXTI会把中断的请求,通知给NVIC,NVIC若对其使能,则NVIC把这个中断请求通知给CORTEX_M3,由CORTEX_M3处理中断。
stm32所有的I/O都可以配置中断。
stm32NVIC中断优先级的配置
stm32中断配置思路
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 个外部中断/事件线上
stm32F10x产品的向量表。
stm32有许多中断,用中断向量表对中断进行管理。中断向量表给每个中断分配一个地址。这个地址里面是一个跳转语句。可以看到每个向量占用4个字节。而这四个字节就可以存储一个跳转指令。
非阴影部分为外设的中断向量,共60个外部中断。4个字节
优先级编号从-3 至 6 的中断向量定义为系统异常;
编号为负的内核异常不能被设置优先级,如复位(Reset)、不可屏蔽中断 (NMI)、硬错误(Hardfault);
从编号 7 开始的为外部中断,这些中断的优先级都是可以自行设置的;
NVIC 是属于Cortex 内核的器件,不可屏蔽中断 (NMI)和外部中断都由它来处理,而SYSTICK 不是由 NVIC 来控制的。