单个按键程序,实现单击双击长按

2020-01-14 18:57发布

本帖最后由 cumthe 于 2013-9-29 09:44 编辑

闲来无事,写了一个小程序,欢迎讨论和拍砖。
扫描在定时器中应该占不了太多资源。

enum Btn{NoClick = 0,ShortClick,DoubleClick,LongClick};
enum Btn        BtnState = NoClick ;

#define LongClickTime        1000UL
#define DoubleClickTimeDur        200

定时器中:
        static unsigned int count = 0,ShortClickFlag = 0,ShortClickFlagCount = 0;

        if(SW == 0)
        {
                  count++;
        }
        else
        {
                 if(count>=5 && count < LongClickTime)
                {
                         if(ShortClickFlag == 1)
                        {       
                                ShortClickFlag = 0;
                                BtnState = DoubleClick;
                        }
                        else
                        {
                                 ShortClickFlag = 1;
                        }
                }
                else if(count >= LongClickTime)
                {
                         BtnState = LongClick;
                }
                count = 0;
                if(ShortClickFlag == 1)
                {                
                        if(ShortClickFlagCount++ > DoubleClickTimeDur)
                        {
                                 BtnState = ShortClick;
                                ShortClickFlag = 0;
                                ShortClickFlagCount = 0;
                        }       
                }
                else
                {
                         ShortClickFlagCount = 0;
                }               
        }

主函数中:
注意在使用BtnState 后,需将其置位NoClick
                switch(BtnState)
                {
                        case        NoClick:
                                break;
                         case        ShortClick:
                                BtnState = NoClick;
                                break;
                        case        DoubleClick:
                                BtnState = NoClick;
                                break;
                        case        LongClick:
                                BtnState = NoClick;
                                break;
                }       

修改后:
定时器中:
        static unsigned int count = 0,ShortClickFlagCount = 0;        
        //count为按键按下计时变量;ShortClickFlagCount为单击按键后超时判断是否有双击计时变量
        static unsigned char ShortClickFlag = 0,LongClickFlag = 0;       
        //ShortClickFlag为单击按键标志,判断双击时用;LongClickFlag为长按按键标志,防止按键按下不释放

        if(SW == 0)
        {
                if(count < LongClickTime)
                {
                         count++;
                }
                else
                {
                         BtnState = LongClick;
                        LongClickFlag = 1;
                }
        }
        else
        {
                 if(count>=5 && count < LongClickTime)
                {
                         if(ShortClickFlag == 1)
                        {       
                                ShortClickFlag = 0;
                                BtnState = DoubleClick;
                        }
                        else
                        {
                                 ShortClickFlag = 1;
                        }
                }
                else if(count >= LongClickTime && LongClickFlag == 0)
                {
                         BtnState = LongClick;
                }
                LongClickFlag = 0;
                count = 0;
                if(ShortClickFlag == 1)
                {                
                        if(ShortClickFlagCount++ > DoubleClickTimeDur)
                        {
                                 BtnState = ShortClick;
                                ShortClickFlag = 0;
                                ShortClickFlagCount = 0;
                        }       
                }
                else
                {
                         ShortClickFlagCount = 0;
                }               
        }

主函数中:
注意在使用BtnState 后,需将其置位NoClick
                switch(BtnState)
                {
                        case        NoClick:
                                break;
                         case        ShortClick:
                                BtnState = NoClick;
                                break;
                        case        DoubleClick:
                                BtnState = NoClick;
                                break;
                        case        LongClick:
                                BtnState = NoClick;
                                break;
                        default:       
                                break;
                }       
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
29条回答
gallle
1楼-- · 2020-01-16 12:34
如果长按那里是不是做个超时判断啊?否则一直按住不放~~会不会造成假象?
cumthe
2楼-- · 2020-01-16 15:27
gallle 发表于 2013-9-28 19:25
如果长按那里是不是做个超时判断啊?否则一直按住不放~~会不会造成假象? ...

对。加个超时,如果大于某个值后等待按键释放,count停止增加。
newID
3楼-- · 2020-01-16 20:21
绑定,做个记号
bbglx
4楼-- · 2020-01-17 01:07
 精彩回答 2  元偷偷看……
zuu0
5楼-- · 2020-01-17 05:38
好像有个问题,,长按情况下,一般是只执行一次。。而你是执行1000后,清0,如果我还继续再按住没放,继续1000 你又会出现一个长按

第二个问题,你看过哪个长按是带松手操作的么? 


当同一个按键有长按,短按时,短按做松手检测,长按是不做松手检测的,长按时间到了,就进去了长按处理程序,而且只进入一次,哪怕你按住一天,它也只进入一次!(当然数据连发,中间再加判断)
vc8fans
6楼-- · 2020-01-17 05:43
老问题,得重新好好学

一周热门 更多>