NVIC寄存器组中的中断挂起SETPEND与消除CLRPEND,与外部中断挂起寄存器EXTI_PR

转载自http://www.openedv.com/forum.php?mod=viewthread&tid=275832&page=1

STM32的中断控制是分级管理的,CM3内核中的NVIC是顶层,对每个通道都设有1BIT的中断挂起位,
但每个通道可能不止一个中断源,比如EXTI5_9_IRQn,对NVIC而言,只算一个通道,但实际包含有5个中断源,
因此,下层就必须实现对这多个中断源的独立监控,这就是EXTI->PR中的挂起位了。

STM32的中断系统可以理解为分两级管理,
顶层当然是CM3内核强大的NVIC,下层就是形形色色的片上外设了,
对于NVIC来说,它最大可以管理256个不同的中断通道,
这256个中断,内核自留了16个,剩下的通称为外部中断(注意与EXTI不要混淆,EXTI是外部中断中的一小部分,全称为外部线中断),外部中断可以多达240个(具体的芯片只实现了约60多个)。
这240个中断通道,在CM3的内核中,每一个中断都标配如下的控制:
1、中断优先级寄存器IP:8位(一般芯片只具体实现了高4位可表达16个优先级)
2、中断使能SETENA:1位,写1使能,写0无效
3、中断禁能CLRENA:1位,写1禁能,写0无效。 以上二者是联动的,实际只相当于1位,要使能就置SETENA位,要禁能就置CLRENA
4、中断挂起SETPEND:1位,写1挂起,写0无效,中断请求收到但暂不能服务时,置1,进入中断服务后由硬件清除
5、中断解挂CLRPEND:1位,写1解挂,写0无效。以上二者是联动的,实际只相当于1位,要挂起就置SETPEND位,要解挂就置CLRPEND
6、中断活动状态ACTIVE:1位,用于指示该中断是否处于活动状态,只读,从进入中断服务程序开始由硬件置位,直到中断服务返回由硬件清除。

以上几个内核寄存器(位)中,用户编程经常用到是主要是前3项,我们需要用到某个中断的时候,首先就是设置优先级,ENABLE中断,库函数所执行的就是对这前3项的设置,使用寄存器编程的同学也经常会直接操作;
后3项,用户编程基本用不到,包括使用寄存器编程的同学,甚至都感觉不到它们的存在,没有特殊需求的都任由硬件自由操作了。

NVIC是如何访问这些众多的寄存器或控制位的呢? 靠的就是中断通道号。
NVIC唯一认识的ID,也就是中断通道号,说白了就是0-239的号码牌IRQn,
NVIC就根据此号码去找相应的控制位(或寄存器),达到管理这240个中断通道的目的。
根据这个号码也可以从向量表中找到对应的中断服务程序入口(地址偏移量=0x0000 0040+IRQn*4)

其实虽说NVIC强大,但也可以说傻得可以,它其实根本不知道中断的具体来头,只须照章办事。
来了IRQ后,根据IRQn编号值去查相应的控制位(或寄存器),严格走下述流程:
1、首先是看该IRQ是否使能,只有使能位为1,才能受理申请,如果是禁能状态,则直接无视;
2、然后查看优先级寄存器IP[IRQn],该IRQ的优先级;
3、再通过查看ACTIVE可知,目前处于活动状态的所有中断;
4、如果有正在活动状态的中断(即正在服务中),则进行中断优先级比较。如果活动的中断优先级高,则先挂起这个IRQ。
反复此步,直到没有更高优先级的中断需要服务;
5、轮到这个IRQ享受服务(由编号查向量表进入对应的中断服务程序,服务开始后置位它对应的中断活动状态位),解挂。
第5步里,就是NVIC对挂起和解挂的操作,这算是CM3内核的硬件自动完成的。
但它也允许软件来手动干预,手动挂起相当于来一次软件IRQ申请,手动解挂相当于软件撤消IRQ申请。

至于形形色色的片上外设的中断控制,则属于NVIC的下级机构了,
必须注意的是,这些下级机构,按上面的描述,一个IRQ号算一个下级机构的话,最大可达240个。
如果一个IRQ号只有一个中断源的话,就简单了,下级机构根本无须额外的控制功能,
直接由NVIC代管,用NVIC的中断使能、中断挂起位可以了。
但是实际上,多数情况下,每个IRQ的中断源,往往不止一个。
这样,就必须在外设中增加控制功能了。
不同的外设设置的控制功能可能略有不同,名称可能也有差异,但万变不离其宗,基本都是有如下控制:
中断屏蔽(或使能)
中断挂起(或标志)
前者进行控制,后者显示状态。

比如EXTI5_9_IRQn对于NVIC来说,只是一个中断,编号为23
但实际却包括了5个中断源,这一点NVIC根本是不知情的。EXTI5_9_IRQn是我们编的一个符号,实际就是一个常数,值为23(本文称为编号)
这5个中断源就具体由下级机构来管理了,每个都必须要有:
中断屏蔽位:是否受理该中断请求(在EXTI->IMR中)
中断挂起位:是否发生了该中断请求(在EXTI->PR中)
只要这5个中任一个或多个触发了中断条件(上升沿/下降沿等),相应的中断挂起就会被硬件置位,如果对应的一个或多个中断屏蔽是开放的,都会产生向NVIC发出EXTI5_9_IRQn号中断请求
至于这个EXTI5_9_IRQn是谁发的,是EXTI5、EXTI6、EXTI7、EXTI8还是EXTI9申请了中断? NVIC是无从知道的,它也管不了那么多。
软件如果需要的话,可以通过调阅监控记录来了解细节,而这个监控记录就是在外设中实现的中断挂起位。
在STM32的外部线中断EXTI系统中,共有19条外部中断线,每一条都有相应的中断挂起位,即EXTI->PR的BIT18:0,满足中断条件后,由硬件置位,并一直保持(随便等待调阅监控),直到由软件手动清除。
注:19条是目前常用芯片具体实现的数目,有些互联型的是20条,EXTI各用一个字来设置中断屏蔽位和中断挂起位,理论上最大可扩展能力为可以表达32条外部中断线

STM32的外部线中断共19条,而对于NVIC来说,实际上只有10个通道,具体如下:
内核值(IRQn) 助记符 备注
6 EXTI0_IRQn PX0(即PA0-PG0口线)
7 EXTI1_IRQn PX1口线
8 EXTI2_IRQn PX2口线
9 EXTI3_IRQn PX3口线
10 EXTI4_IRQn PX4口线
23 EXTI5_9_IRQn PX5-PX9口线
40 EXTI15_10_IRQn PX10-PX15口线
1 PVD_IRQn 电压监测
41 RTC_IRQn RTC闹钟
42 USB_IRQn USB唤醒

为进一步加深理解,我们从中断控制的角度来看一下串口1
虽然说只是一个串口,从中断控制的角度来看,也算是NVIC一个比较典型的下级机构,
对于NVIC来说,串口1只分配到了一个中断通道USART1_IRQn,编号值为37
但USART1的中断源是非常多的,
常用的有:
RXNE接收缓冲区非空中断
TC发送完成中断
TXE发送缓冲区空中断
其它的还有IDLE中断、CTS中断、错误中断等等,总计不下十种。
但这些,NVIC都是一概不管的,对NVIC只能算一个中断!!!。

具体各类小中断的细分都是由串口1的外设来实现,具体实现套路是:
每一种小中断必有相应的屏蔽位(有时候称为中断允许位xxIE, 一般在控制寄存器CR中),
另外必有相应的标志位(名称如RXNE、TC、TXE等,一般在状态寄存器中),相当于挂起位,在满足触发条件时由硬件置位,并一直保持(随便等待调阅监控)

  • 7
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值