原创 手机按键分析及一种实现方法

2008-10-23 19:55 3357 8 8 分类: MCU/ 嵌入式

使用这么多年的手机也没有观察手机的按键,今天仔细试了手机上的按键..


有的是响应按下的时候,有的响应抬起的时候,有的响应长按,,有的响应连续的按键.有的可以响应多种方式...


有的按键在不同的场合下响应不同的按键方式....


突然想到,手机里的按键处理程序返回的值应该包含了这个按键的状态...应用程序接响应不响应要看应用程序响应什么样子的按键来看了.


所以我定义了四种按键属性,放在高四位上.


    #define     KEY_DOWN        0xA0
    #define     KEY_UP               0xB0
    #define     KEY_LONG         0xC0
    #define     KEY_LIAN           0xD0


又定义了若干种按键值,放在低四位上


    //按键值
    #define     KEY_0           0x00
    #define     KEY_1           0x01
    #define     KEY_2           0x02
    #define     KEY_3           0x03
    #define     KEY_4           0x04


返回的就是这属性跟键值的组合...


一种方法是:在按键映射的时候响应符合这个应用程序条件的按键.


二种方法是:到了应该程序这再把属性取出来判断一下,不响应就返回..


我用了第一种方法映射的应用程序,,如下


void DealKey(void)
{
    INT8U KeyTmp;
    KeyTmp = GetKey();
   
    switch(KeyTmp)
    {
        case KEY_1 | KEY_DOWN:
        case KEY_1 | KEY_LONG:
        case KEY_1 | KEY_LIAN:
            Menu_Next();
            break;
           
        case KEY_2 | KEY_DOWN:
        case KEY_2 | KEY_LONG:
        case KEY_2 | KEY_LIAN:
            Menu_Prev();  
            break;
           
        case KEY_3 | KEY_DOWN:
            Menu_Enter();  
            break;
           
        case KEY_4 | KEY_DOWN:
            Menu_Esc();    
            break;
    }
}


 


也就是在任何情况下都会有按键返回,只是有些按键被忽略了,没有响应.


用状态机很容易做出来...


INT8U GetKey()
{
    static INT8U KeyState   = 0;      //按键状态
    static INT8U KeyPrev    = 0;      //上一次按键
    static INT8U KeyDelay   = 0;      //按键连发时间  
    static BOOL  bKeySeries = 0;      //标志连发开始
   
    INT8U KeyPress  = 0;            //按键值
    INT8U KeyReturn = 0;            //按键返回值
   
    KeyPress = GetKeyCode();
   
    switch(KeyState)
    {
        //按键初始态00
        case 0:    
            if( KeyPress )
            {
                KeyState = 1;
                KeyPrev  = KeyPress;
            }
            break;
           
        //按键确认态01
        case 1:
            if( KeyPress )
            {
                //与上次按键不同,是乱码
                if(KeyPrev  != KeyPress)
                {
                    KeyState  = 0;
                }
                else
                {
                    KeyState  = 2;
                    KeyReturn = KEY_DOWN | KeyPrev;             //返回按下的键值
                }
            }
            else
            {//按键抬起,是抖动,不响应按键
                KeyState = 0;
            }
            break;
       
        //按键连续按下11
        case 2:           
            if( KeyPress )
            {
            
                KeyDelay++;
    
                if( (bKeySeries==1) && (KeyDelay>KEY_SERIES_DELAY) )
                {
                    KeyDelay  = 0;
                    KeyReturn = KEY_LIAN | KeyPrev;             //返回连发的值
                    break;
                }
               
                if(KeyDelay>KEY_SERIES_FLAG)
                {
                    bKeySeries = 1;
                    KeyReturn = KEY_LONG | KeyPrev;             //返回长按后的值
                }
               
            }
            else
            {  
                KeyState   = 3;
            }
                   
            break;
           
        //按键释放    10
        case 3:
            if(!KeyPress )
            {
                KeyState   = 0;
                KeyDelay   = 0;
                bKeySeries = 0;
              
                KeyReturn = KEY_UP | KeyPrev;                   //返回按键抬起值
            }  
           
            break;
           
        default :break;
    }


 


移植到我的菜单里,,,还是不错滴嘛~~~~

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
8
关闭 站长推荐上一条 /3 下一条