发新帖我要提问
12
返回列表
打印

怎样识别长短键

[复制链接]
楼主: book99
手机看帖
扫描二维码
随时随地手机跟帖
21
hgjinwei| | 2010-4-28 19:33 | 只看该作者 回帖奖励 |倒序浏览
以下代码仅供参考!
#define LONG_KEEP_TRG           300                     /* 按键长闭合触发等待时间(3s)               */
#define KEY_AP                  1                       /* 按键数量(<= 30)                          */                                 

/* static variable -------------------------------------------------------------------------------- */
uint8   ext_shift;
uint8   key_shift[KEY_AP];                              /* 按键状态移位寄存器                       */
uint16  key_timer[2];                                   /* 按键1,2长闭合触发计时器                  */
                        
void (* KeyOnFunction[])(void);                         /* 功能触发执行函数表                       */
void (* KeyOffFunction[])(void);
void (* ExtFunction[])(void);

/*
****************************************************************************************************
*
* Description     : 按键定时检测 Tick ,周期调用
*
* Arguments       : None
*
* Returns         : None
*
* Note :
* 1) 按键状态说明:
*    按键采用查询方式判断,每检测一次将以前状态向左移动一位并记录最新检测状态。
*    按键状态只取低三位:
*       000 - 没有检测到按键动作
*       001 - 第一次检测到按键动作
*       011 - 按键稳定闭合
*       111 - 按键持续闭合
*       110 - 第一次检测到按键释放
*       100 - 按键稳定释放
*       010 - 正脉冲抖动干扰,状态置为 000
*       101 - 负脉冲抖动干扰,状态置为 111
****************************************************************************************************
*/
void KeyClockTick(void)
{
    int     i;
    uint8   shift;
    uint32  key = 0;

    if(KEY_PROG_ON)     key |= (1<<0);                  /* 编程键                                   */
    if(KEY_UP_ON)       key |= (1<<KEY_AP);             /* 上翻键                                   */
    if(KEY_DOWN_ON)     key |= (1<<(KEY_AP+1));         /* 下翻键                                   */
   

    for(i=0;i<KEY_AP;i++)                               /* 普通按键检测                             */
    {
        shift = key_shift & 0x03;
        shift = (key & (1<<i))?(shift << 1):((shift << 1) | 0x01);

        switch(shift)
        {
            case 3  : KeyOnFunction();   break;
            case 4  : KeyOffFunction();  break;
            case 5  : shift = 7;            break;
            case 2  : shift = 0;            break;
            default : break;
        }

        key_shift = shift;
    }
   

    shift = (ext_shift << 1) & 0x77;                    /* 扩展功能按键检测                         */
    if(key & (1<<(KEY_AP+0)))   
        shift |= 0x01;   
    if(key & (1<<(KEY_AP+1)))   
        shift |= 0x10;

    ext_shift = (ext_shift & 0x80) | shift;             /* bit8 表示扩展功能有效                    */
    switch(shift)
    {
        case 0x03 : key_timer[0] = LONG_KEEP_TRG;       /* 按键1触发,装载延时时间                  */
                    break;

        case 0x30 : key_timer[1] = LONG_KEEP_TRG;       /* 按键2触发,装载延时时间                  */
                    break;

        case 0x04 : if(ext_shift & 0x80)                /* 按键1释放                                */
                        ext_shift &= ~0x80;             /* 扩展功能有效,失效扩展功能               */
                    else
                        ExtFunction[0]();               /* 扩展功能无效,触发按键事件               */
                    break;

        case 0x40 : if(ext_shift & 0x80)                /* 按键2释放                                */
                        ext_shift &= ~0x80;             /* 扩展功能有效,失效扩展功能               */
                    else
                        ExtFunction[1]();               /* 扩展功能无效,触发按键事件               */
                    break;

        case 0x37 : if(0 == (ext_shift & 0x80))
                    {
                        ExtFunction[2]();               /* 双键闭合有效,按键1 先闭合               */
                        ext_shift |= 0x80;
                    }
                    break;

        case 0x73 : if(0 == (ext_shift & 0x80))
                    {
                        ExtFunction[3]();               /* 双键闭合有效,按键2 先闭合               */
                        ext_shift |= 0x80;
                    }
                    break;

        case 0x07 : if(0 == (ext_shift & 0x80))
                    {
                        if(--key_timer[0] == 0)
                        {
                            ExtFunction[4]();           /* 按键1长闭合状态激活                      */
                            ext_shift |= 0x80;
                        }   
                    }
                    break;

        case 0x70 : if(0 == (ext_shift & 0x80))
                    {
                        if(--key_timer[1] == 0)
                        {
                            ExtFunction[5]();           /* 按键2长闭合状态激活                      */
                            ext_shift |= 0x80;
                        }   
                    }
                    break;

        default   : break;
    }   
}
/*
****************************************************************************************************
* Function Name   : key_func_null
* Description     : 空操作
* Arguments       : None
* Returns         : None
****************************************************************************************************
*/
static void key_func_null(void)
{
}

/* ------------------------------------------------------------------------------------------------ */

void (* KeyOnFunction[])(void) =                        /* 按键闭合触发执行函数表                   */
{
    ProgrammeKeyTrigger,                                /* 0.  按键3闭合触发                        */
    key_func_null,                                      /* 1.  按键4闭合触发                        */
    key_func_null,                                      /* 2.  按键5闭合触发                        */
    key_func_null,                                      /* 3.  按键6闭合触发                        */
};

void (* KeyOffFunction[])(void) =                       /* 按键断开触发执行函数表                   */
{
    key_func_null,                                      /* 0.  按键3断开触发                        */
    key_func_null,                                      /* 1.  按键4断开触发                        */
    key_func_null,                                      /* 2.  按键5断开触发                        */
    key_func_null,                                      /* 3.  按键6断开触发                        */
};

void (* ExtFunction[])(void) =                          /* 扩展功能触发执行函数表                   */
{
    UpKeyTrigger,                                       /* 0.  按键1闭合触发                        */
    UpKeyTrigger,                                       /* 1.  按键2闭合触发                        */
    key_func_null,                                      /* 2.  双键闭合触发1(按键1 先闭合)          */
    key_func_null,                                      /* 3.  双键闭合触发2(按键2 先闭合)          */
    key_func_null,                                      /* 4.  按键1长闭合触发                      */
    key_func_null,                                      /* 5.  按键2长闭合触发                      */
};

/*
*****************************************************************************************************
*   End of file
*****************************************************************************************************
*/

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
book99 + 1
22
DEKANGCX| | 2010-4-28 21:03 | 只看该作者
都是高手

使用特权

评论回复
23
lzz_vip| | 2010-4-28 21:35 | 只看该作者
楼上也有提到,就是每个按键定义两个键值,“按下”和“抬起”,根据两个扫描到两个键值的时间间隔分辨长短键

使用特权

评论回复
24
dulianling| | 2010-4-29 12:40 | 只看该作者
本帖最后由 dulianling 于 2010-4-29 12:41 编辑

检测按键,采用定时扫描,状态判断、时间累计、标志位等配合处理,既方便也不浪费
时间。用软件延时很是占用CPU时间,如果其他程序跑起来占时间多或多个实时要求高
的功能模块在运行,那实现起来很麻烦,也没有太多的定时器、中断等功你使用啊。

使用特权

评论回复
25
hondephy| | 2010-4-29 17:41 | 只看该作者
看了程序一下,呢呢,还真没看明白。。。

使用特权

评论回复
26
dong2007| | 2010-4-29 21:01 | 只看该作者
哈哈,好贴!

使用特权

评论回复
27
zhuang_569| | 2014-7-28 22:47 | 只看该作者
15看的不是太明白,能否详解下

使用特权

评论回复
28
904461272| | 2014-8-20 17:18 | 只看该作者
有完整点的吗

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则