MCU中断处理那些事(二)

大家好,我是电源漫谈,很高兴和各位一起分享我的37原创文章,喜欢和支持我的工程师,一定记得给我点赞、收藏、分享。

前述文章,MCU中断处理那些事(一)中,我们简要介绍了16MCU的中断处理系统的基本特点,本文基于上一次的话题继续讨论中断相关的事情。

.MCU的中断处理过程

当一个中断事件发生时,它主要经历这样一个过程:首先是外设硬件或者MCU内核检测到这个事件,如果这个中断的优先级高于当前CPU的优先级,当前的程序执行就会停下来,接着就开启了中断服务程序ISR.

当中断服务程序执行完成时,硬件会恢复先前停止的程序运行,接着执行停下来时的下一条指令。

.中断的分类

16MCU会识别两种不同的中断类型,其中一种是不可以maskTraps事件。这里我们详细了解一下TrapsTraps是一些不可以mask的,可以嵌套的中断。这些中断具有固定的中断优先级。他们存在的意义主要是检测并纠正一定的硬件和软件问题。

图1 Traps存在的意义

当用户不想去纠正一些Trap错误条件时,中断向量会指向让器件复位的代码,否则用户应用代码需要编程Trap中断向量指向纠正Trap条件的代码。

图2 Traps的种类

dsPIC33PIC24芯片上主要有以上几种Trap事件。一般来说,在Trap中断服务程序开始前,引起Trap的指令是允许执行完成的,所以用户需要考虑引起Traps的指令导致的一些影响。

对于Trap事件来说,他们具有固定的优先级,如振荡器失效的Trap的优先级最高,而DMAC错误的优先级最低。Trap的源是可以分为两类的,一类是Hard Trap,另一类是Soft Trap,大家需要注意。

除了Trap类型的中断之外,就是外设和I/O的外部中断。这些中断是属于一般的,可以被mask的中断,这些中断源都是来源于硬件外设的申请,例如外部中断pin,比较器中断,通信接口I2C或者UART中断等。

.CPU的中断优先级

16MCU的中断处理系统的一个关键特性是,用户可以对中断优先级进行设定,包括外设中断和外部中断等,对于此,我们先了解一下CPU的中断优先级的设定方式。

CPU的优先级可以设定为0-15这个范围的共16个优先级水平,所以,中断进行响应处理的一个前提是,中断的优先级必须要高于CPU的当前的优先级。

外设或者外部中断的优先级可以设定为0-7这些优先级水平,而需要注意的是CPU8-15的优先级部分是为Traps事件所保留且是固定的。

当前执行线程的CPU的优先级是由CPU的状态寄存器SR中的IPL<0-2>位及Core的控制寄存器中的IPL3所决定,如图34。

图3 CPU的SR寄存器中的IPL位

图4 CORCON寄存器的IPL3位

图5 CPU优先级的设定示例

如果我们将CPU的优先级设定为7,则所有的用户中断将被disable,因为所有的外设及外部中断优先级不可能大于7.IPL3这一位被系统设定为了1,意味着发生了Trap事件。

这里,有一个知识点需要注意,就是当器件复位后,CPU的优先级是默认为0的,也就是说它比任何优先级非0的外设中断和外部中断的优先级都要低,它是允许用户中断的。

那么,我们如何配置CPU的优先级呢?首先IPL<0-2>是可以根据用户的需要手动配置的,它可以允许配置为7,允许系统在一段时间内mask所有的外设和外部中断,以便密集执行一些CPU命令。

IPL3是被CPU Core所设置的,它在发生Trap事件时,自动会设置为1.

.中断的嵌套功能

中断处理系统不得不提的一个特性,就是中断嵌套,在默认设置下,16MCU是允许中断嵌套功能的,任何一个高优先级的中断都可以打断一个低优先级的中断复位程序,去执行高优先级的中断服务程序。

这里我们有一个示例,用以说明中断嵌套的执行,如图6所示。

图6 中断嵌套示例

这里假定,当在主程序main执行任务时,有不同的优先级的三个ISR执行,此处使能了中断嵌套功能,可以看到由于CPU的优先级是0,所以优先级为4的中断打断了CPU去执行其任务,在执行过程中,优先级为7的中断触发了,所以优先执行这个7优先级中断,在此过程中,优先级为1的中断触发了,但是其优先级太低,所以排队在后面再执行。7优先级中断任务执行完之后,接着执行4优先级未执行完的任务,最终4优先级的中断执行完成,最后执行1优先级的任务。这就是一个中断嵌套的典型示例。

这里有一个知识点需要注意,在中断嵌套允许时,由于低优先级的中断可能会被打断,所以其中断延时会发生延长变化,比如它需要7个指令周期的中断延时,3个指令周期用于走出前面的中断,四个指令周期用于进入新的中断。

当用户不希望中断在执行时被其它高优先级中断打断时,那么,可以disable中断嵌套功能,具体可以在INTCON1中的NSTDIS位置位,这样在一个中断执行时,CPU的中断优先级会被强制为7,这就可以mask所有的其它中断,直到系统收到当前中断执行完成的标志,则可以执行其它中断,此时需要执行当时pending发生的最高优先级的中断。关于中断嵌套使能的功能这一个设置如图7所示。

图7 中断嵌套的mask

.中断冲突的解决

当多个中断源同时发生时,且他们的中断优先级都是一样的值,比如,他们被设为初始化时的中断优先级4,那么此时如何解决他们的冲突呢?需要先执行响应谁呢?

事实上,每一个中断源都有一个自然优先级,这个自然优先级取决于这个中断向量在中断向量表IVT上的位置,越小编号的中断向量,其自然优先级越高。

图8 中断向量的自然优先级

所以,当出现同一个用户设定的优先级冲突时,可以以自然优先级的顺序来执行中断申请,如图8所示。

总的说来,解决中断冲突,需要首先看用户指定的中断优先级,这个在IPC寄存器中设置,如果若干中断的优先级一样,那么需要以自然优先级为顺序去响应中断。

.中断功能的使用

在代码中使用一个中断,需要注意三个寄存器的使用,中断标志位IF,中断使能位IE,中断优先级位IPC,中断控制器会接收所有的中断申请并判断其优先级,然后发给CPU一个唯一的中断申请源,及其优先级信息,如图9所示。

图9 中断控制器的功能

这里,可以看出Trap的中断优先级为8-15,在发生TrapCPUCORCON寄存器中的IPL3自动设为1,表示这是Trap的发生。

需要使用一个中断,首先应该使能这个中断,比如,此处以外部中断INT0为例,INT0IE设为1使能这个中断。

图10 中断使能示例

需要注意的是,使能中断和设置中断的优先级的顺序需要注意,一般不推荐在中断使能后,再去改变中断的优先级,这会导致在中断发生时去改变其优先级,那么可能会丢失这个中断,或者使用了错误的优先级。正确的做法是先disable中断,设定其优先级,再使能中断。

图11 中断的优先级设定

中断的优先级设定使用IPC寄存器,此处以INT0中断优先级设定为例说明,如图11所示,通过三位的优先级设定位,可以设定0-7的优先级水平,值得注意的是,当中断优先级设为0时,这个中断是不被响应的,相当于disable了这个中断。

图12 中断标志位

当一个中断或者事件发生时,中断标志位会置位为1,在用户中断服务程序中可以将其清零,作为用户程序对此中断的应答。

七.中断服务程序相关的讨论

标准的C语言规范并没有说明如何去声明一个函数作为中断服务程序,MPLABXC16对中断属性进行了特殊定义,用于申明一个函数作为中断服务程序。这里我们以INT0中断为例说明。

图13 中断服务程序属性声明示例

XC16的编译器用户手册中或者芯片规格书中,我们可以找到中断服务程序预定义的名字,如图1415所示(注:并非完整表格,仅仅截图示意)。

图14 编译器定义的中断服务程序名称

图15 编译器定义的中断服务程序名称2

从上面的INT0中断服务程序ISR来看,它的特点主要如下:

§ 没有参数;

§ void返回类型;

§ 必须使用在XC16中定义的名字;

§ 不能在main函数中调用;

在中断使能后,中断可能在任何时候发生,所以它会破坏主程序原有使用的变量,16位单片机的硬件中断处理器提供了一种机制,在堆栈中去保存和恢复CPU的背景内容。其中PC指针,PCH,PCLCPU状态寄存器的低位字节部分SRL,是自动在堆栈中存储和恢复的。如图16所示。

图16 CPU背景保存和恢复

同时XC16还可以用额外的背景保存指令,保存和恢复诸如RCOUNTW0-W13,W14,PSVPAG等寄存器内容。除此之外,还可以通过编译器的save属性去保存和恢复一些关心的变量,如图17所示。

图17 变量的保存和恢复

总结,本文延续前述文章,在中断处理系统初步介绍的基础上,去进一步探讨了中断的处理过程,中断的优先级,CPU的优先级,及中断的嵌套功能及如何处理中断冲突,最后通过示例介绍了中断的使用及中断服务程序的一些要求,相对完整的对中断处理有一个基本的认识,为后续进一步深入探讨奠定基础。

参考资料:

Exception Handling on a 16-bit PIC® MCU - Developer Help (microchipdeveloper.com)

声明:本内容为作者独立观点,不代表电子星球立场。未经允许不得转载。授权事宜与稿件投诉,请联系:editor@netbroad.com
觉得内容不错的朋友,别忘了一键三连哦!
赞 4
收藏 2
关注 389
成为作者 赚取收益
全部留言
0/200
成为第一个和作者交流的人吧