TQ2440实现按键中断

有几点需要注意:

1、需要调用MMU函数,实现内存的映射;

2、在中断触发跳入中断处理函数后,首先要清除SRCPND和INTPND相应的位,如果用到次级中断源,如这里用到了 EINT4_7中的EINT4,就要清除EINTPEND相应的位。一般来说,应该先清除次级中断源相应的位,再清除中断源,否则中断源会发生多次中断。 在完成清除后再进行具体的处理。

#include "def.h"
#include "option.h"
#include "2440addr.h"
#include "2440lib.h"
#include "2440slib.h"
#include "mmu.h"


#define LED1 (1<<5) //must be "()"
#define LED2 (1<<6)
#define LED3 (1<<7)
#define LED4 (1<<8)
 
#define KEY1  (1<<1)  //GPF1
#define KEY2  (1<<4)  //GPF4
#define KEY3  (1<<2)  //GPF2
#define KEY4  (1<<0)  //GPF0

//void delay_ms(U32 i);
void init_irq(void);
void MMU_Init(void);

int Main(void)
{
    rGPBCON=0x15400;
    rGPBDAT=0x7ff;
    MMU_Init();   //必须要有MMU,目的是为了实现地址映射
    init_irq();       //初始化中断寄存器
    while(1);
   
}

void delay_ms(U32 i)
{
   int j;
   for(;i>0;i--)
       for(j=65535;j>0;j--);
}

void key_per(void)   //按键处理
{
    if(!(rGPFDAT&KEY1))
        rGPBDAT=~LED1;
       
    else if(!(rGPFDAT&KEY2))
        rGPBDAT=~LED2;
       
    else if(!(rGPFDAT&KEY3))
     rGPBDAT=~LED3;
     
    else if(!(rGPFDAT&KEY4))
        rGPBDAT=~LED4;
       
}

void __irq key1_3_4(void)
{
   //当按下键后,就跳到此函数里,在以下的按键对应的各个分支里,在跳到key_per()前应该调用

  //ChearPending()清除SCRPND和INTPND对应的位
    if(rINTPND &KEY3)          
    {                                 
      ClearPending(BIT_EINT2);
      key_per();
    }
    else if(rINTPND &KEY4)
    {                              
      ClearPending(BIT_EINT0);
      key_per();
    }
  
    else if(rINTPND&KEY1)           
    {               
      ClearPending(BIT_EINT1);
      key_per();
    }
   

}

void __irq key2(void) 

{
 //if(rEINTPEND &KEY2)            //10000
 //{     
      rEINTPEND = (1<<4);           //CLEAR  rEINTPEND
      ClearPending(BIT_EINT4_7);
      key_per();
 //} 
}

//由于key2在电路图上对应的是GPF4,相应的中断功能是EINT4,它具体是由次级中断寄存器中的

//EINTMASK来使能的,在init_irq()中由于要映射中断处理函数,因此这里单独写出key2,清晰程序。

void init_irq(void)
{
    rGPFCON&=(~((3<<0)|(3<<2)|(3<<4)|(3<<8)));
    rGPFCON|=((2<<0)|(2<<2)|(2<<4)|(2<<8));  //configure GPF0、1、2、4 to EINT0、1、2、4
    //rGPFCON=0xfeea;
    rPRIORITY=0x00000000;    //deafult priority configure
    rINTMOD=0x0;                    //IRQ
    EnableIrq(BIT_EINT0|BIT_EINT1|BIT_EINT2|BIT_EINT4_7);//enable EINT0、1、2、4_7 with INTMSK register
    //rINTMSK&=(~((1<<0)|(1<<1)|(1<<2)|(1<<4)));
    rEINTMASK&=~(1<<4);                              //enbale EINT4 with EINTMASK register

//下面是将key1_3_4和key2函数的地址映射到中断向量表,这样,当中断触发时,就跳到相应函数的地址执

//行该函数。如EINT0中断被触发时,就执行函数key1_3_4。

    pISR_EINT0= (unsigned int)key1_3_4;     

    pISR_EINT1= (unsigned int)key1_3_4;
    pISR_EINT2= (unsigned int)key1_3_4;
    pISR_EINT4_7= (unsigned int)key2;
  
}

posted @ 2013-03-16 21:40  天涯海角路  阅读(170)  评论(0)    收藏  举报