中断

用到的概念:
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和上面数组中的某个值关联起来;
imm->sim.ICR4=ICR[LEVEL6][PRIORITY1];       
imm
->sim.ICR5=ICR[LEVEL6][PRIORITY0];                
补充2:中断屏蔽
1 中断使能
asm("        move.w        #0x2000,SR      "); 

解释:只有执行了该语句,才可以中断;这相当于所有中断的一个总开关。
2 开某个特定的中断
例如:    imm->sim.IMR &= ~MCF5307_SIM_IMR_EINT1;

解释:IMR(Interrupt Mask Register)称为中断屏蔽寄存器
把哪位设为1表示屏蔽掉该位所对应的中断,
把哪位设为0表示不屏蔽该位所对应的中断。
上句中,把EINT1对应的中断打开。


posted on 2007-05-14 17:52  坚强地活着  阅读(409)  评论(0编辑  收藏  举报

导航