acercqu 发表于 2012-4-2 10:32:22

按键单双击流水灯

一个按单击一个灯流水,双击两个灯流水,三击三个灯流水。而且任何时候,单击,双击,三击 都能够切换到相应的流水模式。

acercqu 发表于 2012-4-2 10:38:08

这是我写的程序,大家看看问题在哪里
#include"reg51.h"
sbit s17=P3^2;   //按键
#define uintunsigned 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={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};
         for(k=0;k<8;k++)
             {
             P1=nu;
             delay(1500);
         }
}
void two()
{      
      uchar code num={0x3f,0x9f,0xcf,0xe7,0xf3,0xf9,0xfc};
      for(k=0;k<7;k++)
           {
            P1=num;
            delay(1500);
      }
       
       
          

}

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

acercqu 发表于 2012-4-2 10:41:12

{:loveliness:}

acercqu 发表于 2012-4-2 12:38:34

做出这,就提升一个按键境界

.titrwh 发表于 2012-4-2 13:21:59

没有松手检测,按下按键时c++不知道执行了多少次,早就乱了。                                             

acercqu 发表于 2012-4-3 09:18:58

本帖最后由 acercqu 于 2012-4-3 09:35 编辑

怎么加入松手检测?


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

w514640 发表于 2012-4-3 09:51:30

来个延时就可以了吧

acercqu 发表于 2012-4-3 09:58:13

上面加了延时

ShawnLinson 发表于 2012-4-3 10:00:31

按键中断检测,主程序切换流水灯模式,这样按键想要检测一长几短都可以的啊

acercqu 发表于 2012-4-3 10:07:11

怎么个按键中断检测法? 能否给个例子,模仿一下。

dadajujing 发表于 2012-4-4 10:48:08

acercqu 发表于 2012-4-2 10:38 static/image/common/back.gif
这是我写的程序,大家看看问题在哪里
#include"reg51.h"
sbit s17=P3^2;   //按键


莫有中断~

renwocai 发表于 2012-4-5 09:09:10

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

xyz2008 发表于 2012-4-5 09:13:26

{:biggrin:}{:biggrin:}

w843387990 发表于 2012-4-5 09:54:14

{:loveliness:}

acercqu 发表于 2012-4-6 14:49:00

renwocai 发表于 2012-4-5 09:09 static/image/common/back.gif
不用任何中断,给个思路,用10MS左右的延时,时间到了就检测按键,然后判断执行结果,同样的要求我写过长短 ...

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

acercqu 发表于 2012-4-6 14:49:58

dadajujing 发表于 2012-4-4 10:48 static/image/common/back.gif
莫有中断~

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

a312835782 发表于 2012-4-6 15:34:25

论坛里好像有过,可以搜索下

ShawnLinson 发表于 2012-4-7 00:25:11

acercqu 发表于 2012-4-3 10:07 static/image/common/back.gif
怎么个按键中断检测法? 能否给个例子,模仿一下。

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

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次
               }
            }
      }
    }
}

ShawnLinson 发表于 2012-4-7 00:25:43

STM32 模板

ShawnLinson 发表于 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))

ShawnLinson 发表于 2012-4-7 00:29:46


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

qtds67 发表于 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;
}

leexiaowei 发表于 2012-4-7 17:56:55

消抖~~~这么做得好。

longwu537 发表于 2012-4-7 20:21:17

觉得楼主应该看看单击、双击、三击的定义……你这个只能记录按键次数……

acercqu 发表于 2012-4-8 23:09:00

longwu537 发表于 2012-4-7 20:21 static/image/common/back.gif
觉得楼主应该看看单击、双击、三击的定义……你这个只能记录按键次数…… ...

你 能再阐述一下吗?

acercqu 发表于 2012-4-8 23:10:13

ShawnLinson 发表于 2012-4-7 00:25 static/image/common/back.gif
参考自坛子其他网友的大作

void EXTI15_10_IRQHandler(void)


我要理解一下。 谢谢!

liushiming82 发表于 2012-4-9 15:14:57

{:victory:}{:victory:}{:victory:}{:victory:}

acercqu 发表于 2012-4-17 10:12:42

没有好的答案。

wapmo 发表于 2012-4-17 13:01:59

学习{:smile:}{:smile:}
页: [1]
查看完整版本: 按键单双击流水灯