单片机键盘怎样去抖动c语言程序?

#include
#define uint unsigned int
#define uchar unsigned char
sbit d1=P1^0;
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};
uchar num;
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void main()
{
wela=1;
P0=0xfe;
wela=0;
P3=0xff;
while(1)
{
if(key1==0)
{
delay(5);
if(key1==0)
{
d1=0;
num++;
if(num==10)
num=0;
}
while(!key1);
delay(5);
while(!key1);
}
else
d1=1;
dula=1;
P0=table[num];
dula=0;
}
}

以上是郭老师的程序。我总觉得有点问题,就是那些delay(), while(!key)的,看似有道理,但仔细一推敲觉得很多漏洞啊!是否需要改进这个程序,以及去抖动到底应该用什么思想呢?

使用这个到板子里面:

    #include <reg52.h>

    sbit ADDR0 = P1^0;

    sbit ADDR1 = P1^1;

    sbit ADDR2 = P1^2;

    sbit ADDR3 = P1^3;

    sbit ENLED = P1^4;

    sbit KEY1 = P2^4;

    sbit KEY2 = P2^5;

    sbit KEY3 = P2^6;

    sbit KEY4 = P2^7;

    unsigned char code LedChar[] = { //数码管显示字符转换表0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E};

    void delay();

    void main(){

    bit keybuf = 1; //按键值暂存,临时保存按键的扫描值

    bit backup = 1; //按键值备份,保存前一次的扫描值

    unsigned char cnt = 0; //按键计数,记录按键按下的次数

    ENLED = 0;  //选择数码管 DS1 进行显示

    ADDR3 = 1;

    ADDR2 = 0;

    ADDR1 = 0;

    ADDR0 = 0;

    P2 = 0xF7;  //P2.3 置 0,即 KeyOut1 输出低电平

    P0 = LedChar[cnt];  //显示按键次数初值

    while (1){

    keybuf = KEY4;  //把当前扫描值暂存

    if (keybuf != backup){  //当前值与前次值不相等说明此时按键有动作

    delay();  //延时大约 10ms

    if (keybuf == KEY4){  //判断扫描值有没有发生改变,即按键抖动

    if (backup == 0){  //如果前次值为 0,则说明当前是弹起动作

    cnt++;  //按键次数+1

    //只用 1 个数码管显示,所以加到 10 就清零重新开始

    if (cnt >= 10){

    cnt = 0;

    }

    P0 = LedChar[cnt]; //计数值显示到数码管上

    }

    backup = keybuf; //更新备份为当前值,以备进行下次比较
    }
    }
    }
    }

    /* 软件延时函数,延时约 10ms */

    void delay(){

    unsigned int i = 1000;

    while (i--);
    }

温馨提示:内容为网友见解,仅供参考
无其他回答

单片机键盘消抖,用延时消抖,汇编语言
DELAY(延时程序) ;延时消抖 JB START,RESTART;再次检测(检测位置在稳定阶段)……第一次检测有可能会检测到抖动的波峰“尖点”处,信号为1,此时第一条语句会原地踏步,不往下执行,直到检测到波谷“地点”处,信号为0,才开始执行第二条语句,调用延时子程序,延时子程序会持续一段时间(当然这...

请教,51单片机C语言,按键防抖
if(0==sw1)delay(100);\/\/很短的延时,防抖 if(0==sw1){ ...;} while(!sw) 的意思是松开按键才有效,就是松开按键才会执行下一条语句,不能起到防抖作用

51单片机怎么用c语言写一个按钮控制一个led的闪烁,按一下开始闪烁,再按...
void delay(unsigned int i){自己根据单片机频率写个1MS带形参的演示程序} 这个程序是现写的。。应该能执行,有些细节没有写,自己修改下,只是个大框而已(比如函数声明,定义端口什么的)

单片机C语言代码问题 这个按键消抖是如何实现的?
因为按键动作接触的时间比起芯片处理所需的时间周期多得去,而其他因素引起的抖动却没有这种特性,所以往往用多次重复或保持较长时间周期来确定是抖动还是按键动作;按键动作可能保持会有成千上万个周期。

c语言按键抖动问题
先要把按键的端口设置为输入,如果没有的话,默认引脚都会是高电平,所以你说检测松开能检测到,其实是端口一直是高电平。只能帮你这么多,我没用过你这款单片机,猜一下是128不?另外按键去抖动用普通的delay函数就可以,何必搞中断,中断本来就是件麻烦事,对程序运行效果影响很大。

在做单片机按键控制流水灯,我想达到按一下自己循环,再按一下就停止的...
Delayms(10); \/\/按键去抖动 if(K1==0) s=0; \/\/按键按下此时是键值s=0 } while(s==0) \/\/当按键第一次按下时进入循环点亮灯的循环 { temp=0x01; for(i=0;i<8;i++) { P0=~

求解释单片机键盘扫描的一段程序(关键是松手那块不明白)
SPK=1; \/\/按键有松开,停止蜂鸣器响 return; } 主要作用就是防止其他干扰信号误判成按键信号。另一个就是假如你长按不放的话就要使它在那等待你放开才会执行程序,所以这在你这的程序就是 if(l_keyold==key){ \/\/检测按键放开否,如果一样表明没放开,return;} 其实这个return可以不要,直接...

求一单片机c语言程序:两个按键控制两个led,按键按住不放led闪烁,松手...
一个按键时程序如下:while(1){ if(key==0)\/\/按键按下 { delayms(20);\/\/延时消抖 if(key==0)\/\/再次判断按键是否按下 { while(key==0)\/\/按键没有抬起 { led=!led; delayms(200);}\/\/LED闪烁 } } else led=0;}

在51单片机中用c语言keil写程序实现用一个按键控制8个灯的亮和灭(按...
sbit key = P1^0;\/\/按键 void delay(unsigned int time){ unsigned int i,j;for(i=0; i<time; i++)for(j=0; j<1000; j++){;} } void mian(){ unsigned int temp =0x00;while(1){ if(key == 0){ delay(20);\/\/适当延时,消除按键抖动,自己看实际情况修改时间 if(key ==...

用单片机C语言怎么写用状态机实现按键控制LED灯闪烁这个程序
sbit key=P1^2;sbit p1_6=P1^6;void delay(uchar delay_time){ uchar n;uint m;for (n=0;n<delay_time;n++){ for(m=0;m<10000;m++);} } void keyscan(){ if(key==0){ delay(5);if(key==0)while(!key){ p1_6 = 0;delay(20);p1_6 = 1;delay(20);} } } void ...

相似回答