您的位置:首页 > 其它

飞思卡尔Kinetis芯片中NVIC模块的中断寄存器的介绍及其应用举例

2015-12-12 12:43 453 查看
NVIC模块的中断寄存器简介

嵌套式向量中断控制器(NVIC)是Cortex内核不可分割的一部分,它与CPU紧密结合,可对系统异常和外设中断进行控制。如图1所示,NVIC右端连接到各个外围模块,负责对外设中断进行处理;左端连接到内核,负责对内核系统异常进行处理。本文重点介绍NVIC对外围模块的中断控制。通常,在配置某个外围模块的中断功能时,除了需要设置此模块本身的寄存器中的中断使能位外,还需要配置NVIC模块中对应的中断控制寄存器,系统才会响应此外围模块的中断请求。



ARM Cotex-M4的NVIC模块中相关寄存器的地址、名称、功能描述如图2所示,它们可分为两种类型:非优先级中断寄存器(non-IPR register)和优先级中断寄存器(IPR register)。其中,非优先级中断寄存器有以下几种:

NVICISERx:中断使能设置寄存器;

NVICICERx:中断使能清除寄存器;

NVICISPRx:中断挂起设置寄存器;

NVICICPRx:中断挂起清除寄存器;

NVICIABRx;中断激活状态寄存器;

其中x为0 - 7,称为寄存器的组号,表示每种寄存器都有8个。这些寄存器都是32位的。因此,如果每一位控制一个中断源,则可以分别控制256个中断源。通常, NVICISERx(中断使能设置寄存器)用于去使能某个中断,而NVICICPRx(中断挂起清除寄存器)用于配合NVICISERx寄存器来使能这个中断;NVICIABRx(中断激活状态寄存器)为只读寄存器,用于判断某个中断是否处于激活的状态。


而优先级中断寄存器只有一种: NVICIPRx,用于设定每个中断源的优先级。从图3可以看到,每个中断源的优先级控制字要占用4位,再加上保留位,则每个32位的寄存器可以配置4个中断源的优先级。因此,如果要配置256个中断源的优先级,则需要256 ÷ 4 = 64个32位的寄存器。但是Kinetis系列MCU的中断源一般都没有这么多,也就不需要这么多的寄存器。



下面以K60为例进行具体说明。K60支持16级中断控制,所以在NVIC中,对应于不同的中断源,在优先级中断寄存器NVICIPRx中都有4个相应的位来控制其优先级,另外还有4位是保留位,如图3所示。

从图2可以看出,每种非优先级中断寄存器都是一个包含8个32位寄存器的寄存器组。那么在应用过程中,对应于K60的90多种不同的中断源,应该配置这些寄存器组中的哪一个寄存器(组号)和该32位寄存器的那一位(位号)呢?简单来说,就是组号和位号的确定。例如NVICICER2[21],它的组号就是2,位号就是21。这就需要借助芯片厂商在CPU中为不同中断源定义的中断请求号IRQ。需要特别注意的是,中断向量号和中断请求号IRQ号不同,中断请求号IRQ = 中断向量号-16,因为有16个ARM内核中断请求是没有分配IRQ号的。在K60的Reference Manual 的P74页可以看到CPU中断向量分配表,定义了各种不同的中断源所对应的中断入口地址、中断向量号、中断请求号、寄存器号以及彼此之间的关系,如图4所示。


这里结合K60的中断向量分配表,以LPTMR(低功耗定时器)模块为例介绍一下NVIC寄存器的配置。LPTMR模块的中断向量分配如图4所示,可以看到LPTMR中断入口地址为0x0000_0194,中断向量号为101,中断请求号IRQ为85。那么如何确定配置LPTMR中断所对应的NVIC寄存器的组号和位号呢?即LPTMR使用NVIC寄存器组中的哪一个寄存器,以及该寄存器的哪个位呢?它们又和中断向量号 IRQ有什么关系呢,下面分非优先级中断寄存器和优先级中断寄存器分别介绍。

对于非优先级中断寄存器,如上面提到的NVICISERx、NVICICERx、NVICSPRx、NVICCPRx以及NVICABRx,组号的计算公式为IRQ / 32,所以可以得到LPTMR的NVIC非优先级中断寄存器的组号为85 / 32 = 2,从而得到LPTMR需要使用的非优先级中断寄存器为 NVICISER2、 NVICICER2、 NVICISPR2、NVICICPR2、NVICIABR2。这些寄存器都是32位的,所以对应于LPTMR的位号计算公式为IRQ % 32,得到85 % 32 = 21。确定完了组号和位号,便得到了需要设置的LPTMR的非优先级中断控制寄存器及相应的位为:NVICISER2[21]、 强调内容NVICICER2[21]、 NVICISPR2[21]、NVICICPR2[21]、NVICIABR2[21]。

对于优先级中断寄存器IPR,如上所述,因为每一个IPR寄存器可以设置4个中断源的优先级,所以组号计算公式为IRQ / 4 = 21。下面确定位号,前面讲到优先级控制需要4位,另外还有4位保留位,所以每个中断源需要8位,因此位起始号的计算公式为8 * (IRQ % 4) + 4,得到LPTMR的位起始号为8 * (85 % 4) + 4 = 12。确定完了组号和位号,便得到了LPTMR的优先级中断寄存器及相应的位为:NVICIPR21[15:12]。

通常,中断程序的处理流程为:关闭系统总中断、开启外设模块并使能该外设模块中断、配置NVIC模块中的中断寄存器、开总中断等几个过程。

第一步,关闭系统总中断。一般采用宏定义DisableInterrupts,其本质是在内部调用一句汇编代码“CPSID i”。同样,打开总中断一般采用EnableInterrupts,本质是在内部调用一句汇编代码“CPSIE i”。

第二步,开启外设模块并使能其中断。需要设置外设模块的寄存器中的中断使能位。对于LPTMR,需要置位控制状态寄存器LPTMRx_CSR的TIE位。 SIM_SCGC5|=SIM_SCGC5_LPTIMER_MASK; //开LPT模块时钟 LPTMR0_CSR|=LPTMR_CSR_TIE_MASK; //使能LPT定时器中断

第三步,配置NVIC模块的中断寄存器。需要设置NVIC中相关的中断控制寄存器,如上面提到的NVICISERx、NVICICERx、NVICSPRx、NVICCPRx、NVICABRx以及NVICIPRx。值得注意的是,使能一个外设的中断需要完成两个步骤,首先置位 NVICICPRx(中断挂起清除寄存器),然后再置位NVICISERx(中断使能设置寄存器)。其原因在于,在完成第二步开启并使能外设模块中断后,外设模块便可以被触发产生中断请求,这时如果置位NVICISERx(中断使能设置寄存器),程序便可以进入中断服务程序,而这并非程序编写者的本意。所以为避免出现这种情况,需要首先置位NVICICPRx(中断挂起清除寄存器),清除已经挂起的中断,然后再置位NVICISERx(中断使能设置寄存器),等待下一个中断的发生。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: