切换到宽版
  • 526阅读
  • 7回复

[C51]按键长按快调功能如何写? [复制链接]

上一主题 下一主题
离线lipeixian
 

发帖
461
M币
148
专家
1
粉丝
12
平时使用的按键是单点式的,一次按下数据+1,但是有些调整数值范围太大,一次+1的调整需要较长时间,想增加一个长按快调的功能,不知怎么写。
离线bg4rff

发帖
1451
M币
1230
专家
8
粉丝
28
只看该作者 1楼 发表于: 12-03
用定时器监测按键按下的时间,超过1秒(例子)就认为是长按,然后累加值可以是10,50
或者设定步长,然后再加减也行
回江苏南通如东了,闲暇时间较多,欢迎交流
离线thinkabout44

发帖
1172
M币
2353
专家
6
粉丝
63
只看该作者 2楼 发表于: 12-03
你这个需求不叫长按,叫连击功能。
离线lin28

发帖
2
M币
-47
专家
0
粉丝
0
只看该作者 3楼 发表于: 12-03
1楼 说得应该对
离线netbeetle

发帖
599
M币
821
专家
3
粉丝
7
只看该作者 4楼 发表于: 12-03
把按键扫描放在定时器中断里面,比如1毫秒一个中断,按下开始计时,抬起判断时间,这样你想定义多少时间段就可以定义多少时间段,而且精准可靠,而且连消抖一起了。
离线z2091981

发帖
1555
M币
3508
专家
13
粉丝
63
只看该作者 5楼 发表于: 12-04

短按加一,长按连加,带按钮防抖

if(!key)
{
  key_buf++;
}
else
{
  key_buf = 0;
}

if(key_buf == 100)
{
   i++;//短按一下,加一
}

if(key_buf > 500)
{
  key_buf = 400;  //长按,连续加
  i++;
}
本帖最近打赏记录:共2条打赏M币+23
山东人 M币 +15 - 12-07
cmheia M币 +8 精彩回帖 写点打赏理由吧 12-07
只要有心,无处不是风景
离线cmheia

发帖
11642
M币
6431
专家
9
粉丝
116
只看该作者 6楼 发表于: 12-07
精彩回帖 写点打赏理由吧
离线ayumi7

发帖
12332
M币
3848
专家
25
粉丝
5724
只看该作者 7楼 发表于: 12-07
      -----------------------以下内容为转载,非原创,但亲测可用-----------------

以三行核心算法为主导,可以识别压下(下降沿)、弹起(上升沿)、短按、长按、连发、多次采样消抖的程序基本完善,可以和状态机键盘媲美了。

#define TIMES                        3                        //采样次数设定
#define READ_KEYPORT        P1^0xFF                //读键盘口

/* 2次采样 */
void KeyRead() {
        static u8 Curr = 0;
        static u8 Last;

        Last = Curr;
        Curr = READ_KEYPORT;
        if (Curr^Last)  return;

        TrgDown = Curr & (Curr ^ Prev);                //Down跳变
        TrgUp   = Prev & (Curr ^ Prev);                //Up跳变
        Prev = Curr;                                        //前次值
}

/* TIMES+1次采样 */
void KeyRead() {
        static u8 Curr = 0;
        static u8 Last;
        static u8 ii = 0;

        if(ii==0)  Last = Curr;

        while (ii < TIMES) {
                Curr = READ_KEYPORT;
                if (Curr^Last)        { ii = 0; return; }
                else                        { ii++;   return; }
        }
        ii = 0;

        TrgDown = Curr & (Curr ^ Prev);                //Down跳变
        TrgUp   = Prev & (Curr ^ Prev);                //Up跳变
        Prev = Curr;                                        //前次值
}

程序分二种,如果只需要2次采样,则用第一种方式,简单明了。
如果需要多次采样,则用第二种方式,适用于任何干扰的场合,采样次数TIMES最大值255,也就是255*10ms=2.55s,一般4-5次采样足够了。






执行举例:
#define KEY_BEEP 0x01
void KeyProc(void)
{
       if (Trg & KEY_BEEP) // 如果按下的是KEY_BEEP
    {
         Beep();            // 执行蜂鸣器处理函数
    }
}

可以判断到长按 + 10  +100 之类的