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

来源:互联网 发布:dnf商城cd药算法 编辑:程序博客网 时间:2024/06/16 20:40
下面主要讲一下按键的原理:1.独立键盘![独立键盘原理](http://img.blog.csdn.net/20170814121905771?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaGhjaGVuY2hvbmc=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)对其来说,如果你检验KeyIn口为高电平,说明按键弹起,相反的,KeyIn口为低电平,则说明按键按下。2.矩阵键盘![矩阵键盘原理](http://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;                }            }        }}