找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2338|回复: 14
打印 上一主题 下一主题
收起左侧

关于单片机按键处理程序,短按1次,短按3次,长按3秒,长按10S,怎么去做好点?

  [复制链接]
跳转到指定楼层
楼主
ID:344646 发表于 2021-12-21 15:18 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
求助,PIC单片机,做按键处理的时候,短按1次,短按3次,长按3秒,长按10S,怎么去做好点,目前知道利用判断按下时长作为区分短按长按的关键,,可是短按3次怎么去判断,求大神解答下。。
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏3 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:130230 发表于 2021-12-24 18:17 | 只看该作者
搜下状态机按键很适合处理你这种
回复

使用道具 举报

板凳
ID:908826 发表于 2021-12-25 10:03 | 只看该作者
楼主搞出来记得分享一下,我看了你这个东西也是没有思路
回复

使用道具 举报

地板
ID:401564 发表于 2021-12-25 11:47 | 只看该作者
你得有一个时间间隔的标准,比如是0.5秒
那么,按下第一次之后,计时并标记第一次按下,0.5秒之内如果有再次按下,标记第二次按下,0.5秒之内如果有再次按下,标记第三次按下,第三次按下有效,这就是短按3次
每次按下,0.5秒之内没有再次按下,清除按下标志位
回复

使用道具 举报

5#
ID:136119 发表于 2021-12-25 12:47 | 只看该作者
这个是我的是个按键处理程序 ,有点复杂,你能看懂 就能解决你的问题
void Verify_init (void)  是一个按键初始化程序
一下中断调用

Verifydata(&VY_Lock);     //获取按键
Verifydata(&VY_ZJQ);      //获取按键
Verifydata(&VY_Key);          //按动确认       

if( VY_Key.Movement==0 )
{
    if(VY_Key.MovementTime<8)
    {
        按键次数计数       
            VY_Key.MovementTime =10;
    }
    if(VY_Key.MovementTime<25)长时间按键处理
    {

    }
}

if( VY_Key.Movement==1 )
{
    if(VY_Key.MovementTime<250)
    {
     执行一次按键处理
     执行按键二次处理
     执行按键三次处理
     清除按键次数计数
    }

}
以上中断中调用
///////////////////////////////////////////////
//////////////////////////////////////////////
/////////////////////////////////////////////

typedef struct
{
        unsigned char Location ; // 数据标记
        unsigned char Position ; // 按键临时位置
        unsigned char flag        ; //按键确认标记,循环执行N次被标记。
        unsigned char Movement ;  //动作
        unsigned char MovementTime;        //未松开动作用时
}  SIN_Verify ;

SIN_Verify  VY_Lock , VY_Key ,VY_ZJQ;  //

/*---------------------------------------------------------------
* 函 数 名: Verify_init ()
* 参 数:    void
* 返 回 值:uint8
* 功能描述:  读取当前IO数据
* 异常:     无
* 作 者:   
----------------------------------------------------------------*/
void Verify_init (void)
{
        VY_Lock.Location = 1;
        VY_Key.Location = 2;
        VY_ZJQ.Location = 3;
}
/*---------------------------------------------------------------
* 函 数 名: keyIn()
* 参 数:    void
* 返 回 值: void
* 功能描述:  

* 异常:     无                  
* 作 者:   
----------------------------------------------------------------*/
void Verifydata(SIN_Verify* verify )
{       
        u8 i;
        switch (verify ->Location)
  {
          case 1 : i = IN_Lock ;  //获取端锁端口信息
                  break;
          case 2 : i = IN_Key  ; //获取按键端口信息
                  break;
                case 3 : i = IN_ZJQ  ; //获取按键端口信息
                  break;
          default:                 //写入数据失败
                  break;
  }
  
        if(verify -> Position == i & (verify -> MovementTime != 255))
        {
                if((verify -> flag) > 6 )
                {                 
                        //长期验证////////////////////
     if(i == verify -> Movement )
                 {
                                if(verify -> MovementTime != 0xff)
                                ++(verify -> MovementTime);                        
                 } else { verify -> MovementTime = 0 ;}
                 //长期验证END/////////////////
                 
                 //确认信息////////////////////                 
                 verify -> Movement = i;
                 verify -> flag = 0;
                 //确认信息END/////////////////       
                }else ++(verify -> flag); // 标记累加
        }       
        if(verify -> Position != i)
        {
    if(verify -> MovementTime==255)
                verify -> MovementTime = 252;
                verify -> Position = i;       
        }
}

回复

使用道具 举报

6#
ID:488334 发表于 2021-12-25 15:25 | 只看该作者
本帖最后由 tatachaoren 于 2021-12-25 15:28 编辑

上一楼其实给的思路挺好的,细说一点的话
1:在3秒之内松开,算一次短按。或者1秒之内松开,算1次短按,若超过1秒,小于3秒,可以不算任何按键。松开之后计时0.5秒(这个时间你可以自己做主),若在0.5秒内,再次按下,根据前面的定义,3秒(1秒)内松开,次数加1。若在短按三次时,中间长按超过三秒,则清零这个计数器,算长按3秒。
2:长按十秒这个功能,若在长按未达到十秒, 你可以算3秒,或者不算。长按计时多少秒算长按3秒,自己定义也行。
3:若是一个按键做所有功能,就可以根据1,2来做分段处理。其实类似计时时间然后分段处理:短按一次(<3秒松开或者<1秒松开,PS:自己定义),长按3秒(3秒<X<10秒或者3秒<X<7秒 :7秒<X<10秒算无效,PS:自己定义),长按>=10秒(因为10秒之后没有其他功能,可以不用松开立即执行)
回复

使用道具 举报

7#
ID:344646 发表于 2022-1-13 10:57 | 只看该作者
tatachaoren 发表于 2021-12-25 15:25
上一楼其实给的思路挺好的,细说一点的话
1:在3秒之内松开,算一次短按。或者1秒之内松开,算1次短按,若 ...

感谢~~~
回复

使用道具 举报

8#
ID:344646 发表于 2022-1-13 10:57 | 只看该作者
yuyechenai 发表于 2021-12-25 12:47
这个是我的是个按键处理程序 ,有点复杂,你能看懂 就能解决你的问题
void Verify_init (void)  是一个按 ...

感谢~~
回复

使用道具 举报

9#
ID:344646 发表于 2022-1-13 10:59 | 只看该作者
13205495918 发表于 2021-12-25 10:03
楼主搞出来记得分享一下,我看了你这个东西也是没有思路

楼下写的思路就很清晰,可以参考写下。。
回复

使用道具 举报

10#
ID:192883 发表于 2022-1-13 21:34 | 只看该作者
采用定时器的带滤波的输入捕获。键按下是启动计时器,键抬起时停止计时器;看计时器的值就得到结果。
回复

使用道具 举报

11#
ID:625730 发表于 2022-1-13 22:56 | 只看该作者
                51单片机可以用的代码。
                unsigned char flag=0,count1=0,count2=0;//flag 标识位,count1单次按键时长预估,count2短按计数
                if(key1==0)//按键按下
                {
                        delay_ms(10);//延时10ms防止干扰
                        if(key1==0)//确认按键按下
                        {
                                while(!key1)//等待按键松开
                                {
                                        delay_ms(100);//延时100毫秒
                                        count1++;//估算按键持续时间
                                }
                                if(count1<15)//持续时间小于1.5秒视为短按,count2的值改变。
                                {
                                        count2++;
                                        count1=0;
                                }
                                if((count1<15)&&count2==3)//短按三次
                                {
                                        flag=1;
                                        count1=0;
                                        count2=0;
                                }
                                else if((count1>=15)&&(count1<70))//按键持续1.5s~7s之间,不是短按,都把count2置0
                                {
                                        flag=2;
                                        count1=0;
                                        count2=0;
                               
                                }
                                else if(count1>=100)//持续时间大于10秒的长按
                                {
                                        flag=3;
                                        count1=0;
                                        count2=0;
                                }
回复

使用道具 举报

12#
ID:625730 发表于 2022-1-13 23:35 | 只看该作者
在按键扫描的过程中,都有一个按键释放的循环语句while(!key_x),这个循环语句里可以添加延时和计数。
  1. unsigned char flag=0,count1=0,count2=0; //定义标识符,按键计时,短按计数器
  2. /××按键检测  ×/       
  3.                 if(key1==0)
  4.                 {
  5.                         delay_ms(10);//延时10ms防止干扰
  6.                         if(key1==0)
  7.                         {
  8.                                 while(!key1)//等待按键松开
  9.                                 {
  10.                                         delay_ms(100);//延时100毫秒
  11.                                         count1++;//估算按键持续时间
  12.                                 }
  13.                                 if(count1<15)//count<1.5s视为短按
  14.                                 {
  15.                                         count2++;
  16.                                         count1=0;
  17.                                 }
  18.                                 if((count1<15)&&count2==3)//短按三次
  19.                                 {
  20.                                         flag=1;
  21.                                         count1=0;
  22.                                         count2=0;
  23.                                 }
  24.                                 else if((count1>=15)&&(count1<70))//按键持续1.5s~7s之间
  25.                                 {
  26.                                         flag=2;
  27.                                         count1=0;
  28.                                         count2=0;
  29.                                
  30.                                 }
  31.                                 else if(count1>=100)//大于10秒的长按
  32.                                 {
  33.                                         flag=3;
  34.                                         count1=0;
  35.                                         count2=0;
  36.                                 }
复制代码
回复

使用道具 举报

13#
ID:161164 发表于 2022-1-14 11:40 | 只看该作者
TEC 发表于 2022-1-13 23:35
在按键扫描的过程中,都有一个按键释放的循环语句while(!key_x),这个循环语句里可以添加延时和计数。

短按一次呢?
回复

使用道具 举报

14#
ID:453974 发表于 2022-1-18 20:50 | 只看该作者
定时器设置标志位,设定按键按下时长的区间范围,用定时器计数
回复

使用道具 举报

15#
ID:1040201 发表于 2022-8-13 16:25 | 只看该作者
这个好 ,学习到了,51黑有你更精彩。。。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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