找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3461|回复: 29
收起左侧

关于单片机按键长按过程中触发短按的问题?萌新求各位指导

  [复制链接]
ID:540927 发表于 2020-8-29 11:15 | 显示全部楼层 |阅读模式
我的程序在按键长按过程中会触发短按,一般一次长按在开始和结束时各触发一次短按,不知道怎么改程序才合适,求各位指导
捕获.PNG
回复

使用道具 举报

ID:816093 发表于 2020-8-29 12:15 | 显示全部楼层
应该是按下的时候 按键的机械抖动 造成侧毛刺信号 所以触发了短按检测 在按下和结束的时候加延时再检测试一下
回复

使用道具 举报

ID:236035 发表于 2020-8-29 13:31 | 显示全部楼层
if(exKeyValueFlag != 0)
{
        if(i<1000)
        {
                i++;
                if(i > 1500)
                {
                        longkeyflag = 1;
                        i = 0;
                }
        }
}
else
{
        if(i>50)
        {
                shortkeyflag = 1;
                i = 0;
        }
        else
                i = 0;
}
回复

使用道具 举报

ID:236035 发表于 2020-8-29 13:32 | 显示全部楼层
1 上面的回复是纯手打,因为楼主位的程序无法复制
2 有问题先百度下,有很多经典例程,如果实在解决不了,再发贴提问 。
回复

使用道具 举报

ID:540927 发表于 2020-8-29 14:14 | 显示全部楼层
meitao 发表于 2020-8-29 12:15
应该是按下的时候 按键的机械抖动 造成侧毛刺信号 所以触发了短按检测 在按下和结束的时候加延时再检测试一 ...

感谢您的回复,消抖已经处理过了,我只粘贴出来计数部分
回复

使用道具 举报

ID:540927 发表于 2020-8-29 14:18 | 显示全部楼层
ly1972001 发表于 2020-8-29 13:32
1 上面的回复是纯手打,因为楼主位的程序无法复制
2 有问题先百度下,有很多经典例程,如果实在解决不了, ...

辛苦了,感谢您的程序和建议
回复

使用道具 举报

ID:540927 发表于 2020-8-29 14:33 | 显示全部楼层
ly1972001 发表于 2020-8-29 13:31
if(exKeyValueFlag != 0)
{
        if(i 1500)

谢谢您的代码,参考了您的代码,抬起手的时候不触发短按了,但是刚开始的时候还是触发了短按
回复

使用道具 举报

ID:540927 发表于 2020-8-29 15:08 | 显示全部楼层
ly1972001 发表于 2020-8-29 13:31
if(exKeyValueFlag != 0)
{
        if(i 1500)


这是修改后的程序
捕获.PNG
回复

使用道具 举报

ID:89515 发表于 2020-8-30 11:43 来自手机 | 显示全部楼层
山水间 发表于 2020-8-29 15:08
这是修改后的程序

按键按下
{
}
回复

使用道具 举报

ID:89515 发表于 2020-8-30 12:11 来自手机 | 显示全部楼层
山水间 发表于 2020-8-29 15:08
这是修改后的程序

按键按下
{
1:确定按下实现短按键功能退出
2:按键是否弹起?
     弹起退出进入3
按键没弹起,延时变量加,
      延时变量是否达到设定值?
达到,实现长按键功能退出进入3
未达到,退出返回2
3:清除变量退出返回1
}
无论你要做什么按键逻辑上首先要保证按键按下
吧,你的程序就算勉强实现,逻辑也有很大的问题。
回复

使用道具 举报

ID:89515 发表于 2020-8-30 12:14 来自手机 | 显示全部楼层
山水间 发表于 2020-8-29 15:08
这是修改后的程序


1:确定按下实现短按键功能退出
2:按键是否弹起?
     弹起退出进入3
按键没弹起,延时变量加,
      延时变量是否达到设定值?
达到,实现长按键功能退出进入3
未达到,退出返回2
3:清除变量退出返回1

无论你要做什么按键逻辑上首先要保证按键按下
过吧,你的程序就算勉强实现,逻辑也有很大的问题。
回复

使用道具 举报

ID:89515 发表于 2020-8-30 12:17 来自手机 | 显示全部楼层
这种程序用状态机最简单,单个按键所有的按键功能都可以在里面实现
回复

使用道具 举报

ID:808485 发表于 2020-8-31 14:39 | 显示全部楼层
一般区分长短,是在抬起的时候判断,
如果还未抬起的情况下要做出判断,那长按过程肯定会经过短按的时间,这个逻辑应该容易理解,就像走路100步,会先走过30步。
对于单键多用,建议用单击/双击的方法,像鼠标那样。
回复

使用道具 举报

ID:540927 发表于 2020-8-31 14:52 | 显示全部楼层
本帖最后由 山水间 于 2020-8-31 15:27 编辑
mengzhixinheng 发表于 2020-8-30 12:17
这种程序用状态机最简单,单个按键所有的按键功能都可以在里面实现

感谢您的回复,现在我用状态机了,可惜连短按都无法实现
void key()
{
        static CHAR keystate = keystate0;
        INT16U keytime = 0;
        CHAR keypress;
        keypress = exKeyValueFlag;            //读取按键
        switch(keystate)
        {
                case keystate0:
                        if(keypress != 0)
                        {
                                keystate =keystate1;
                        }
                        break;
                        
                case keystate1:                      //计时状态
                        if(keypress != 0)
                        {
                                keytime++;
                                keystate = keystate2;
                        }
                       
                        break;
                        
                case keystate2:                      //按键判断状态
                        if(keypress == 0)
                        {
                                if((keytime >= 10)&&(keytime <= 1000))
                                {
                                        keytime = 0;
                                        shortkeyflag = 1;
                                        keystate = keystate0;
                                }
                                else if(keytime >= 3000)
                                {
                                        keytime = 0;
                                        longkeyflag =1;
                                        keystate = keystate0;
                                }
                        }
                        else
                        {
                                keystate = keystate1;
                        }
                break;     
        }
}
回复

使用道具 举报

ID:540927 发表于 2020-8-31 14:53 | 显示全部楼层
gbchang 发表于 2020-8-31 14:39
一般区分长短,是在抬起的时候判断,
如果还未抬起的情况下要做出判断,那长按过程肯定会经过短按的时间, ...

好的,谢谢您的回复,我试着这么做
回复

使用道具 举报

ID:511890 发表于 2020-9-1 00:23 | 显示全部楼层
有很多问题。if语句的用法问题。if语句每一个分支都必须是唯一的。你的if语句第一个i<10000,和第二个i>50,当i=51---9999的时候,两个if分支是同事触发的。
然后是按键事件问题,一般这个情况都是在按键抬起(exKeyValueFlag == 0)时进行事件处理。

修改程序如下:
if(exKeyValueFlag != 0)
{
    if(i<10000) {
           i++;
    }
    else{
         i=10000;//i达到最大值时定住,防止溢出
     }
}
else   //当按键抬起时做判断
{
        if(i > 1500) {
                        longkeyflag = 1;
                }
        else{                           //这里也可以按照你的意思:if(i>50 && i<200)
               shortkeyflag = 1;
        }
        }
     i = 0;//i初始化
}
--------------------------------------
前天发的好像不见了。再发以下。
有很多问题。if语句的用法问题。if语句每一个分支都必须是唯一的。你的if语句第一个i<10000,和第二个i>50,当i=51---9999的时候,两个if分支是同事触发的。
然后是按键事件问题,一般这个情况都是在按键抬起(exKeyValueFlag == 0)时进行事件处理。


if(exKeyValueFlag != 0)
{
    if(i<10000) {
           i++;
    }
    else{
         i=10000;//i达到最大值时定住,防止溢出
     }
  //if(i > 1500) {
  //                      longkeyflag = 1;
   //             }

}
else   //当按键抬起时做判断
{
        if(i > 1500) {
                        longkeyflag = 1;
                }
        else{                           //这里也可以按照你的意思:if(i>50 && i<200)
               shortkeyflag = 1;
        }
        }
     i = 0;//i初始化
}

一般这种情况都是按键抬起时再做事件。当然,也可以分成两部分,长按的放在按键按下时处理,也就是我注释掉的那三行。

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:469932 发表于 2020-9-1 08:24 | 显示全部楼层
很简单的问题绕了这么远,你不会在短按键时加1个标志位,在长按键中约束这个标志位?
比如if(SW长==0){.........FLAG1=0;//短按键失控......}
if(SW短 == 0  && FLAG == 1)这时的短按键无论如何不会触发......你品,你细品!
回复

使用道具 举报

ID:540927 发表于 2020-9-1 11:41 | 显示全部楼层
幻剑心 发表于 2020-9-1 00:23
前天发的好像不见了。再发以下。
有很多问题。if语句的用法问题。if语句每一个分支都必须是唯一的。你的if ...

感谢您的回复,您的这个方案我尝试了,不过长按不能触发,在长按的过程中短按也触发了,出发的时候按键还没有抬起,这与程序不符,可能是我用的弹簧按键有点特殊吧
回复

使用道具 举报

ID:540927 发表于 2020-9-1 11:44 | 显示全部楼层
Sawardeakar 发表于 2020-9-1 08:24
很简单的问题绕了这么远,你不会在短按键时加1个标志位,在长按键中约束这个标志位?
比如if(SW长==0){... ...

感谢您的建言,加个标志位我也有考虑过,不过关键是要在什么地方把标志位置1
回复

使用道具 举报

ID:540927 发表于 2020-9-1 11:48 | 显示全部楼层
gbchang 发表于 2020-8-31 14:39
一般区分长短,是在抬起的时候判断,
如果还未抬起的情况下要做出判断,那长按过程肯定会经过短按的时间, ...

我的短按就是在抬起时才判断的,但是实际执行过程中长按下去还没抬起就触发了短按
回复

使用道具 举报

ID:474670 发表于 2020-9-1 14:27 | 显示全部楼层
山水间 发表于 2020-9-1 11:44
感谢您的建言,加个标志位我也有考虑过,不过关键是要在什么地方把标志位置1

有句话叫经验不够,汗水来凑!别人将思路很明确的告诉你了,就是不知道去动动手,一味在那里干站着干问!很明显不要短按键误动作就放FLAG=0,要短按键动作就放FLAG=1;比如你手机。短按是开关机画面,按时间长一点就是重启与真正关机(这个时候的长按键与短按键都有效)
回复

使用道具 举报

ID:89515 发表于 2020-9-1 15:34 来自手机 | 显示全部楼层
gbchang 发表于 2020-8-31 14:39
一般区分长短,是在抬起的时候判断,
如果还未抬起的情况下要做出判断,那长按过程肯定会经过短按的时间, ...

你说的是常规方法,一直按下自然要经过短按键
但是如果用状态机把长按键放在下一个状态。与短按键不会互相影响,因为无论怎么做,每次按下传回的键值只能有一个。还有长按键,连续按键都是在按下状态去判断的,怎么可能弹起再判断,不符合逻辑。你想我按下按键,当延时到了就返回长按键键值实现功能,然后我松开按键这是正常的过程。如果抬起判断,你知道是什么后果吗?很简单,长按键的时间只能靠人为去感知,可能按短了实现不了,也可能按长了,功能倒是实现了,但你这样做了就知道很不爽的。
回复

使用道具 举报

ID:89515 发表于 2020-9-1 15:52 来自手机 | 显示全部楼层
山水间 发表于 2020-8-31 14:52
感谢您的回复,现在我用状态机了,可惜连短按都无法实现
void key()
{

函数内静态变量别赋值,要赋值就用全局变量,
怕变量多凌乱就就用结构体把相关的放一起。这个用状态机绝对很好,它可以让你避开一些互锁标志,过程很清晰,也不用管消抖,把按键程序写好了,做个20ms的时基,往里面一放就好了。你要用的只是返回的不同键值,与你实现的功能不要有太多的耦合。如果还是很久都搞不好,就做个简单的按键仿真,先把方法学会。
回复

使用道具 举报

ID:89515 发表于 2020-9-1 16:06 来自手机 | 显示全部楼层
山水间 发表于 2020-8-31 14:52
感谢您的回复,现在我用状态机了,可惜连短按都无法实现
void key()
{

函数内静态变量别赋常值,不然它怎么变化。如果不行,就做个仿真,把一个按键搞会,在嵌入你的程序。如果还不会再问吧!
回复

使用道具 举报

ID:540927 发表于 2020-9-1 16:24 | 显示全部楼层
站着说话不腰疼 发表于 2020-9-1 14:27
有句话叫经验不够,汗水来凑!别人将思路很明确的告诉你了,就是不知道去动动手,一味在那里干站着干问! ...

感谢您的建议,我会认真思考的
回复

使用道具 举报

ID:540927 发表于 2020-9-1 16:27 | 显示全部楼层
mengzhixinheng 发表于 2020-9-1 16:06
函数内静态变量别赋常值,不然它怎么变化。如果不行,就做个仿真,把一个按键搞会,在嵌入你的程序。如果 ...

好的,谢谢您如此详细又耐心的指导,我试着掌握状态机的用法
回复

使用道具 举报

ID:540927 发表于 2020-9-2 10:31 | 显示全部楼层
感谢所有回复提出宝贵建议的人,我的问题已经解决,真的谢谢大家
回复

使用道具 举报

ID:130230 发表于 2020-9-2 23:50 | 显示全部楼层
我再论坛里面发过一个状态机扫描按键的实例,你可以看一下。拿来即用的程序。
回复

使用道具 举报

ID:540927 发表于 2020-9-3 10:32 | 显示全部楼层
jizhongbiao 发表于 2020-9-2 23:50
我再论坛里面发过一个状态机扫描按键的实例,你可以看一下。拿来即用的程序。

好的,谢谢您的建议
回复

使用道具 举报

ID:475858 发表于 2022-9-14 14:01 | 显示全部楼层
站着说话不腰疼 发表于 2020-9-1 14:27
有句话叫经验不够,汗水来凑!别人将思路很明确的告诉你了,就是不知道去动动手,一味在那里干站着干问! ...

这样操作的话,短按一直不起作用了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表