10 - 中断:中断优先级

前面讲到了各种中断。
PIT中断用于控制小车的直立速度角度;
EXTI中断用于处理摄像头的行场中断;
UART中断用于串口通信;

直立控制必须1ms进行一次计算,所以PIT中断一次都不能少;
摄像头的行场中断缺一不可,而且行场中断来了必须马上处理,处理过程不能暂停,否则图像会采集出错;
UART不要求马上反应,但需要处理每个请求;

那么问题来了,一个中断正在处理的时候,另一个中断来了,怎么办?
中断优先级的设置,可以让每个中断都得到处理,且能按照优先级进行中断嵌套。(优先级低的中断正在处理的时候,来了优先级高的中断,会先暂停优先级低的中断,执行完优先级高的中断后再继续进行处理。)

好消息是,在K60和XS128中设置中断优先级都不难。

K60

  //调整中断优先级 set_irq_priority (int irq, int prio),肥叉烧,2014-3-30
  // irq写的是中断号(注意不是VECTOR的号码)
  // irq可以在cpu/vectors.h中查到
  set_irq_priority (88,0); //exti_PTB最高优先级0,用于控制DMA采集图像;
  set_irq_priority (68,1); // PIT0第二优先级1,用于控制直立;
  set_irq_priority (45,2); // UART0第三优先级2。

在中断处理函数的开始,一定要EnableInterrupts; 否则优先级更高的中断会执行不了。
set_irq_priority (int irq, int prio)是cmsis库自带函数,在cpu/arm_cm4.c可以查看实现;

XS128

详情请参考:
4.4.2 Interrupt Prioritization, MC9S12XS256 Reference Manual.
Table 1-10. Interrupt Vector Locations, MC9S12XS256 Reference Manual.

Table1-10

Table1-10-2

1. 在Table 1-10找到相应中断的Vector Address;
2. 取高4位的值放到CFADDR的高4位里;(如TIM7的地址是Vector base+ $E0,将E放到CFADDR的高4位里,INT_CFADDR = 0xE0;)
3. 低4位的值除以2,如TIM7的低4位是0,除以2是0,则在CFDATA0中设置TIM7的优先级,如果设成3,则INT_CFDATA0 = 3;
4. 优先级数值越高,越优先;

/*************************************************************************
*  函数名称:SetInterruptPriority
*  功能说明:Set Priority
*  参数说明:
*  函数返回:无
*  修改时间:2014-04-24
*  备    注 :   feichashao
*************************************************************************/
void SetInterruptPriority(void) {

  // Set timch0 to priority 7.
  // Vector Address $EE
      INT_CFADDR = 0xE0;
      INT_CFDATA7 = 7;    // E/2 = 7

   // Set timch1 to priority 7.
   // Vector Address $EC
      INT_CFADDR = 0xE0;
      INT_CFDATA6 = 7;   // C/2=6

   // Set pit0 to priority 6.  
   // Vector Address $7A
      INT_CFADDR = 0x70;
      INT_CFDATA5 = 6;   // A/2=5

   // Set sci0 to priority 5.
   // Vecort Address $D6
      INT_CFADDR = 0xD0;
      INT_CFDATA3 = 5;  // 6/2=3
}