子优先级至少是1个位。因此抢占优先级最多是7个位,这就造成了最多只有128级抢占的现象(stm32只有4位)。
向量表:当发生了异常并且要响应它时,CM3 需要定位其服务例程的入口地址。这些入口地址存储在所 谓的“(异常)向量表”中。缺省情况下,CM3认为该表位于零地址处,且各向量占用4字节。因此 每个表项占用4字节。 NVIC 的访问地址是0xE000_E000,NVIC 中有一个寄存器,称为“向量表偏移量寄存器”(在地 址0xE000_ED08处),通过修改它的值就能重定位向量表。但必须注意的是:向量表的起始地址是 有要求的:必须先求出系统中共有多少个向量,再把这个数字向上“圆整”到2 的整次幂,而起始 地址必须对齐到后者的边界上。例如,如果一共有32 个中断,则共有32+16 (系统异常)=48 个 向量,向上圆整到2 的整次幂后值为64,因此向量表重定位的地址必须能被64*4=256整除,从而 合法的起始地址可以是:0x0, 0x100, 0x200等。
表7.7 向量表偏移量寄存器(VTOR) (地址:0xE000_ED08 )
位段 名称 类型 复位值 描述
7-28 TBLOFF RW 0 向量表的起始地址
29 TBLBASE R - 向量表是在Code 区(0),还是在RAM区(1)
每个外部中断都在NVIC 的下列寄存器中“挂号”:
使能与除能寄存器
悬起与“解悬”寄存器
优先级寄存器
活动状态寄存器
另外,下列寄存器也对中断处理有重大影响
异常掩蔽寄存器(PRIMASK, FAULTMASK 以及BASEPRI)
向量表偏移量寄存器
软件触发中断寄存器
优先级分组位段
cortex_m3 内核对于每一个外部中断通道都有相应的控制字和控制位,用于单独的和总
的控制该中断通道。它们包括有:
z 中断优先级控制字:PRI_n(上面提到的)
z 中断允许设置位:在 ISER 寄存器中
z 中断允许清除位:在 ICER 寄存器中
z 中断悬挂 Pending(排队等待)位置位:在 ISPR 寄存器中(类似于置中断通道标志位)
z 中断悬挂 Pending(排队等待)位清除:在 ICPR 寄存器中(用于清除中断通道标志位)
z 正在被服务(活动)的中断(Active)标志位:在 IABR 寄存器中,(只读,可以知道当
前内核正在处理哪个中断通道)
中断系统设置全过程的演示
下面给出一个简单的例子,以演示如何建立一个外部中断。
1. 当系统启动后,先设置优先级组寄存器。缺省情况下使用组0 (7位抢占优先级,1位亚优
先级)。
2. 如果需要重定位向量表,先把硬fault和NMI服务例程的入口地址写到新表项所在的地址中。
3. 配置向量表偏移量寄存器,使之指向新的向量表(如果有重定位的话)
4. 为该中断建立中断向量。因为向量表可能已经重定位了,保险起见需要先读取向量表偏移
量寄存器的值,再根据该中断在表中的位置,计算出对应的表项,再把服务例程的入口地址填写进
去。如果一直使用ROM中的向量表,则无需此步骤。
5. 为该中断设置优先级。
6. 使能该中断
如果应用程序储存在ROM中,并且不需要改变异常服务程序,则我们可以把整个向量表编码到
ROM的起始区域(从0地址开始的那段)。在这种情况下,向量表的偏移量将一直为0,并且中断向量
一直在ROM中,因此上例可以大大简化,只需3步:
1. 建立优先级组
2. 为该中断指定优先级
3. 使能该中断
如果在I/O密集型系统中,软件需要控制大量的硬件设备,则可能必须要考虑如下因素:
该芯片支持的中断数
该芯片中表达优先级的位数
对于stm32,实现了16个异常(其中6个保留),实现了60个中断,所以就有两个中断设置使能寄存器ISER0和ISER1,每个可以控制32个中断的使能,也有两个中断清除寄存器ICER0和ICER1.例如RTC中断,向量位置为3,即RTC向量地址为4*(16+3)= 0x4C位置.要实现RTC中断处理,首先在启动文件中0x4C位置放入RTC_IRQHandler()函数的首地址,(keil编译器自动生成)然后ISER0 |= (0x01 << 3);即可.
如果要产生中断,必须事先配置好并使能中断线。根据需要的边沿检测设置2个触发寄存器,同
时在中断屏蔽寄存器的相应位写’1’ 允许中断请求。当外部中断线上发生了需要的边沿时,将产
生一个中断请求,对应的挂起位也随之被置’1’。在挂起寄存器的对应位写’1’,可以清除该中断
请求。
如果要为产生事件,必须事先配置好并使能事件线。根据需要的边沿检测通过设置2个触发寄存
器,同时在事件屏蔽寄存器的相应位写’1’允许事件请求。当事件线上发生了需要的边沿时,将
产生一个事件请求脉冲,对应的挂起位不被置’1’。
通过在软件中断/事件寄存器写’1’,也可以通过软件产生中断/事件请求。
硬件中断选择
通过下面的过程来配置19个线路做为中断源:
● 配置19个中断线的屏蔽位(EXTI_IMR)
● 配置所选中断线的触发选择位(EXTI_RTSR和EXTI_FTSR);
● 配置那些控制映像到外部中断控制器(EXTI)的NVIC中断通道的使能和屏蔽位,使得19个中
断线中的请求可以被正确地响应。
硬件事件选择
通过下面的过程,可以配置19个线路为事件源
● 配置19个事件线的屏蔽位(EXTI_EMR)
● 配置事件线的触发选择位(EXTI_RTSR和EXTI_FTSR)
软件中断/事件的选择
19个线路可以被配置成软件中断/事件线。下面是产生软件中断的过程:
● 配置19个中断/事件线屏蔽位(EXTI_IMR, EXTI_EMR)
● 设置软件中断寄存器的请求位(EXTI_SWIER)
具体配置步骤:配置向量表(在时钟初始化里面)
使能端口(A—G时钟)
设置端口方向,上拉下拉
使能IO复位时钟RCC->APB2ENR
配置外部中断输入源AFIO->EXTICR
开启line BITx上的中断EXTI->IMR
EXTI->FTSR或EXTI->RTSR上升沿或下降沿触发
设置分组SCB->AIRCR
使能中断位NVIC->ISER
抢占优先级和响应优先级NVIC->IPR(不完全手册68页)
最后中断服务函数