interrupt pending寄存器
未决中断寄存器
****************************
在mcf5307中对中断的处理过程(使用的操作系统为Nucleus):
1 为了方便,定义中断向量表(这可以通过查阅处理器的资料得到)
为了简单,这里只以中断向量“0x1F”为例子
------------程序部分开始--------------------
const INT InterruptVectorTable[]={0x1F,0x1E,0x1D,0x1C,0x1B,0x1A,0x19};
------------程序部分结束--------------------
2 注册中断
对应于某个中断向量的中断源可以分为5个优先级,分别是:
PRIORITY0,PRIORITY1,EXT_INT,PRIORITY2,PRIORITY3
其中,EXT_INT是外部中断。
可以使用查看IPR(未决中断寄存器)的值来确定是哪个中断源所产生的中断
假设有UART1和UART2都挂接在 “0x1F” 上
------------程序部分开始--------------------
// IRQ_Table中的下标
#define LEVEL7 0
#define LEVEL6 1
#define LEVEL5 2
#define LEVEL4 3
#define LEVEL3 4
#define LEVEL2 5
#define LEVEL1 6
//IRQ的优先级下标
#define PRIORITY3 0 //highest
#define PRIORITY2 1 //lower than external
#define EXT_INT 2 //external int
#define PRIORITY1 3 //higher than internal
#define PRIORITY0 4 //lowest
VOID (*old_lisr)(INT);
ptrLISR DispatchInt;//声明LISR函数
MCF5307_IMM *pimm= (MCF5307_IMM *)0x10000000;
NU_Register_LISR(vectorNum[0],DispatchInt,&old_lisr);
void DispatchInt(INT InterruptVector)
{
unsigned long InterruptVectorIPR_UART1 = MCF5307_SIM_IPR_UART1;
unsigned long InterruptVectorIPR_UART2 = MCF5307_SIM_IPR_UART2;
MCF5307_IMM *imm;
imm = (MCF5307_IMM *)0x10000000;
//这里去掉了对外部中断的判断
if (0x00!=((InterruptVectorIPR_UART1)&imm->sim.IPR))
{
LISR_UART1(InterruptVector);
}
else if (0x00!=((InterruptVectorIPR_UART2)&imm->sim.IPR))
{
LISR_UART2(InterruptVector);
}
}
void LISR_UART1(INT InterruptVector)
{
}
void LISR_UART2(INT InterruptVector)
{
}
------------程序部分结束--------------------
补充:
前面有“假设有UART1和UART2都挂接在 “0x1F” 上”,那么怎么来实现这一步呢?
1 通过查询cpu的资料可以得到每个中断向量(以及每个向量的不同优先级)所对应的ICR(中断控制寄存器)的值
关于ICR的定义见下图():
例如:ICR[0][0] = 0x9F 是这样得到的
Byte[7]=1;Byte[6,5]=0;Byte[4-2]=111 (level是7);Byte[1,0]=11(priority是3);
所以Byte=10011111 =9F
// -ICRn的值
const static ICR[7][5]=
{
// PRIO3 PRIO2 EI PRIO1 PRIO0
{0x9F, 0x9E, 0, 0x9D, 0x9C}, // Level 7
{0x9B, 0x9A, 0, 0x99, 0x98}, // Level 6
{0x97, 0x96, 0, 0x95, 0x94}, // Level 5
{0x93, 0x92, 0, 0x91, 0x90}, // Level 4
{0x8F, 0x8E, 0, 0x8D, 0x8C}, // Level 3
{0x8B, 0x8A, 0, 0x89, 0x88}, // Level 2
{0x87, 0x86, 0, 0x85, 0x84} // Level 1
};
//注:这里好像使用了声明变量时的默认类型,若比较严格一些应该为const static unsigned int ICR[7][5]
2 把UART1、UART2的ICR和上面数组中的某个值关联起来;const static ICR[7][5]=
{
// PRIO3 PRIO2 EI PRIO1 PRIO0
{0x9F, 0x9E, 0, 0x9D, 0x9C}, // Level 7
{0x9B, 0x9A, 0, 0x99, 0x98}, // Level 6
{0x97, 0x96, 0, 0x95, 0x94}, // Level 5
{0x93, 0x92, 0, 0x91, 0x90}, // Level 4
{0x8F, 0x8E, 0, 0x8D, 0x8C}, // Level 3
{0x8B, 0x8A, 0, 0x89, 0x88}, // Level 2
{0x87, 0x86, 0, 0x85, 0x84} // Level 1
};
//注:这里好像使用了声明变量时的默认类型,若比较严格一些应该为const static unsigned int ICR[7][5]
imm->sim.ICR4=ICR[LEVEL6][PRIORITY1];
imm->sim.ICR5=ICR[LEVEL6][PRIORITY0];
补充2:中断屏蔽imm->sim.ICR5=ICR[LEVEL6][PRIORITY0];
1 中断使能
asm(" move.w #0x2000,SR ");
解释:只有执行了该语句,才可以中断;这相当于所有中断的一个总开关。
2 开某个特定的中断
例如: imm->sim.IMR &= ~MCF5307_SIM_IMR_EINT1;
解释:IMR(Interrupt Mask Register)称为中断屏蔽寄存器
把哪位设为1表示屏蔽掉该位所对应的中断,
把哪位设为0表示不屏蔽该位所对应的中断。
上句中,把EINT1对应的中断打开。