打印
[资料下载]

单片机实现按键短按双击长按程序

[复制链接]
228|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
dspmana|  楼主 | 2023-11-25 15:04 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式



/*-----------------------------------------------
  名称:按键
------------------------------------------------*/
#include"key.h"
extern unsigned char keyvalue;

unsigned char keyscan()
{
        unsigned char keynumber;
        if(!KEY1) keynumber = 1;                                                                        //!!!修改此处,可以增加/减少按键数量
        else if(!KEY2) keynumber = 2;                                                        //!!!修改此处,可以增加/减少按键数量
        else if(!KEY3) keynumber = 3;                                                        //!!!修改此处,可以增加/减少按键数量
        else if(!KEY4) keynumber = 4;                                                        //!!!修改此处,可以增加/减少按键数量
        else keynumber = 0;
        return keynumber;
}

unsigned char key_multi(void)
{
        static uchar key_state;                                                                         //按键状态变量
        static uint key_time;                                                                                 //按键计时变量
        static uchar key_press_nums;                                                        //按键次数变量               
        static uint key_time_double;                                                        //按键双击时间
        static uchar keynum;                                                                                        //键值
        static uchar new_keynum;                                                                        //新的键值
        uchar key_press, key_return;                                                        //键值和返回值
      
        key_return = None_click;                                                                         //清除返回按键值
      
        switch(keyscan())
        {
                case 1:key_press = KEY1;new_keynum = 1;break;                //!!!修改此处,可以增加/减少按键数量
                case 2:key_press = KEY2;new_keynum = 2;break;                //!!!修改此处,可以增加/减少按键数量
                case 3:key_press = KEY3;new_keynum = 3;break;                //!!!修改此处,可以增加/减少按键数量
                case 4:key_press = KEY4;new_keynum = 4;break;                //!!!修改此处,可以增加/减少按键数量
                default:key_press = 1;break;
        }
        if(key_press_nums > 0)                                                                                 //按键次数大于0,说明有按键
        {
                key_time_double++;                                                                                        //是否开始双击计
                if(key_time_double >= DOUBLE_KEY_TIME && key_time_double < LONG_KEY_TIME) key_state = KEY_STATE_2;//如果时间到了在双击和长按之间,切换到状态2
        }
        switch (key_state)
        {
                case KEY_STATE_0:                                                                                         //按键状态0:判断有无按键按下
                {
                        if (!key_press)                                                                                         //是否有按键按下,没有按下就退出
                        {
                                key_time = 0;                                                                                         //清零时间间隔计数
                                key_state = KEY_STATE_1;                                                 //然后进入 按键状态1
                        }
                }break;
                case KEY_STATE_1:                                                                                         //按键状态1:软件消抖(确定按键是否有效,而不是误触)。按键有效的定义:按键持续按下超过设定的消抖时间。
                {
                        if (!key_press)
                        {
                                key_time++;                                                                                                 //一次10ms
                                if(key_time>=SINGLE_KEY_TIME)                         //消抖时间为:SINGLE_KEY_TIME*10ms = 10ms;
                                {
                                        key_state = KEY_STATE_2;                                         //如果按键时间超过 消抖时间,即判定为按下的按键有效。进入按键状态2,继续判定到底是单击、双击还是长按
                                        key_press_nums++;                                                                        //按键次数+1
                                }
                        }
                        else key_state = KEY_STATE_0;                                 //如果按键时间没有超过,判定为误触,按键无效,返回 按键状态0,继续等待按键
                }break;
                case KEY_STATE_2:                                                                                         //按键状态2:判定按键有效的种类:是单击,双击,还是长按
                {
                        if(key_press)                                                                                                 //如果按键在 设定的双击时间内释放,则判定为单击/双击
                        {
                                if(key_time_double < DOUBLE_KEY_TIME ) key_state = KEY_STATE_0;                                                        //双击时间达到前,再次扫描按键,看还有没有按键按下
                                if(key_time_double >= DOUBLE_KEY_TIME && key_time_double < LONG_KEY_TIME)         //达到双击设定时间后,如果时间超过双击的时间则判断按键按下的次数
                                {
                                        if(key_press_nums == 1) key_return = Single_click + new_keynum*10;                                 //判断只按了1次,返回有效按键值:单击,通过不同的值判断是哪个按键按下的单击
                                        else if(key_press_nums ==2 && new_keynum == keynum) key_return = Double_click + new_keynum*10;         //判断按了2次和两次按键按的一样,返回有效按键值:双击,通过不同的值判断是哪个按键按下的双击
                                        key_state = KEY_STATE_0;                                         //返回 按键状态0,继续等待按键
                                        key_press_nums = 0;                                                                //清空按键次数
                                        key_time_double = 0;                                                        //清空双击计时
                                }
                                if(key_time_double >LONG_KEY_TIME ) key_state = KEY_STATE_3;        //如果长按之后才松开的,则切换到状态3清0
                        }
                        else
                        {      
                                key_time++;                                                                                                        //按键一直按着的话,长按计时
                                if(key_time >= LONG_KEY_TIME)                         //如果按键时间超过 设定的长按时间(LONG_KEY_TIME*10ms=80*10ms=800ms), 则判定为 长按
                                {
                                        key_return = Long_click + new_keynum*10;         //返回有效键值值:长按,通过不同的值判断是哪个按键按下的长按了
                                        //key_state = KEY_STATE_3;                                         //去状态3,等待按键释放
                                }
                        }
                }break;
                case KEY_STATE_3:                                                                                         //等待按键释放
                {
                        if (key_press)
                        {
                                key_state = KEY_STATE_0;                                                 //按键释放后,进入 按键状态0 ,进行下一次按键的判定
                                key_press_nums = 0;                                                                        //清空按键次数
                                key_time_double = 0;                                                                //清空双击计时
                        }
                }break;
                default:key_state = KEY_STATE_0;break;        //特殊情况:key_state是其他值得情况,清零key_state。这种情况一般出现在 没有初始化key_state,第一次执行这个函数的时候
        }
        keynum = new_keynum;                                                                                        //将新获取的键值赋值给键值
        return key_return;                                                                                                 //返回 按键值
}


使用特权

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

本版积分规则

24

主题

2371

帖子

2

粉丝