第八章 函数进阶和按键(1)

下面主要讲一下按键的原理:
1.独立键盘
![独立键盘原理](https://img-blog.csdn.net/20170814121905771?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaGhjaGVuY2hvbmc=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
对其来说,如果你检验KeyIn口为高电平,说明按键弹起,相反的,KeyIn口为低电平,则说明按键按下。
2.矩阵键盘
![矩阵键盘原理](https://img-blog.csdn.net/20170814121927939?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaGhjaGVuY2hvbmc=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
KeyOut1引脚输出高电平,其余KeyOut引脚输出低电平,这时候,我们按下Key1。检测4个KeyIn引脚时,只有KeyIn1引脚为低电平,其余为高电平,这时我们就可以检测是哪一个按键按下。
由于机械键盘的特性,我们需要对按键扫描的时候实行消抖处理。
这是一个不消抖的程序,目的是实现按键按一下,数字加1
#include <reg52.h>

sbit KeyS2=P3^4;
sbit KeyS3=P3^5;
sbit KeyS4=P3^6;
sbit KeyS5=P3^7;

sbit dula=P2^6;
sbit wela=P2^7;

unsigned char code LedChar[]={
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,};
unsigned char num=0;

void main()
{
    wela=1;
    P0=0xdf;
    wela=0;
    dula=1;
    P0=LedChar[num];
    dula=0;
    P3=0xff;
    while(1);
    {
        if(KeyS2==0)
        {
            num++;
            if(num>=10)
                num=0;
            dula=1;
            P0=LedChar[num];
            dula=0;
            while(!KeyS2);//此处用于检验用户是否放下按键      
        }
}
在下载到单片机的时候,我们会发现,有时你按一下,数码管跳动的数字并非一个,有时会有多个。我们在按下的时候,KeyIn引脚接收到的信号是这样的111111100101000000000010010111111,我们发现其实在高低电平转化的时候会有高低电平的跳动,这就是抖动。那么如何消抖呢?
我们有两种方式消抖
①延时函数
当我们判断KeyS2==0之后,延时10ms,再次判断KeyS2是否为0。消除按下时的抖动,当弹起时,会有10010111的抖动,当再次进入if(KeyS2==0)判断后,延时后,KeyS2=1;这时消除了弹开时的抖动。
程序如下:
#include <reg52.h>

sbit KeyS2=P3^4;
sbit KeyS3=P3^5;
sbit KeyS4=P3^6;
sbit KeyS5=P3^7;

sbit d1=P1^0;

sbit dula=P2^6;
sbit wela=P2^7;

unsigned char code LedChar[]={
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71
};
unsigned char num=0;

void delay();

void main()
{
    wela=1;
    P0=0xdf;
    wela=0;
    dula=1;
    P0=LedChar[num];
    dula=0;
    P3=0xff;
    while(1)
    {
        if(KeyS2==0)
        {
            delay();
            if(KeyS2==0)
            {
                num++;
                if(num>=10)
                    num=0;
                dula=1;
                P0=LedChar[num];
                dula=0;
                while(!KeyS2);
            }
        }

    }

}
void delay()
{
    unsigned int i=1000;
    while(i--);
}
但是,延时消抖也给我们了麻烦,例如在程序执行的过程中反复的延时,会对程序执行的过程有很大的难读性。
这时我们选用定时器消抖:
2.定时器消抖
我们只需要给主函数一个确定按键按下的标志,检验按键按下在定时器函数中完成。
程序如下:
#include <reg52.h>

sbit KeyS2=P3^4;
sbit KeyS3=P3^5;
sbit KeyS4=P3^6;
sbit KeyS5=P3^7;

sbit d1=P1^0;

sbit dula=P2^6;
sbit wela=P2^7;

bit flag=0;

unsigned char code LedChar[]={
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71
};
unsigned char num=0;

void delay();

void main()
{
    wela=1;
    P0=0xdf;
    wela=0;
    dula=1;
    P0=LedChar[num];
    dula=0;
    P3=0xff;
    TMOD=0x01;
    TH0=0xb8;
    TL0=0x00;
    TR0=1;
    EA=1;
    ET0=1;
    while(1)
    {
        if(flag==1)
        {
            flag=0;
            num++;
            if(num>=10)
            {
                num=0;
            }
            dula=1;
            P0=LedChar[num];
            dula=0;
        }


    }

}

void Key_Test() interrupt 1
{
    static unsigned char cnt;
    TH0=0xb8;
    TL0=0x00;

    cnt++;
    if(KeyS2==0)
        {
            if(cnt>=10)
            {
                cnt=0;
                if(KeyS2==0)
                {
                    flag=1;
                }
            }
        }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值