单片机论坛

 找回密码
 立即注册
QQ登录 只需一步,快速开始
搜索
查看: 2770|回复: 14
打印 上一主题 下一主题
收起左侧

51单片机实现单按键单击、双击、长按功能

  [复制链接]
跳转到指定楼层
楼主
defu_yin1512 发表于 2016-3-8 11:53 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
自己整理的单按键程序,请大家指正,附件里有详细的注释

Pro.rar 1.83 KB, 下载次数: 101, 下载积分: 黑币 -5

评分

参与人数 1黑币 +100 收起 理由
admin + 100 共享资料的黑币奖励!
查看全部评分
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏4 转播转播 分享分享 分享淘帖 顶 踩
回复 使用道具 举报
沙发
admin 发表于 2016-3-10 18:06 | 只看该作者
下面是楼主的程序 给大家省点黑币:
  • #include "keyboard.h"

  • /***************************************************************************
  • 程序功能:一个按键的单击、双击、长按。三种按键方式,然后做不同的处理。
  •                                         这里以P1口的LED变化作为测试
  •                                         单击:点亮P1口的第一个LED(低电平点亮)
  •                                         双击:点亮P1口的第二个LED(低电平点亮)
  •                                         长按:点亮P1口上的8个LED(低电平点亮)
  • ***************************************************************************/

  • static unsigned char key_driver(void)
  • {
  •         static unsigned char key_state_buffer1 = key_state_0;
  •         static unsigned char key_timer_cnt1 = 0;
  •         unsigned char key_return = key_no;
  •         unsigned char key;
  •         
  •         key = key_input;  //read the I/O states
  •         
  •         switch(key_state_buffer1)
  •         {
  •                 case key_state_0:
  •                         if(key == 0)
  •                                 key_state_buffer1 = key_state_1;
  •                                 //按键被按下,状态转换到按键消抖和确认状态//
  •                         break;
  •                 case key_state_1:
  •                         if(key == 0)
  •                         {
  •                                 key_timer_cnt1 = 0;
  •                                 key_state_buffer1 = key_state_2;
  •                                 //按键仍然处于按下状态
  •                                 //消抖完成,key_timer开始准备计时
  •                                 //状态切换到按下时间计时状态
  •                         }
  •                         else
  •                                 key_state_buffer1 = key_state_0;
  •                                 //按键已经抬起,回到按键初始状态
  •                         break;  //完成软件消抖
  •                 case key_state_2:
  •                         if(key == 1)
  •                         {
  •                                 key_return = key_click;  //按键抬起,产生一次click操作
  •                                 key_state_buffer1 = key_state_0;  //转换到按键初始状态
  •                         }
  •                         else if(++key_timer_cnt1 >= 100)  //按键继续按下,计时超过1000ms
  •                         {
  •                                 key_return = key_long;  //送回长按事件
  •                                 key_state_buffer1 = key_state_3;  //转换到等待按键释放状态
  •                         }
  •                         break;
  •                 case key_state_3:  //等待按键释放
  •                         if(key == 1)  //按键释放
  •                                 key_state_buffer1 = key_state_0;  //切回按键初始状态
  •                         break;
  •         }
  •         return key_return;
  • }

  • /***************************************************************************
  • 函数功能:中层按键处理函数,调用底层函数一次,处理双击事件的判断,
  •                                         返回上层正确的无键、单击、双击、长按四种状态
  • 本函数由上层循环调用,间隔10ms
  • ***************************************************************************/
  • unsigned char key_read(void)
  • {
  •         static unsigned char key_state_buffer2 = key_state_0;
  •         static unsigned char key_timer_cnt2 = 0;
  •         unsigned char key_return = key_no;
  •         unsigned char key;
  •         
  •         key = key_driver();
  •         
  •         switch(key_state_buffer2)
  •         {
  •                 case key_state_0:
  •                         if(key == key_click)
  •                         {
  •                                 key_timer_cnt2 = 0;  //第一次单击,不返回,到下个状态判断是否会出现双击
  •                                 key_state_buffer2 = key_state_1;
  •                         }
  •                         else
  •                                 key_return = key;  //对于无键、长按,返回原事件
  •                         break;
  •                 case key_state_1:
  •                         if(key == key_click)  //又一次单击,时间间隔小于500ms
  •                         {
  •                                 key_return = key_double;  //返回双击事件,回到初始状态
  •                                 key_state_buffer2 = key_state_0;
  •                         }
  •                         else if(++key_timer_cnt2 >= 50)
  •                         {
  •                                 //这里500ms内肯定读到的都是无键事件,因为长按大于1000ms
  •                                 //在1s前底层返回的都是无键
  •                                                                         
  •                                 key_return = key_click;  //500ms内没有再次出现单击事件,返回单击事件
  •                                 key_state_buffer2 = key_state_0;  //返回初始状态
  •                                        
  •                         }
  •                         break;
  •         }
  •         
  •         return key_return;
  • }
  • 复制代码
    回复 使用道具 举报
    板凳
    腾飞的龙 发表于 2016-3-11 15:32 | 只看该作者
    看不懂,不过值得学习!谢谢分享
    回复 使用道具 举报
    地板
    vincentmax3 发表于 2017-9-1 14:44 | 只看该作者
    看不懂,不过值得学习!谢谢分享
    回复 使用道具 举报
    5#
    AIvy 发表于 2017-11-12 16:36 | 只看该作者
    admin 发表于 2016-3-10 18:06
    下面是楼主的程序 给大家省点黑币:

    这个仿真怎么做
    回复 使用道具 举报
    6#
    xmch 发表于 2017-11-22 22:20 | 只看该作者
    感谢分享。。。
    回复 使用道具 举报
    7#
    panlongdian 发表于 2017-11-28 01:54 | 只看该作者
    刚在学习51,还看不太懂,谢谢你们
    回复 使用道具 举报
    8#
    roggie 发表于 2017-11-28 16:04 | 只看该作者
    Timer0_init()函数和key_init()函数怎么不写?
    回复 使用道具 举报
    9#
    tt98 发表于 2017-11-29 06:57 | 只看该作者
    看看编程思路,学习下!
    回复 使用道具 举报
    10#
    残念 发表于 2017-12-22 09:35 | 只看该作者
    值得学习,很有帮助啊,谢谢楼主
    回复 使用道具 举报
    11#
    abcd7471 发表于 2018-1-2 00:41 | 只看该作者
    下载来看看是什么
    回复 使用道具 举报
    12#
    万人无往 发表于 2018-1-10 00:36 | 只看该作者
    学习一个
    回复 使用道具 举报
    13#
    ronchi 发表于 2018-2-9 09:11 | 只看该作者
    学习一个
    回复 使用道具 举报
    14#
    大力做大力愛 发表于 2018-2-9 13:32 | 只看该作者
    非常感谢管理员 又省了一笔黑币   我非常崇拜管理员  你绝对是一个很牛逼的人
    回复 使用道具 举报
    15#
    bhjyqjs 发表于 2018-2-9 16:53 | 只看该作者
    好贴!状态机方式处理键盘,非常稳定的!
    回复 使用道具 举报
    您需要登录后才可以回帖 登录 | 立即注册
    本版积分规则
    QQ|手机版|小黑屋|单片机论坛
    Powered by 单片机教程网
    快速回复 返回顶部 返回列表