dingppp23 发表于 2010-4-12 19:00:15

谁能给我一郭天祥按键消抖的C程序

谁能给我一郭天祥按键消抖的C程序,会用汇编写,但不会用C

jrcsh 发表于 2010-4-13 17:14:51

原理是检查按下后用W来检查 按扭是否反转了

0712 发表于 2010-4-13 17:21:48

马老师的书里不是有一个很好的算法吗
用状态机

tear086 发表于 2010-4-13 18:26:06

原来郭先生是神呀。

chun 发表于 2010-4-13 18:56:10

经过大概10ms的延时就可以了

jrcsh 发表于 2010-4-13 19:37:26

回复【4楼】chun 春
经过大概10ms的延时就可以了
-----------------------------------------------------------------------

这是也是一种


他要的是按扭安下后 后放开才开始运行程序

wallyone 发表于 2010-4-13 21:14:23

就是先检测一下 按键是否按下 再过10ms在检测 是否按下

dingppp23 发表于 2010-4-13 21:19:19

原理我知道就是用C写的没有他的漂亮

mcu131368 发表于 2010-4-13 22:58:01

while(!s);
delay(5);//5ms就够了
   while(!s);

zqhdevelopment 发表于 2010-4-15 16:29:40

#include<reg51.h>
#include<intrins.h>
sbit buzz=P1^0;
unsigned char keyscan(void);
void main(void)
{
        keyscan();

}

unsigned char keyscan(void)
{
        unsigned char k;
        unsigned char c=0;
        P0=0xff;                                //关闭输出驱动场效应管
        buzz=1;                                        //关蜂鸣器
        if(P0!=0xff)                        //判断是否有键按下
        {
                k=P0;                                //读按键值
                _nop_();                        //延时这里的延时都是用nop()代替的使用者可以根据你的按键习惯来设置
                if(k==P0)                        //假如判断还有信号,再延时
                {
                        k=P0;                        //重新取值,作为下次判断的依据
                        _nop_();                //延时
                        if(k==P0)                //确认实在有按键信号,蜂鸣器蜂鸣,返回按键值
                        {
                                while(((c++)<200)&&(k==P0))
                                {
                                        _nop_();//延时//此延时是长按键的时间

                                }
                                if(c==200)
                                {
                                        switch(k)//不同按键的长短按功能选择
                                        {
                                                case 0x7f:break;
                                                case 0xbf:break;
                                                case 0xdf:break;
                                                case 0xef:break;
                                                case 0xfe:break;
                                                case 0xfd:break;
                                                case 0xfb:break;
                                                case 0xf7:break;
                                                default:k=0x00;break;

                                        }

                                }

                                buzz=0;        //有真正的按键时,蜂鸣器鸣器

                        }
                        else
                                k=0x00;

                }
                else
                        k=0x00;

        }
        else
                k=0x00;
        return k;

}

luyongganglyg 发表于 2010-5-15 22:15:43

受教

wodedell 发表于 2010-5-16 11:06:05

这是郭天祥矩阵检测的程序,里面有按键按下消抖和松手消抖!
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit dula=P2^6;
sbit wela=P2^7;
sbit key1=P3^4;
uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71,0};
uchar num,temp,num1;
void delay(uint z)
{
        uint x,y;
        for(x=z;x>0;x--)
                for(y=110;y>0;y--);
}
uchar keyscan();
void display(uchar aa);
void main()
{
        num=17;
        dula=1;
        P0=0;
        dula=0;
        wela=1;
        P0=0xc0;
        wela=0;
       
        while(1)
                {
                        display(keyscan());
                }
}
void display(uchar aa)
{
                        dula=1;
                        P0=table;
                        dula=0;               
}
uchar keyscan()
{
                        P3=0xfe;
                        temp=P3;
                        temp=temp&0xf0;
                        while(temp!=0xf0)
                                {
                                        delay(5);
                                        temp=P3;
                                        temp=temp&0xf0;
                                        while(temp!=0xf0)
                                        {
                                                temp=P3;
                                        switch(temp)
                                                {
                                                        case 0xee:num=1;
                                                                break;
                                                        case 0xde:num=2;
                                                                break;
                                                        case 0xbe:num=3;
                                                                break;
                                                        case 0x7e:num=4;
                                                                break;
                                                }
                                        while(temp!=0xf0)
                                                {
                                                        temp=P3;
                                                        temp=temp&0xf0;
                                                }
                                        }
                                }

                        P3=0xfd;
                        temp=P3;
                        temp=temp&0xf0;
                        while(temp!=0xf0)
                                {
                                        delay(5);
                                        temp=P3;
                                        temp=temp&0xf0;
                                        while(temp!=0xf0)
                                        {
                                                temp=P3;
                                        switch(temp)
                                                {
                                                        case 0xed:num=5;
                                                                break;
                                                        case 0xdd:num=6;
                                                                break;
                                                        case 0xbd:num=7;
                                                                break;
                                                        case 0x7d:num=8;
                                                                break;
                                                }
                                        while(temp!=0xf0)
                                                {
                                                        temp=P3;
                                                        temp=temp&0xf0;
                                                }
                                        }
                                }


                        P3=0xfb;
                        temp=P3;
                        temp=temp&0xf0;
                        while(temp!=0xf0)
                                {
                                        delay(5);
                                        temp=P3;
                                        temp=temp&0xf0;
                                        while(temp!=0xf0)
                                        {
                                                temp=P3;
                                        switch(temp)
                                                {
                                                        case 0xeb:num=9;
                                                                break;
                                                        case 0xdb:num=10;
                                                                break;
                                                        case 0xbb:num=11;
                                                                break;
                                                        case 0x7b:num=12;
                                                                break;
                                                }
                                        while(temp!=0xf0)
                                                {
                                                        temp=P3;
                                                        temp=temp&0xf0;
                                                }
                                        }
                                }


                        P3=0xf7;
                        temp=P3;
                        temp=temp&0xf0;
                        while(temp!=0xf0)
                                {
                                        delay(5);
                                        temp=P3;
                                        temp=temp&0xf0;
                                        while(temp!=0xf0)
                                        {
                                                temp=P3;
                                        switch(temp)
                                                {
                                                        case 0xe7:num=13;
                                                                break;
                                                        case 0xd7:num=14;
                                                                break;
                                                        case 0xb7:num=15;
                                                                break;
                                                        case 0x77:num=16;
                                                                break;
                                                }
                                        while(temp!=0xf0)
                                                {
                                                        temp=P3;
                                                        temp=temp&0xf0;
                                                }
                                        }
                                }
return num;

}

D.lovers 发表于 2010-5-16 12:18:08

推荐用状态机思想坐

zlulu2006 发表于 2010-5-20 08:28:36

状态机流程图~~

tonydh 发表于 2010-5-20 08:54:47

mark

yanxinboy 发表于 2010-9-2 10:30:45

这个记号下,有点用.

总看到人说状态机,可是一个用于51的例子还没有看到啊.

kkalizee 发表于 2010-11-21 16:34:00

void Check_Key(void)
{
    unsigned char row,col,tmp1,tmp2;
    tmp1 = 0x10;            //tmp1用来设置P1口的输出,取反后使P1.4~P1.7中有一个为0
    for(row=0;row<4;row++)   // 行检测
{
      P1 = 0x0f;            // 先将p1.4~P1.7置高
      P1 =~tmp1;            // 使P1.4~p1.7中有一个为0
      tmp1*=2;             // tmp1左移一位
      if ((P1 & 0x0f) < 0x0f)    // 检测P1.0~P1.3中是否有一位为0,只要有,则说明此行有键按下,进入列检测
{
   tmp2 = 0x01;   // tmp2用于检测出哪一列为0
   for(col =0;col<4;col++)   // 列检测
   {
    if((P1 & tmp2)==0x00)// 该列如果为低电平则可以判定为该列
    {
   key_val =key_Map[ row*4 +col ]; // 获取键值,识别按键;key_Map为按键的定义表
   return;   // 退出循环
    }
   tmp2*=2;      // tmp2左移一位
            }
      }
    }
}   //结束

觉着这个不错 短小精炼。

muzheyun 发表于 2010-11-21 20:05:34

mark

kongjie07 发表于 2010-11-30 12:40:28

记号。

yiyu 发表于 2010-11-30 13:30:00

#define TICK_MS 10
#define DEBOUNCE_DELAY   (20/TICK_MS)
#define DOUBLE_DELAY          ( 200/TICK_MS)
#define DOUBLE_INTERVAL   (333/TICK_MS)

char get_key(void)
{
   static char delay = 0;
   char chr;
   chr = keydown();          /*获取键值 ,无按键为0 */
if(chr)
{
       ++delay;
    if( delay == DEBOUNCE_DELAY )    /*经过去抖动延时 */
         return(chr);
    else if( delay == DOUBLE_DELAY + DOUBLE_INTERVAL )   /*   键持续按下一段时间 */
    {
         delay = DOUBLE_DELAY;
         return(chr);
    }
}
else
   delay = 0;
return 0;
}
未经测试,仅供参考

susuyu 发表于 2010-12-1 14:22:49

mark

mysignal 发表于 2010-12-1 16:50:18

mark

bluelool 发表于 2010-12-2 09:08:27

mark

wwwdege 发表于 2010-12-3 00:36:00

mark

moyanqd 发表于 2010-12-4 00:20:24

让cpu空等不是好的算法!应该杜绝delay这样的用法,放到定时器中断中出来比较好

rockgoogle 发表于 2010-12-4 00:29:17

标记收藏

qinhya 发表于 2010-12-4 09:17:58

mark

poet_lee 发表于 2010-12-5 23:36:26

mark~

hqjhr0912 发表于 2010-12-6 00:29:48

24楼说得对

ljmdzyx 发表于 2011-10-31 13:33:44

mark

mingyitao2052 发表于 2011-10-31 16:46:50

#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
void delay(uint xms)
{
uint i,j;
for(i=xms;i>0;i--)
    for(j=127;j>0;j--);
}
void display(uchar num)
{
P0=table;         
}
void matrixkeyscan()
{
uchar temp,key;
P3=0xfe;       //将第一行置于低电平
temp=P3;
temp=temp&0xf0;   
if(temp!=0xf0)
{
    delay(10);
    temp=P3;               
    temp=temp&0xf0;
    if(temp!=0xf0)
    {
      temp=P3;
      switch(temp)
      {
      case 0xee:key=0;break;   // 第1个按键
      case 0xde:key=1;break;   // 第2个按键
      case 0xbe:key=2;break;   // 第3个按键
      case 0x7e:key=3;break;   // 第4个按键                                                                              
      }                                                                                                                                            
      while(temp!=0xf0)                                                                                       
      {                                                                                                                      
      temp=P3;                                                                                                   
      temp=temp&0xf0;                                                                                                        
      }                                                                                                                      
      display(key);                                                                                           
    }                                                                                                              
}                                                                                                              
P3=0xfd;      //将第二行置于低电平                                                
temp=P3;                                                                                        
temp=temp&0xf0;                                                                         
if(temp!=0xf0)                                                                           
{
    delay(10);
    temp=P3;
    temp=temp&0xf0;                                                                                                      
    if(temp!=0xf0)
    {                                                                                                                             
      temp=P3;
      switch(temp)
      {
      case 0xed:key=4;break;//第5个按键                   
      case 0xdd:key=5;break;//第6个按键       
      case 0xbd:key=6;break;//第7个按键       
      case 0x7d:key=7;break;//第8个按键       
      }
      while(temp!=0xf0)
      {
      temp=P3;                                                                                           
      temp=temp&0xf0;                                             
      }
      display(key);
    }
}
   P3=0xfb;   //将第三行置低电平
temp=P3;
temp=temp&0xf0;   
if(temp!=0xf0)
{
    delay(10);
    temp=P3;               
    temp=temp&0xf0;
    if(temp!=0xf0)
    {
      temp=P3;
      switch(temp)
      {
      case 0xeb:key=8;break;   // 第9个按键
      case 0xdb:key=9;break;   // 第10个按键
      case 0xbb:key=10;break;// 第11个按键
      case 0x7b:key=11;break;// 第12个按键                                                                             
      }                                                                                                                                            
      while(temp!=0xf0)                                                                                       
      {                                                                                                                      
      temp=P3;                                                                                                   
      temp=temp&0xf0;                                                                                                        
      }                                                                                                                      
      display(key);                                                                                           
    }                                                                                                              
}
   P3=0xf7;   //将第四行置低电平
temp=P3;
temp=temp&0xf0;   
if(temp!=0xf0)
{
    delay(10);
    temp=P3;               
    temp=temp&0xf0;
    if(temp!=0xf0)
    {
      temp=P3;
      switch(temp)
      {
      case 0xe7:key=12;break;// 第13个按键
      case 0xd7:key=13;break;// 第14个按键
      case 0xb7:key=14;break;// 第15个按键
      case 0x77:key=15;break;// 第16个按键                                                                             
      }                                                                                                                                            
      while(temp!=0xf0)                                                                                       
      {                                                                                                                      
      temp=P3;                                                                                                   
      temp=temp&0xf0;                                                                                                        
      }                                                                                                                      
      display(key);                                                                                           
    }                                                                                                              
}                                                                                                 
}
void main()
{
P0=0x00;
P2=0xff;
P2=0x00;
while(1)
    matrixkeyscan();

}

qinyuming200 发表于 2011-11-1 22:47:42

学习了,

delta8921 发表于 2011-11-2 21:18:33

关键是delay10ms好浪费呀。

qun453176385 发表于 2011-11-9 23:23:34

回复【楼主位】dingppp23
-----------------------------------------------------------------------

就写一个延时20ms 的延时函数就OK了   

void delay(uint x)
{
uint i,j;
for(i=0;i<100;i++)
    for(j=0;j>x;j++);
}
没算了 这肯定不是20ms

Making 发表于 2013-7-20 15:10:51

mark。。。。。。。。。。。。。。。。

osesemi 发表于 2013-11-10 14:03:16

飘过,学习

小邢 发表于 2017-2-10 11:13:06

千万不要用郭天祥的这个思路。用delay的方式死等。而且要等按键释放,才能继续工作。万一按键坏了,一直短路,系统不就挂掉了。
用状态机做。

easier 发表于 2017-2-10 11:40:22

chun 发表于 2010-4-13 18:56
经过大概10ms的延时就可以了

10ms 的延時 一 简值大大浪費時間

gaowh 发表于 2017-2-10 14:48:50

状态机 状态机 状态机 重要的事情说三遍!!用延时的如果公司够正规 每个功能对应一个测试用例 你肯定过不了。

让爱随风 发表于 2017-2-10 15:28:05

不建议用延时等待的方法,对于实时性会有很大的影响,工程大了你就感觉到了

lxa0 发表于 2017-2-11 13:48:17

经典用法是调用显示子程序~~~~~~~~~~~~~~做消抖动延时

dexidz 发表于 2018-7-26 14:53:12

听郭天祥还想进步不?

68167253 发表于 2018-9-12 15:25:35

mark一下

dongwang_fl 发表于 2018-9-12 16:43:01

kkalizee 发表于 2010-11-21 16:34
void Check_Key(void)
{
    unsigned char row,col,tmp1,tmp2;


这个觉得比较好。

easier 发表于 2018-9-18 13:39:57

郭天祥那個程序,真是「神」一樣才可用
页: [1]
查看完整版本: 谁能给我一郭天祥按键消抖的C程序