找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 24696|回复: 38
收起左侧

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

  [复制链接]
ID:72251 发表于 2016-3-8 11:53 | 显示全部楼层 |阅读模式
自己整理的单按键程序,请大家指正,附件里有详细的注释

Pro.rar

1.83 KB, 下载次数: 587, 下载积分: 黑币 -5

评分

参与人数 1黑币 +100 收起 理由
admin + 100 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:1 发表于 2016-3-10 18:06 | 显示全部楼层
下面是楼主的程序 :
  1. #include "keyboard.h"

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

  9. static unsigned char key_driver(void)
  10. {
  11.         static unsigned char key_state_buffer1 = key_state_0;
  12.         static unsigned char key_timer_cnt1 = 0;
  13.         unsigned char key_return = key_no;
  14.         unsigned char key;
  15.         
  16.         key = key_input;  //read the I/O states
  17.         
  18.         switch(key_state_buffer1)
  19.         {
  20.                 case key_state_0:
  21.                         if(key == 0)
  22.                                 key_state_buffer1 = key_state_1;
  23.                                 //按键被按下,状态转换到按键消抖和确认状态//
  24.                         break;
  25.                 case key_state_1:
  26.                         if(key == 0)
  27.                         {
  28.                                 key_timer_cnt1 = 0;
  29.                                 key_state_buffer1 = key_state_2;
  30.                                 //按键仍然处于按下状态
  31.                                 //消抖完成,key_timer开始准备计时
  32.                                 //状态切换到按下时间计时状态
  33.                         }
  34.                         else
  35.                                 key_state_buffer1 = key_state_0;
  36.                                 //按键已经抬起,回到按键初始状态
  37.                         break;  //完成软件消抖
  38.                 case key_state_2:
  39.                         if(key == 1)
  40.                         {
  41.                                 key_return = key_click;  //按键抬起,产生一次click操作
  42.                                 key_state_buffer1 = key_state_0;  //转换到按键初始状态
  43.                         }
  44.                         else if(++key_timer_cnt1 >= 100)  //按键继续按下,计时超过1000ms
  45.                         {
  46.                                 key_return = key_long;  //送回长按事件
  47.                                 key_state_buffer1 = key_state_3;  //转换到等待按键释放状态
  48.                         }
  49.                         break;
  50.                 case key_state_3:  //等待按键释放
  51.                         if(key == 1)  //按键释放
  52.                                 key_state_buffer1 = key_state_0;  //切回按键初始状态
  53.                         break;
  54.         }
  55.         return key_return;
  56. }

  57. /***************************************************************************
  58. 函数功能:中层按键处理函数,调用底层函数一次,处理双击事件的判断,
  59.                                         返回上层正确的无键、单击、双击、长按四种状态
  60. 本函数由上层循环调用,间隔10ms
  61. ***************************************************************************/
  62. unsigned char key_read(void)
  63. {
  64.         static unsigned char key_state_buffer2 = key_state_0;
  65.         static unsigned char key_timer_cnt2 = 0;
  66.         unsigned char key_return = key_no;
  67.         unsigned char key;
  68.         
  69.         key = key_driver();
  70.         
  71.         switch(key_state_buffer2)
  72.         {
  73.                 case key_state_0:
  74.                         if(key == key_click)
  75.                         {
  76.                                 key_timer_cnt2 = 0;  //第一次单击,不返回,到下个状态判断是否会出现双击
  77.                                 key_state_buffer2 = key_state_1;
  78.                         }
  79.                         else
  80.                                 key_return = key;  //对于无键、长按,返回原事件
  81.                         break;
  82.                 case key_state_1:
  83.                         if(key == key_click)  //又一次单击,时间间隔小于500ms
  84.                         {
  85.                                 key_return = key_double;  //返回双击事件,回到初始状态
  86.                                 key_state_buffer2 = key_state_0;
  87.                         }
  88.                         else if(++key_timer_cnt2 >= 50)
  89.                         {
  90.                                 //这里500ms内肯定读到的都是无键事件,因为长按大于1000ms
  91.                                 //在1s前底层返回的都是无键
  92.                                                                         
  93.                                 key_return = key_click;  //500ms内没有再次出现单击事件,返回单击事件
  94.                                 key_state_buffer2 = key_state_0;  //返回初始状态
  95.                                        
  96.                         }
  97.                         break;
  98.         }
  99.         
  100.         return key_return;
  101. }
复制代码
回复

使用道具 举报

ID:79544 发表于 2016-3-11 15:32 | 显示全部楼层
看不懂,不过值得学习!谢谢分享
回复

使用道具 举报

ID:230409 发表于 2017-9-1 14:44 | 显示全部楼层
看不懂,不过值得学习!谢谢分享
回复

使用道具 举报

ID:248640 发表于 2017-11-12 16:36 | 显示全部楼层
admin 发表于 2016-3-10 18:06
下面是楼主的程序 给大家省点黑币:

这个仿真怎么做
回复

使用道具 举报

ID:161033 发表于 2017-11-22 22:20 | 显示全部楼层
感谢分享。。。
回复

使用道具 举报

ID:139783 发表于 2017-11-28 01:54 | 显示全部楼层
刚在学习51,还看不太懂,谢谢你们
回复

使用道具 举报

ID:253624 发表于 2017-11-28 16:04 | 显示全部楼层
Timer0_init()函数和key_init()函数怎么不写?
回复

使用道具 举报

ID:88606 发表于 2017-11-29 06:57 | 显示全部楼层
看看编程思路,学习下!
回复

使用道具 举报

ID:265153 发表于 2017-12-22 09:35 | 显示全部楼层
值得学习,很有帮助啊,谢谢楼主
回复

使用道具 举报

ID:223308 发表于 2018-1-2 00:41 | 显示全部楼层
下载来看看是什么
回复

使用道具 举报

ID:274077 发表于 2018-1-10 00:36 | 显示全部楼层
学习一个
回复

使用道具 举报

ID:283239 发表于 2018-2-9 09:11 | 显示全部楼层
学习一个
回复

使用道具 举报

ID:272080 发表于 2018-2-9 13:32 | 显示全部楼层
非常感谢管理员 又省了一笔黑币   我非常崇拜管理员  你绝对是一个很牛逼的人
回复

使用道具 举报

ID:66287 发表于 2018-2-9 16:53 | 显示全部楼层
好贴!状态机方式处理键盘,非常稳定的!
回复

使用道具 举报

ID:86276 发表于 2018-3-14 09:38 | 显示全部楼层
好东西,谢谢
回复

使用道具 举报

ID:293645 发表于 2018-3-18 17:53 | 显示全部楼层
多谢分享,新人表示感谢
回复

使用道具 举报

ID:243748 发表于 2018-3-18 23:57 来自手机 | 显示全部楼层
谢谢分享
回复

使用道具 举报

ID:140183 发表于 2018-4-19 20:08 | 显示全部楼层
谢谢!!!!!!
回复

使用道具 举报

ID:67356 发表于 2018-4-20 06:35 来自手机 | 显示全部楼层
很不错,谢谢了
回复

使用道具 举报

ID:353559 发表于 2018-6-18 20:58 | 显示全部楼层
谢谢分享
回复

使用道具 举报

ID:326489 发表于 2018-6-23 16:52 | 显示全部楼层
下载了,很好!!!!
回复

使用道具 举报

ID:257260 发表于 2018-7-16 19:48 | 显示全部楼层
谢谢,真好需要这个!
回复

使用道具 举报

ID:269211 发表于 2018-7-17 16:25 | 显示全部楼层
这个头文件怎么在主程序调试?麻烦高手写一下主程序
回复

使用道具 举报

ID:431327 发表于 2018-11-29 08:56 | 显示全部楼层
很好,学习到了 。。。
回复

使用道具 举报

ID:66287 发表于 2018-11-30 09:55 | 显示全部楼层
程序写的非常好,而且楼主有个好习惯,注释很详细,棒!
回复

使用道具 举报

ID:475236 发表于 2019-4-14 00:05 | 显示全部楼层
唉,没有往下看就下了,不过还是谢谢了
回复

使用道具 举报

ID:343102 发表于 2019-4-14 11:31 | 显示全部楼层
谢谢楼主,谢谢管理员。
回复

使用道具 举报

ID:511752 发表于 2019-4-14 17:00 | 显示全部楼层
感谢分享
回复

使用道具 举报

ID:687831 发表于 2020-3-1 23:50 来自手机 | 显示全部楼层
最后判断应该是"小于"50吧
回复

使用道具 举报

ID:506075 发表于 2020-7-7 18:59 | 显示全部楼层
admin 发表于 2016-3-10 18:06
下面是楼主的程序 给大家省点黑币:

楼主的头像好生眼熟啊,好人一生平安
回复

使用道具 举报

ID:245820 发表于 2020-9-9 16:13 | 显示全部楼层
包含了一个特殊的头文件,难搞
回复

使用道具 举报

ID:251029 发表于 2021-12-4 15:47 | 显示全部楼层
看起来逻辑很细密,赞一个
回复

使用道具 举报

ID:143767 发表于 2021-12-4 16:52 | 显示全部楼层
编译通不过,提示:
Rebuild started: Project: 按键
Rebuild target 'Target 1'
compiling 按键.C...
按键.C(2): warning C318: can't open file 'keyboard.h'
按键.C(14): error C202: 'key_state_0': undefined identifier
按键.C(16): error C202: 'key_no': undefined identifier
按键.C(19): error C202: 'key_input': undefined identifier
按键.C(23): error C202: 'key_state_0': undefined identifier
按键.C(25): error C202: 'key_state_1': undefined identifier
按键.C(28): error C202: 'key_state_1': undefined identifier
按键.C(32): error C202: 'key_state_2': undefined identifier
按键.C(38): error C202: 'key_state_0': undefined identifier
按键.C(41): error C202: 'key_state_2': undefined identifier
按键.C(44): error C202: 'key_click': undefined identifier
按键.C(45): error C202: 'key_state_0': undefined identifier
按键.C(49): error C202: 'key_long': undefined identifier
按键.C(50): error C202: 'key_state_3': undefined identifier
按键.C(53): error C202: 'key_state_3': undefined identifier
按键.C(55): error C202: 'key_state_0': undefined identifier
按键.C(68): error C202: 'key_state_0': undefined identifier
按键.C(70): error C202: 'key_no': undefined identifier
按键.C(77): error C202: 'key_state_0': undefined identifier
按键.C(78): error C202: 'key_click': undefined identifier
按键.C(81): error C202: 'key_state_1': undefined identifier
按键.C(86): error C202: 'key_state_1': undefined identifier
按键.C(87): error C202: 'key_click': undefined identifier
按键.C(89): error C202: 'key_double': undefined identifier
按键.C(90): error C202: 'key_state_0': undefined identifier
按键.C(97): error C202: 'key_click': undefined identifier
按键.C(98): error C202: 'key_state_0': undefined identifier
Target not created.
Build Time Elapsed:  00:00:00
回复

使用道具 举报

ID:262 发表于 2021-12-4 17:47 | 显示全部楼层
dj3365191 发表于 2021-12-4 16:52
编译通不过,提示:
Rebuild started: Project: 按键
Rebuild target 'Target 1'

你没有把头文件放进去,当然会报错了,你看我帮你整理了一下 工程
51hei.png

c样本51hei.7z

13.86 KB, 下载次数: 35, 下载积分: 黑币 -5

回复

使用道具 举报

ID:143767 发表于 2021-12-5 10:16 | 显示全部楼层
heicad 发表于 2021-12-4 17:47
你没有把头文件放进去,当然会报错了,你看我帮你整理了一下 工程

谢谢指教
回复

使用道具 举报

ID:189875 发表于 2022-4-9 16:40 | 显示全部楼层
学习学习,编程思路很好。
回复

使用道具 举报

ID:933601 发表于 2022-5-19 19:03 | 显示全部楼层
编程思路很好。
回复

使用道具 举报

ID:1044755 发表于 2024-7-31 10:07 | 显示全部楼层
admin 发表于 2016-3-10 18:06
下面是楼主的程序 :

回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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