官方文档《STM32F10xxx Cortex-M3编程手册》Page 36和37对终端进行了简单的描述如下:
翻译大致为:
如果软件未配置任何优先级,则具有可配置优先级的所有异常的优先级为0.有关配置异常优先级的信息,请参见:
可配置的优先级值的范围为0-255。 这意味着具有固定负优先级值的Reset,HardFault和NMI异常总是具有比任何其他异常更高的优先级。
例如,将较高优先级值分配给IRQ [0],将较低优先级值分配给IRQ [1]意味着IRQ [1]的优先级高于IRQ [0]。 如果IRQ [1]和IRQ [0]都被置位,则在IRQ [0]之前处理IRQ [1]。
如果多个挂起的异常具有相同的优先级,则具有最低异常编号的挂起异常优先。 例如,如果IRQ [0]和IRQ [1]都未决并且具有相同的优先级,则在IRQ [1]之前处理IRQ [0]。
当处理器正在执行异常处理程序时,如果发生更高优先级异常,则异常处理程序被抢占。 如果发生的异常具有与正在处理的异常相同的优先级,则不管异常编号如何,处理程序都不会被抢占。 但是,新中断的状态为待处理。
关于抢占(即STM32中的嵌套)
当一个异常抢占另一个异常时,异常称为嵌套异常。例如,考虑以下所有具有软件可配置优先级编号的例外:
- A具有最高优先级。
- B具有中等优先级。
- C具有最低优先级。
事件序列示例:
- 发生异常B. 处理器接受异常并开始执行此异常的处理程序。 执行优先级为优先级B.
- 发生异常A. 因为它的优先级高于执行优先级,所以它抢占异常B,并且处理器开始执行异常A处理程序。 执行优先级现在是优先级A.
- 发生异常C. 其优先级小于执行优先级,因此其状态为待处理
- 异常A的处理程序将异常A的优先级降低到低于优先级C的优先级。执行优先级落在所有活动异常的最高优先级。 这是优先B.
异常C保持等待,因为其优先级低于当前执行优先级。
只有具有比优先级B高的优先级的挂起异常可以抢占当前异常处理程序。 因此,具有比异常B低的优先级的新异常不能优先于抢占的异常B.
ARM公司的Cortex-m3 内核,支持256个中断,其中包含16个内核中断和240个内部中断,并且具有256级的可编程中断设置。在ST公司的STM32单片机中最多有84个中断,包括16个内核中断(这16个内部中断是任何半导体商也改不了的),和68个可屏蔽中断,具有16级可编程的中断优先级。但是在STM32F103系列中只要60个可屏蔽中断,(107系列有68个)。
针对这60个可屏蔽中断,重点掌握它的一个中断优先级寄存器组IPR,全称Interrupt Priority Registers。这个寄存器组包含15个32位的寄存器,一个可屏蔽中断占用8bit,那么一个寄存器可以控制4个可屏蔽中断,一共15*4=60。然而在这占用的8bit中又只运用了高4bit,这高4bit的分配才是STM32F103系列单片机中断嵌套的设置所在。STM32F103系列的中断嵌套分为5个组,分别是0、1、2、3、4 这5个组,下面是5个组与中断嵌套的对应关系。
组
|
分配结果
|
0
|
0位抢占优先级,4位呼应优先级
|
1
|
1位抢占优先级,3位呼应优先级
|
2
|
2位抢占优先级,2位呼应优先级
|
3
|
3位抢占优先级,1位呼应优先级
|
4
|
4位抢占优先级,0位呼应优先级
|
对于抢占优先级和呼应优先级,只需记住两点,第一、抢占任何优先级比都比一切呼应优先级优先级高。只要抢占优先级更高的具有中断嵌套功能。(即打断其他正在执行的中断)。第二、数字越小优先级越高 ,抢占优先级和呼应优先级都一样时,首先呼应中断通道对应中断向量地址低的那个中断。
对0组和1组的情况做一个分析:
0组对应是0位抢占优先级,4位呼应优先级,那么无抢占优先级,呼应优先级可设置为0到15级(2的4次方种)中的任意一种。
1组对应是1位抢占优先级,3位呼应优先级,那么抢占优先级只可设置为0级或者1级中的任意一种(2的1次方种),呼应优先级可设置为0到7级(2的3次方种)中的任意一种。
上电复位时,中断配置为4组,并且60个内部中断都是抢占优先级为0级,无呼应优先级。
所以可以看出判断两个中断的优先级时先看抢占优先级的高低,如果相反再看呼应优先级的高低。如果全都相反最后看中断通道向量地址。
普通来说在运用过程中,一个零碎运用一个组别就完全可以满足需求。所以在运用一个组别后普通不要在零碎中再改动组别,骨灰级玩家可以去试试(小心芯片烧了)。
内部中断:
STM32F103的内部中断EXTI支持19个内部中断/事情请求。每个中断/事情都有独立的触发和屏蔽设置。
0到15线:对应内部I/O口输入中断
线16:接到PVD输入
线17:接到RCT闹钟事情
线18:接到USB唤醒事情
线0到15的I/O输入中断这16个内部中断中,其中0到4线,这5个内部中缀都有本人单独的中断呼应函数。5到9线公用一个中断服务函数,10到15线公用一个中断服务函数。
内部中断配置寄存器组EXTICR包含4个32位的寄存器,分别是EXTICR0、EXTICR1、EXTICR2、EXTICR3、但每一个寄存器只用了低16位,每4位控制一个I/O口,一个寄存器控制4个I/O口,EXTICR寄存器组控制16个I/O口,刚好一个GPIO的I/O口数。下面以 EXTICR0为例,用一个表格表示:
I/O口3
|
I/O口2
|
I/O口1
|
I/O口0
|
0000 GPIOA
|
0000 GPIOA
|
0000 GPIOA
|
0000 GPIOA
|
0001 GPIOB
|
0001 GPIOB
|
0001 GPIOB
|
0001 GPIOB
|
0010 GPIOC
|
0010 GPIOC
|
0010 GPIOC
|
0010 GPIOC
|
0011 GPIOD
|
0011 GPIOD
|
0011 GPIOD
|
0011 GPIOD
|
0100 GPIOE
|
0100 GPIOE
|
0100 GPIOE
|
0100 GPIOE
|
0101 GPIOF
|
0101 GPIOF
|
0101 GPIOF
|
0101 GPIOF
|
0110 GPIOG
|
0110 GPIOG
|
0110 GPIOG
|
0110 GPIOG
|
比如配置GPIOA.0就是将EXTICR0的低4位配置成0000,若配置GPIOB.1就是配置EXTICR0的4到7位,为0001。留意运用固件库时中断复位函数是写在stm32f10x_it.c这个文件里的。