DSP F2812的中断

看了TI的文档:TMS321x281x DSP System Control and Interrupts Reference Guide,spru078b.pdf

有一些心得:

1、一个外设中断要到达CPU,让CPU处理,得经过许多道门

PIEIER->(PIEACKx)->IER->INTM

在CPU级别上面,有1个不可屏蔽中断(NMI),16个可屏蔽中断(INT1~INT14,RTOSINT和DLOGINT)。其中的INT1~INT12每个又通过PIE扩展出8个外设中断,所以外设中断可以有12*8=96个,F2812仅仅用了其中45个:

2、关于中断嵌套,硬件上没直接支持,但软件可实现

  先看F2812的处理流程图:

可以看到,在进入中断服务程序之前的Stage H,INTM已经被置位(中断关闭),所以不可能在响应其他的中断了,之后的其他中断都会在Stage G这里卡住。所以,如果你要允许中断嵌套,除非在你的中断程序里面手动把INTM清零(EINT),具体例子可看sprc097的sw_prioritized_interrupts,里面的例子就是这么干的,它的中断服务程序都有EINT这一句,以此为基础,来实现中断的嵌套。

3、关于优先级

不能自己设定,硬件本身有自己的一套优先级,当时看上面流程图可知,因为硬件不可实现中断嵌套,所以这个优先级仅仅当两个中断同时发生的时候才起作用,所以一般不用管了。sprc097的sw_prioritized_interrupts例子可以有软件优先级。

4、一个需要注意的地方,PIEACKx的清零

先想一个问题,我们知道,给PIEACK的对应位写1即可清除这个位,以便让中断控制器响应同组的其他中断,但下面这样清除Group1的PIEACK位对不对:

PieCtrl.PIEACK.bit.Ack1 = 1;

回答这个问题之前,先参考第2点中的流程图,考虑一个问题,PIEAck这个寄存器我们用了第0~11位来对应第1到第12组中断,那么这12位中可不可能同时有多个位为1?答案是肯定的,因为虽然不能中断嵌套,但是各组中断被卡的地方在Stage G,假如同时有多组中都有中断发生,那么到Stage G才会被卡,这个之前,对应各组的PIEAck都已经在Stage C之后被置1了,所以PIEAck完全有可能有多个位被置1.

    再来考虑上面写法,虽然上面用了位域的写法,语法上只是对Ack1这一位写1,但是位域最终在处理器的执行上,还是要一次重新写一次寄存器,而这个写入是按照读-修改-写的流程的,即先读取PIEAck的值,再把Ack1修改为1(按上面语句),最后再把修改完之后的值写入寄存器PIEAck,这个时候就会出现问题了,因为在读入的PIEAck中,可能有其他组有中断在等待了,它对应的Ack为1,你这样一写1进去,就有可能导致同组的其他中断把这个中断覆盖掉。所以正确的写法应该是:

#define PIEACK_GROUP1 0x0001
……
PieCtrl.PIEACK.all = PIEACK_GROUP1;

因为PIEACK写0无效,不起作用,这样写就仅仅影响了第一位了。

这个具体可见sprc097中的DSP281x_HeaderFiles_QuickStart_Readme.pdf 6.1.1一节。

posted @ 2012-11-26 15:48  果壳中的宇宙  阅读(6511)  评论(0编辑  收藏  举报