前面讲到了各种中断。
PIT中断用于控制小车的直立速度角度;
EXTI中断用于处理摄像头的行场中断;
UART中断用于串口通信;
直立控制必须1ms进行一次计算,所以PIT中断一次都不能少;
摄像头的行场中断缺一不可,而且行场中断来了必须马上处理,处理过程不能暂停,否则图像会采集出错;
UART不要求马上反应,但需要处理每个请求;
那么问题来了,一个中断正在处理的时候,另一个中断来了,怎么办?
中断优先级的设置,可以让每个中断都得到处理,且能按照优先级进行中断嵌套。(优先级低的中断正在处理的时候,来了优先级高的中断,会先暂停优先级低的中断,执行完优先级高的中断后再继续进行处理。)
好消息是,在K60和XS128中设置中断优先级都不难。
K60
// 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.
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
}