原创 键盘扫描--keyscan

2011-5-30 14:56 2135 0 分类: MCU/ 嵌入式
/**************************************************************
1*6 Key Scan
**************************************************************/

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

/******************************************************************************
1X6 矩阵键盘
六个输入引脚     EINT8 ------( GPG0  )
                EINT11 -----( GPG3  )
                EINT13------( GPG5  )
                EINT14------( GPG6  )
                EINT15------( GPG7  )
                EINT19------( GPG11 )
                
                
******************************************************************************/
U8 Key_Scan( void )  //键盘扫描,返回哪个按键被按下,按下时管脚与地相连
{
    Delay( 80 ) ;

    if(      (rGPGDAT&(1<< 0)) == 0 )      //在输出模式下,管脚寄存器与管脚输出状态相匹配
        return 1 ;
    else if( (rGPGDAT&(1<< 3)) == 0 )
        return 2;
    else if( (rGPGDAT&(1<< 5)) == 0 )
        return 3 ;
    else if( (rGPGDAT&(1<< 6)) == 0 )
        return 4 ;
    else if( (rGPGDAT&(1<< 7)) == 0 )
        return 5 ;
    else if( (rGPGDAT&(1<<11)) == 0 )
        return 6 ;
    else
        return 0xff;

}



static void __irq Key_ISR(void)   //中断处理函数,外部中断8~23共一个中断处理函数
{
    U8 key;
    U32 r;

    EnterCritical(&r);//中断不能嵌套,保护现场
    if(rINTPND==BIT_EINT8_23)         //INTPND是正在执行的或将要执行的中断。如果中断来自于外部中断8~23,那么执行下面的操作
    {
        ClearPending(BIT_EINT8_23);   //清除来自于外部中断8~23的中断请求
        
        if(rEINTPEND&(1<<8))
        {
            rEINTPEND |= 1<< 8;      //清除中断请求,通过写1清零中断请求标志位
        }
        
        if(rEINTPEND&(1<<11))
        {
            rEINTPEND |= 1<< 11;
        }
        
        if(rEINTPEND&(1<<13))
        {
           
            rEINTPEND |= 1<< 13;
        }
        
        if(rEINTPEND&(1<<14))
        {
           
            rEINTPEND |= 1<< 14;
        }
        
        if(rEINTPEND&(1<<15))
        {
           
            rEINTPEND |= 1<< 15;
        }
        
        if(rEINTPEND&(1<<19))
        {
           
            rEINTPEND |= 1<< 19;
        }
    }

    key=Key_Scan();
    if( key == 0xff )
        Uart_Printf( "Interrupt occur but Key is released!\n") ;
    else
        Uart_Printf( "Interrupt occur... K%d is pressed!\n", key) ;

    ExitCritical(&r);//恢复现场
}




void KeyScan_Test(void)   //外部中断的初始化工作
{
    Uart_Printf("\nKey Scan Test, press ESC key to exit !\n");    

    
    rGPGCON = rGPGCON & (~((3<<22)|(3<<6)|(3<<0)|(3<<10)|(3<<12)|(3<<14))) |
                        ((2<<22)|(2<<6)|(2<<0)|(2<<10)|(2<<12)|(2<<14)) ;        //管脚的模式设定,此处设定为输出模式
    /*以下为设定触发模式*/
    rEXTINT1 &= ~(7|(7<<0));    //外部中断8, 即为K1
    rEXTINT1 |= (0|(0<<0 ));    //低电平触发,此处可以不加,要此代码是为了满足以后的需要,比如要改为上升沿触发或下降沿触发时就需要了
    
    rEXTINT1 &= ~(7<<12);       //外部中断11,即为K2
    rEXTINT1 |= (0<<12);    
    
    rEXTINT1 &= ~(7<<20);       //外部中断13,即为K3
    rEXTINT1 |= (0<<20);    
    
    rEXTINT1 &= ~(7<<24);
    rEXTINT1 |= (0<<24);        //外部中断14,即为K4
    
    rEXTINT1 &= ~(7<<28);
    rEXTINT1 |= (0<<28);        //外部中断15,即为K5
    
    
    
    
        
    rEXTINT2 &= ~(0xf<<12);
    rEXTINT2 |= (0<<12);       //外部中断19,即为K6
    

    rEINTPEND |= (1<<8)|(1<<11)|(1<<13)|(1<<14)|(1<<15)|(1<<19);        //为外部中断输入时,EINTPEND寄存器用于保存是否有中断请求发生,0:没有发生(不发出中断请求);1:有中断发生(也就是发出中断请求)        
    rEINTMASK &= ~((1<<8)|(1<<11)|(1<<13)|(1<<14)|(1<<15)|(1<<19));        //使能6个外部中断,置1为屏蔽,置0表示不屏蔽
    ClearPending(BIT_EINT0|BIT_EINT2|BIT_EINT8_23);
    pISR_EINT0 = pISR_EINT2 = pISR_EINT8_23 = (U32)Key_ISR;
    EnableIrq(BIT_EINT0|BIT_EINT2|BIT_EINT8_23);    

    while( Uart_GetKey() != ESC_KEY ) ;     //等待中断的到来   ESC退出
    DisableIrq(BIT_EINT0|BIT_EINT2|BIT_EINT8_23);    
}

文章评论0条评论)

登录后参与讨论
我要评论
0
0
1
2
3
4
5
6
7
8
9
0
关闭 站长推荐上一条 /4 下一条