搜索
bottom↓
回复: 28

按键单双击流水灯

[复制链接]

出0入0汤圆

发表于 2012-4-2 10:32:22 | 显示全部楼层 |阅读模式
一个按单击一个灯流水,双击两个灯流水,三击三个灯流水。而且任何时候,单击,双击,三击 都能够切换到相应的流水模式。

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

 楼主| 发表于 2012-4-2 10:38:08 | 显示全部楼层
这是我写的程序,大家看看问题在哪里
#include"reg51.h"
sbit s17=P3^2;   //按键
#define uint  unsigned int
#define uchar unsigned char
void one();
void two();
void three();
void delay(uint time);
uchar c;
uchar k,temp;   
void main()   
{
   uchar time;
  while(1)
  {
    if(s17==0)
   {
       
    delay(20);
    if(s17==0)
    {
        c++;
        }
        if(c==1)
        {time=0;}
    if(c==4)
    {c=0;}
    }

  if(++time>=150)
  {       

      switch(c)
      {
      case 1:
      one();
      break;
      case 2:
            two();
      break;
     case 3:
       three();
      break;
     default :
      break;
      }
}
   }
}



void delay(uint time)                                                                       
{
    uint i,j;
    for(i=0;i<time;i++)
    for(j=0;j<50;j++);
}


void one()
{
  
         uchar code nu[8]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};
         for(k=0;k<8;k++)
             {
             P1=nu[k];
             delay(1500);
         }
}
void two()
{      
        uchar code num[7]={0x3f,0x9f,0xcf,0xe7,0xf3,0xf9,0xfc};
        for(k=0;k<7;k++)
             {
            P1=num[k];
            delay(1500);
        }
         
         
          

}

void three()
{
        
         uchar code numm[6]={0x1f,0x8f,0xc7,0xe3,0xf1,0xf8};
         
         for(k=0;k<6;k++)
             {
             P1=numm[k];
             delay(1500);
         }
         
         
            
}

出0入0汤圆

 楼主| 发表于 2012-4-2 10:41:12 | 显示全部楼层

出0入0汤圆

 楼主| 发表于 2012-4-2 12:38:34 | 显示全部楼层
做出这,就提升一个按键境界

出0入0汤圆

发表于 2012-4-2 13:21:59 | 显示全部楼层
没有松手检测,按下按键时c++不知道执行了多少次,早就乱了。                                             

出0入0汤圆

 楼主| 发表于 2012-4-3 09:18:58 | 显示全部楼层
本帖最后由 acercqu 于 2012-4-3 09:35 编辑

怎么加入松手检测?


  加了松手检测就能解决问题吗?

出0入0汤圆

发表于 2012-4-3 09:51:30 | 显示全部楼层
来个延时就可以了吧

出0入0汤圆

 楼主| 发表于 2012-4-3 09:58:13 | 显示全部楼层
上面加了延时

出0入0汤圆

发表于 2012-4-3 10:00:31 | 显示全部楼层
按键中断检测,主程序切换流水灯模式,这样按键想要检测一长几短都可以的啊

出0入0汤圆

 楼主| 发表于 2012-4-3 10:07:11 | 显示全部楼层
怎么个按键中断检测法? 能否给个例子,模仿一下。

出0入0汤圆

发表于 2012-4-4 10:48:08 | 显示全部楼层
acercqu 发表于 2012-4-2 10:38
这是我写的程序,大家看看问题在哪里
#include"reg51.h"
sbit s17=P3^2;   //按键

莫有中断~

出0入0汤圆

发表于 2012-4-5 09:09:10 | 显示全部楼层
不用任何中断,给个思路,用10MS左右的延时,时间到了就检测按键,然后判断执行结果,同样的要求我写过长短按的,可以用状态机写,也可以不用,不用的话,用了大量的GOTO指令,你的要求,我明天有空写出来,另外,请给出单击,双击和三击的定义。

出0入0汤圆

发表于 2012-4-5 09:13:26 | 显示全部楼层

出0入0汤圆

发表于 2012-4-5 09:54:14 | 显示全部楼层

出0入0汤圆

 楼主| 发表于 2012-4-6 14:49:00 | 显示全部楼层
renwocai 发表于 2012-4-5 09:09
不用任何中断,给个思路,用10MS左右的延时,时间到了就检测按键,然后判断执行结果,同样的要求我写过长短 ...

你好!
这里的一个按键 单击 双击 三击 是在一定的时间内看按键几次,比如在两秒内 按了一次就是单击 ,按了两次就是双击,按了三次就是三击。

出0入0汤圆

 楼主| 发表于 2012-4-6 14:49:58 | 显示全部楼层
dadajujing 发表于 2012-4-4 10:48
莫有中断~

可以不用中断,只用延时来做吗?

出0入0汤圆

发表于 2012-4-6 15:34:25 来自手机 | 显示全部楼层
论坛里好像有过,可以搜索下

出0入0汤圆

发表于 2012-4-7 00:25:11 | 显示全部楼层
acercqu 发表于 2012-4-3 10:07
怎么个按键中断检测法? 能否给个例子,模仿一下。

参考自坛子其他网友的大作

void EXTI15_10_IRQHandler(void)
{
//  ___            _____          _______
//     |__________|     |________|
//       miMAX     mjMAX   mkMAX
    #define miMAX 300       //长按时限
    #define mjMAX 50        //弹起监测时限
    #define mkMAX 100       //是否第二次有长按

    u16 mi,mj,mk;


    if(EXTI_GetITStatus(EXTI_Line14) != RESET){          //检查指定的EXTI14线路触发请求发生与否
        msDelay(10);
        for(mi=0;mi<miMAX;mi++){
            msDelay(10);
            if(btnUp()) {   //放开
                break;
            }
        }
        if(mi == miMAX) {//长按
    //--------------------------------------------------------------------------以下是长按
            pcPrintf("长按!\r\n");
    //--------------------------------------------------------------------------以上是长按
            EXTI_ClearITPendingBit(EXTI_Line14);  //清除EXTI14线路挂起位
        } else {
            for(mj=0;mj<mjMAX;mj++){
                msDelay(10);
                if(btnPush()) {   //按下
                    break;
                }
            }
            if(mj == mjMAX) {//单击
    //--------------------------------------------------------------------------以下是单击
                pcPrintf("单击!\r\n");
    //--------------------------------------------------------------------------以上是长按
                EXTI_ClearITPendingBit(EXTI_Line14);  //清除EXTI14线路挂起位
            } else {
                for(mk=0;mk<mkMAX;mk++){
                    msDelay(10);
                    if(btnUp()) {   //放开
                        break;
                    }
                }
                if(mk == mkMAX) { //一短一长
    //--------------------------------------------------------------------------以下是双击_一短一长
                    pcPrintf("一短一长!\r\n");
    //--------------------------------------------------------------------------以上是双击_一短一长
                    EXTI_ClearITPendingBit(EXTI_Line14);  //清除EXTI14线路挂起位
                    EXTI_ClearITPendingBit(EXTI_Line14);  //清除EXTI14线路挂起位,双击需要清除2次
                } else {//二短(双击)
    //--------------------------------------------------------------------------以下是双击_二短
                    pcPrintf("双击!\r\n");
    //--------------------------------------------------------------------------以上是双击_二短
                    EXTI_ClearITPendingBit(EXTI_Line14);  //清除EXTI14线路挂起位
                    EXTI_ClearITPendingBit(EXTI_Line14);  //清除EXTI14线路挂起位,双击需要清除2次
               }
            }
        }
    }
}

出0入0汤圆

发表于 2012-4-7 00:25:43 | 显示全部楼层
STM32 模板

出0入0汤圆

发表于 2012-4-7 00:27:05 | 显示全部楼层
还有一段宏定义一并补上:

#define RCC_BTN             RCC_APB2Periph_GPIOB    //GPIO时钟
#define GPIO_BTN            GPIOB                   //GPIO组
#define PIN_BTN             GPIO_Pin_14                            //GPIO管脚
#define btnUp()             (SET   == GPIO_ReadInputDataBit(GPIO_BTN, PIN_BTN))
#define btnPush()           (RESET == GPIO_ReadInputDataBit(GPIO_BTN, PIN_BTN))

出0入0汤圆

发表于 2012-4-7 00:29:46 | 显示全部楼层

在原有代码的 中断检测中, 其实只要修改 pcPrintf函数 为 某一个全局变量
然后在main 函数中 检测 该全局变量 就开源不停地做各种不同的流水灯的效果了

出0入0汤圆

发表于 2012-4-7 17:16:41 | 显示全部楼层
坛里有3条语句的按键经典用法,LZ可以改编试试
unsigned char Tig;
unsigned char Cont;
void KeyRead(void)
{
      unsigned char ReadData = PINB^0xff;
      Trg = ReadData &(ReadData^Cont);
      Cont = ReadData;
}

出0入0汤圆

发表于 2012-4-7 17:56:55 | 显示全部楼层
消抖~~~这么做得好。

出0入0汤圆

发表于 2012-4-7 20:21:17 | 显示全部楼层
觉得楼主应该看看单击、双击、三击的定义……你这个只能记录按键次数……

出0入0汤圆

 楼主| 发表于 2012-4-8 23:09:00 | 显示全部楼层
longwu537 发表于 2012-4-7 20:21
觉得楼主应该看看单击、双击、三击的定义……你这个只能记录按键次数…… ...

你 能再阐述一下吗?

出0入0汤圆

 楼主| 发表于 2012-4-8 23:10:13 | 显示全部楼层
ShawnLinson 发表于 2012-4-7 00:25
参考自坛子其他网友的大作

void EXTI15_10_IRQHandler(void)

我要理解一下。 谢谢!

出0入0汤圆

发表于 2012-4-9 15:14:57 | 显示全部楼层

出0入0汤圆

 楼主| 发表于 2012-4-17 10:12:42 | 显示全部楼层
没有好的答案。

出0入0汤圆

发表于 2012-4-17 13:01:59 | 显示全部楼层
学习
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-19 21:48

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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