标题: 单片机怎么实现独立按键长按和短按的不同效果 [打印本页]

作者: 撒打算(⊙o⊙)哦    时间: 2020-2-27 11:10
标题: 单片机怎么实现独立按键长按和短按的不同效果
我想让k1长按0.2s后led发光,长按2s后熄灭,为什么下面这个代码实现不了这个功能


单片机源程序如下:
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
uint i;
sbit k1=P3^1;
sbit led=P2^1;



void init()
{
        TMOD=0X01;
        TH0=(65536-10000)/256;                                        //10ms
        TL0=(65536-10000)%256;
        EA=1;
        ET0=1;
                TR0=1;
}




void main()
{        
        init();
        while(1)
        {
                while(k1==1)
                {
                        i=0;
                        led=1;
                }
                while(k1==0)
                {
                        if(200>i>20)
                        {
                                led=0;
                        }
                        if(i>=200)
                        {
                                led=1;
                        }
                }
        }  
}

void time() interrupt 1
{
        TH0=(65536-10000)/256;
        TL0=(65536-10000)%256;
        i++;

               
}


作者: man1234567    时间: 2020-2-27 13:50
把中断里的  i++; 剪贴到  if(200>i>20) 之前试试。
作者: 笨笨兔    时间: 2020-2-27 14:04
程序结构不合理。
关键是:按键查询时没有消除抖动的处理。
......
作者: jhczy    时间: 2020-2-27 14:53
k1按下后,启动一个计数器,长按和短按时计数器出来不同的数字,启动相应的执行程序
作者: 撒打算(⊙o⊙)哦    时间: 2020-2-27 15:16
man1234567 发表于 2020-2-27 13:50
把中断里的  i++; 剪贴到  if(200>i>20) 之前试试。

不行啊
作者: 撒打算(⊙o⊙)哦    时间: 2020-2-27 15:27
笨笨兔 发表于 2020-2-27 14:04
程序结构不合理。
关键是:按键查询时没有消除抖动的处理。
......

我加了消抖还是不行啊

作者: haierzaifei11    时间: 2020-2-27 16:32
加了消抖还是不行?那等你解决了,不要忘了贴上啊
作者: xuyaqi    时间: 2020-2-27 16:59
修改了一下:
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
uint i;
sbit k1=P3^1;
sbit led=P2^1;

sbit led0=P2^0;
sbit led2=P2^2;
sbit led3=P2^3;
sbit led4=P2^4;

sbit led7=P2^7;


void init()
{
                TMOD=0X01;
                TH0=(65536-10000)/256;                                        //10ms
                TL0=(65536-10000)%256;
                EA=1;
                ET0=1;
                TR0=1;
}

void main()
{        
        init();
        while(1)
        {
                if(k1==1)
                {
                        i=0;
                        led=1;
                }
                if(k1==0)
                {
                        if(i < 100)//&&(i!=0)
                        {
                                led=0;
                        }
                        else
                        {
                                led=1;
                        }
                }
        }  
}

void time() interrupt 1
{
        TH0=(65536-10000)/256;
        TL0=(65536-10000)%256;
       
        led7=~led7;
        i++;
}


作者: 007    时间: 2020-2-27 18:23
加一个定时判断啊,先检测到按键按下定时器计时,200ms后在判断一次,如果按键状态还是按下就点灯,然后2000ms加一次判断,如果按键状态不变,灭灯,反正就是只要按键按下了,就做两次判断
作者: wulin    时间: 2020-2-27 18:36
在你的程序基础上改的按键长短按LED开关
  1. #include<reg52.h>
  2. #define uchar unsigned char
  3. #define uint unsigned int
  4. uint i;
  5. sbit k1=P3^1;
  6. sbit led=P2^1;

  7. void init()
  8. {
  9.         TMOD=0X01;
  10.         TH0=(65536-10000)/256;//10ms
  11.         TL0=(65536-10000)%256;
  12.         EA=1;
  13.         ET0=1;
  14.         TR0=1;
  15. }

  16. void main()
  17. {        
  18.         init();
  19.         while(1);  
  20. }

  21. void time() interrupt 1
  22. {
  23.         TH0=(65536-10000)/256;
  24.         TL0=(65536-10000)%256;
  25.         if(!k1)   
  26.         {  
  27.                 if(i<200)
  28.                         i++;
  29.                 if(i>=200)                                //长按2秒以上
  30.                         led=1;
  31.         }  
  32.         else
  33.         {  
  34.                 if(i>20 && i<200)                //短按0.2~2秒
  35.                         led=0;
  36.                 i=0;
  37.         }
  38. }
复制代码

作者: huitata    时间: 2020-2-27 19:02
给你分析一下哈,假如按键按下为0,led=0时点亮:按下后key后led直接先是无反应,i加到20后点亮,此时不松开等到i加到200,led熄灭。如果一直不松,i值将会溢出,
作者: huitata    时间: 2020-2-27 19:07
按你说的你这个就是按下后不松,0.2秒后点亮,持续不松,2S后熄灭
问题1:长时间按住i会溢出
问题2:你的这两个动作都要建立在不松手的前提下,如果松开,无论之前任何状态,都将变成熄灭
总结:逻辑不对,程序不合理,while里面再套俩while,看着很别扭,推荐switch case了解一下
作者: lebrojames    时间: 2020-2-27 19:39
k1按下后,启动一个计数器,长按和短按时计数器出来不同的数字,启动相应的执行程序
作者: hj08102    时间: 2020-2-27 20:54
试试改下代码

新建位图图像.png (14.09 KB, 下载次数: 114)

试试改下代码

试试改下代码

作者: hj08102    时间: 2020-2-27 20:56
回复慢了,回来再看多出老多的答案,坛子里面高手多呀,祝愿论坛越来越好
作者: hxszrb    时间: 2020-3-7 12:32
最近也在学习按键这块就进来看了,题主要的应该不是手一直按着按键吧,如果是这样这个实际用的地方并不多。我理解题主要的应该是短按LED亮、长按灭,看回复多不能实现这样功能。
作者: 1175514240    时间: 2020-3-7 13:30
按一次去抖然后按下启动计数器,松开取值计数器,以此数值判断并执行相应操作
作者: 1175514240    时间: 2020-3-7 13:33
注意按键处理请在按键松开时进行。
作者: stealth123    时间: 2020-3-31 12:45
楼主改好代码了吗  能贴一下吗

作者: stealth123    时间: 2020-3-31 12:45
;楼主完善好代码了吗  麻烦贴一下参考
作者: lingaosou    时间: 2020-3-31 22:18
用一个按键检测函数就可以




欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1