欢迎来到泰骏兴电子,大家有问题可以直接联系管理员QQ:233619809单片机 QQ群:59194556 各位游客也可以注册玩玩,享受更多权益。温馨提示:本网站仅提供平台学习以及渠道,一切后果自行承担,还望广大用户提高自我意识,请不要轻易相信他人,请不要轻易相信他人,请不要轻易相信他人。为了更好的管理论坛工作,所以现在使用邮箱注册,如果以前的邮箱不能修改的,请联系管理员代为修改

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 215|回复: 0

一个拒绝死等的按键程序,支持短按,长按,多个按键同时按下

[复制链接]
发表于 2024-1-29 11:03:42 | 显示全部楼层 |阅读模式
通常我们在写按键程序的时候例如下面的例子:

  1.    while(1)
  2.         {
  3.                         if(KEY1==0)
  4.                 {
  5.                         while(KEY1==0);//等待按键松开
  6.                         ............
  7.                 }
  8.                         LED_1=~LED_1;
  9.         }
复制代码
都是这样进行识别按键的,但是这样的程序就会出现一个问题,就是按键在按下的时候程序会死在while(KEY1==0);//等待按键松开程序中,这样的话就造成一个问题,程序的执行效率很低很低
有什么什么方法可以解决一下呢?
当然是有的,例如下面就给出了一个解决方法
同样的,我也来做一个LED灯闪烁的程序和上面一样例如
  1.    while(1)
  2.         {
  3.                         KEY_Scan();//按键扫描程序
  4.                         for(q=0;q<KEY_number;q++)
  5.                 {
  6.                         KEY=Get_KEY_state(q);//获取按键状态
  7.                         if(KEY==Press)
  8.                         {
  9.                         printf("按键短按:%d\r\n",q);
  10.                         }
  11.                         
  12.                         if(KEY==LongPress)
  13.                         {
  14.                         printf("按键长按:%d\r\n",q);
  15.                         }
  16.                 }        
  17.                         delay_ms(20);
  18.                         if(w++>=10)
  19.                 {
  20.                         w=0;
  21.                         LED_1=~LED_1;
  22.                 }
  23.         }
复制代码
KEY_Scan();按键扫描程序,这个程序我们测试就放在这个循环程序里,当然到时候可以做一个20ms的定时器,把这个程序放入定时器中就可以了

KEY=Get_KEY_state(q);//获取按键状态    通过这个程序可以获取按键是否被按下

Press   :按键被短按了一下

LongPress    :按键被长按了一下



接下来是我们的按键扫描程序



#define KEY_number                                10                        //按键个数
#define KEY_PressDown_state                0                        //按键按下状态
#define KEY_LongPress_Time                100                //超过时间判断为长按 ,按键按下的实际时间计算为=按键扫描周期时间     X    KEY_LongPress_Time


u16 KEY_Time[KEY_number];//保存按键时间
bool KEY_Pin_state[KEY_number];//保存按键状态




typedef enum//定义按键的状态
{
                        Release=0,        //释放,也就是没有按键按下
                        Press=1,               //正常按下
                        LongPress=2,                //长按
                        NoRelease=3,                //按键按下但是还没有被释放
                        
}_KEY_state;


  1. //请将这个程序放入定时器或者是一个单独的任务中调用时间一般为20ms
  2. void KEY_Scan()
  3. {
  4.                         u8 q;
  5.                         for(q=0;q<KEY_number;q++)
  6.         {
  7.                         KEY_Pin_state[q]=GPIO_ReadInputDataBit(KEY_GPIOX[q],KEY_GPIO_Pin[q]);//获取按键状态
  8.                         if(KEY_Pin_state[q]==KEY_PressDown_state)
  9.                 {
  10.                         if(KEY_Time[q]<=60000){KEY_Time[q]++;}//计时
  11.                 }
  12.                         else
  13.                 {
  14.                         KEY_Time[q]=0;//如果按键被释放了则就清空计时
  15.                 }
  16.                         
  17.         }
  18. }
复制代码


下面是按键的识别程序
  1. //获取的按键状态
  2. //key_id:按键的ID号,请与前面定义的端口对应
  3. _KEY_state Get_KEY_state(u8 key_id)//获取按键状态
  4. {
  5.                         static _KEY_state mode[KEY_number];
  6.                         static bool state[KEY_number];
  7.                         if(KEY_Pin_state[key_id]==KEY_PressDown_state)
  8.         {
  9.                         state[key_id]=1;
  10.                         if(KEY_Time[key_id]<KEY_LongPress_Time){mode[key_id]=Press;}
  11.                         else{mode[key_id]=LongPress;}        
  12. //                        printf("按键被按下了:%d-%d\r\n",key_id,mode[key_id]);
  13.         }
  14.                         else
  15.         {
  16.                         if(state[key_id]==1)
  17.                 {
  18.                         state[key_id]=0;
  19. //                        printf("按键被按下过:%d\r\n",mode);
  20.                         return mode[key_id];
  21.                 }
  22.                         else
  23.                 {
  24.                         return Release;
  25.                 }
  26.         }
  27. //                        printf("按键处理为还未释放\r\n");
  28.                         return NoRelease;
  29. }

复制代码
通过上面改良的按键设备程序就可以实现按键的:短按,长按并且是拒绝死等的。同时可以支持多个按键按下,在这个程序中就支持了10个按键






本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
高级模式
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|泰骏兴电子科技有限公司 ( 粤ICP备2023060260号-1 ) 单片机爱好者

GMT+8, 2025-10-31 17:19

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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