找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机长按按键点亮、关闭LED灯的问题 求思路

  [复制链接]
跳转到指定楼层
楼主
我现在会中断扫描处理按键,短按一下LED亮,短按一下再灭,我现在想长按一下LED亮,长按一下再灭,不知道如何下手,请问高手指点一下

1652.png (20.99 KB, 下载次数: 41)

1652.png
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:320306 发表于 2021-2-26 16:20 | 只看该作者
统计按下的时间应该可以,就是时间超过2S认为长按,才开灯!
回复

使用道具 举报

板凳
ID:213173 发表于 2021-2-26 16:50 | 只看该作者
//适用于STC8
#include <reg52.h>

sbit key=P3^0;
sbit LED=P3^3;
long count;//计数变量
bit  key_sign;//按键状态标志

void main()
{
        while(1)
        {
                if(!key)//长按大约0.6秒响应,增加count值就可增加延时
                {
                        if(++count>=100000 && key_sign==0)
                        {
                                key_sign=1;//记忆按键状态
                                LED=~LED;//LED取反
                        }
                }
                else//松手
                {
                        count=0;//计数变量清0
                        key_sign=0;//按键状态复位
                }
        }
}

评分

参与人数 1黑币 +15 收起 理由
liuhailan5757 + 15 绝世好帖!

查看全部评分

回复

使用道具 举报

地板
ID:827243 发表于 2021-2-26 17:00 | 只看该作者
定时中断采样键盘,键盘按下就计数+1,若判断键盘松开,读取键盘按下的计数,根据大小判断长短按。
回复

使用道具 举报

5#
ID:473159 发表于 2021-2-26 20:48 | 只看该作者
坛子里有详细讲解的代码,上面找找看看,很容易
回复

使用道具 举报

6#
ID:823677 发表于 2021-2-26 20:55 | 只看该作者
wulin 发表于 2021-2-26 16:50
//适用于STC8
#include

谢谢,我就是苦恼在了计数怎么计的问题
回复

使用道具 举报

7#
ID:548551 发表于 2021-2-27 09:07 | 只看该作者
非STC得芯片?
回复

使用道具 举报

8#
ID:818410 发表于 2021-2-27 16:06 | 只看该作者
P3.0读到0后f计数,
P3.0变成1后看f的值,
若f大于某一树,则认为是长按,否则判定位短按或未按。
回复

使用道具 举报

9#
ID:885009 发表于 2021-2-28 01:01 | 只看该作者
用定时器计数呗,
或者每过一小段时间读一次进行采样,按照采样次数来确定是否长按
回复

使用道具 举报

10#
ID:491577 发表于 2021-2-28 10:25 | 只看该作者
这是基本功,你不是会中断扫描处理按键了吗,定时器的中断时间是很准确的,比如你的定时器中断时间是10ms,在中断中加一句:time++;这个time就是10ms计时,第一次按键变1后,将time=0;等按键再一次变0后,time*10ms就是按键按下的准确时间。
回复

使用道具 举报

11#
ID:387856 发表于 2021-3-6 13:51 | 只看该作者
wulin 发表于 2021-2-26 16:50
//适用于STC8
#include

终于看到高手了,这才是真确的按键处理思路。不像有些菜鸟,按键处理程序里面有delay();
回复

使用道具 举报

12#
ID:716656 发表于 2021-3-6 15:00 | 只看该作者
  1. #include <reg51.h>

  2. sbit key = P3^0;
  3. sbit led1 = P2^0;
  4. sbit led2 = P2^1;
  5. sbit led3 = P2^2;

  6. unsigned char x = 0;

  7. void init(void); //初始化定时器0
  8. void delay(unsigned int a); //延时
  9. void key_main(void); //按键事件判断

  10. void main()
  11. {
  12.                 init();
  13.                 key_main();
  14. }

  15. void init(void) //初始化定时器0
  16. {
  17.                 TMOD = 0x01;
  18. //                IT0 = 1;      //低电平有效
  19.                 TH0 = (65536-50000)/256;
  20.                 TL0 = (65536-50000)%256;
  21.                 EA = 1;
  22.                 ET0 = 1;             //允许定时器t0中断
  23. //                EX0 = 1;
  24.                 key = 1;
  25.                 P2 = 0x00;
  26. }

  27. void key_main(void) //按键事件判断
  28. {
  29.                 while(1)
  30.                 {
  31.                                 new:if(key == 0)
  32.                                 {
  33.                                                 delay(10);
  34.                                                 if(key == 0)
  35.                                                 {
  36.                                                                 TR0 = 1;
  37.                                                                 while(key == 0);       //第一次按键释放
  38.                                                                 TR0 = 0;
  39.                                                           
  40.                                                                 if(x>16)        //判断是否为长按
  41.                                                                 {
  42.                                                                                 x = 0;
  43.                                                                                 led3 = 1;

  44.                                                                                 goto new;
  45.                                                                 }
  46.                                                                
  47.                                                                 x = 0;
  48.                                                                 TR0 = 1;

  49.                                                                 while(x<=6) //在第一次按键事件完成后,若0.5秒内无按键事件,则为单击,否则是双击
  50.                                                                 {
  51.                                                                                 if(key == 0)
  52.                                                                                 {
  53.                                                                                                 delay(10);
  54.                                                                                                        
  55.                                                                                                 if(key == 0)
  56.                                                                                                 {
  57.                                                                                                                         TR0 = 0;
  58.                                                                                                                         x = 0;
  59.                                                                                                                         while(key == 0);
  60.                                                                                                                         led2 = 1;

  61.                                                                                                                         goto new;
  62.                                                                                                 }
  63.                                                                                         }
  64.                                                                 }
  65.                                                                
  66.                                                                 TR0 = 0;

  67.                                                                 if(x != 0)
  68.                                                                 {
  69.                                                                                 x = 0;
  70.                                                                                 led1 = 1;

  71.                                                                                 goto new;
  72.                                                                 }
  73.                                                 }
  74.                                 }
  75.                 }
  76. }


  77. void delay(unsigned int a) //延时
  78. {
  79.                 unsigned int i;
  80.                 for(a;a>0;a--)
  81.                 for(i=110;i>0;i--);
  82. }

  83. void time0(void) interrupt 1 //定时器0
  84. {
  85. //                ET0 = 0;
  86.                 {
  87.                                 TH0 = (65536-50000)/256;
  88.                                 TL0 = (65536-50000)%256;
  89.                                 x += 1;
  90.                 }
  91. //                ET0 = 1;
  92. }

  93. //void over(void) interrupt 0 //外部中断           触发后亮的指示灯灭
  94. //{
  95. //                ET0 = 0;
  96. //                {
  97. //                                if(led1 == 1)
  98. //                                led1 = 0;
  99. //                                if(led2 == 1)
  100. //                                led2 = 0;
  101. //                                if(led3 == 1)
  102. //                                led3 = 0;
  103. //                }
  104. //                ET0 = 1;
  105. //}
复制代码
单击,双击,长按,是一类一起学习吧
回复

使用道具 举报

13#
ID:340765 发表于 2021-3-6 16:40 | 只看该作者
我的思路是这样的,判断按键按下在while循环自加一个变量,松开后用if判断自加变量是否大于你定的时间变量,大于LED取反,自加变量置0.
回复

使用道具 举报

14#
ID:47286 发表于 2021-3-6 17:05 | 只看该作者
旁观者 发表于 2021-3-6 16:40
我的思路是这样的,判断按键按下在while循环自加一个变量,松开后用if判断自加变量是否大于你定的时间变量 ...

必须加计数器 而且要设定计数器的时长或者间隔 不然以单片机的速度 瞬间你这个变量就溢出了 然后重新计数 最后得到值未知 即 不一定是你需要的值

假设你定义个int变量 那么最大范围是65535 如果不加计数器 int变量从0到65535也就是毫秒级别 等你松手的时候int的值可能是0~65535之间任意一个数值

简单的流程应该是这样

用计数器设定一个20~50ms计数器 即每一次中断是20~50ms
然后设置一个变量 变量=计时器中断次数 即 每20~50ms这个变量被+一次
按下按键后防抖 确认按下时 清零变量
松开按键后防抖 确认松开时 检察变量的值
如果变量>阀值=长按 否则是短按
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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