按键原理与应用

九、 按键

9.1 按键原理

  • 当按键按下的时候,从高电平到低电平,当从低电平到高电平时会产生电流异常抖动。抖动时间一般为5ms~10ms。
  • 一般开发板没有对按键进行硬件消抖处理,我们需要进行软件消抖(就是增加延时)。

9.1.1 独立按键原理

我们可以看到原理图,单片机芯片引脚默认输出高电平。当我们按下按键,这个引脚就接地导通,就是该引脚为低电平,当检测到引脚是低电平,就代表按键按下。

9.1.2 矩阵按键原理

 矩阵按键原理和独立按键原理基本一样,重点就在于怎么检测按下的是哪一个按键。

这里给出一个方法:

  1. 先给所有行(P17~P14)输出低电平,检测所有列(P13 ~P10)中哪一列为低电平(确定按键的列)。
  2. 给所有列(P13~ P10)输出低电平,检测所有行(P17~P14)中哪一行为低电平(确定按键的行)。

9.2 代码

9.2.1 独立按键实验代码

  • 这里我们使用四个独立按键控制四个LED灯,分别为P20~ P23的亮灭。
  • 建立文件夹Sw1。
#include <reg52.h>
typedef unsigned int uint;
typedef unsigned char uchar;
sbit sw1=P3^2;
sbit sw2=P3^3;//按键
sbit sw3=P3^4;
sbit sw4=P3^5;  

sbit LED1=P2^0;
sbit LED2=P2^1;//LED
sbit LED3=P2^2;   
sbit LED4=P2^3;

void delay(uint i){
    while(i--){
    }
}

void main(){
    while(1){
        delay(10000);
        if(!sw1) LED1=!LED1;
        if(!sw2) LED2=!LED2;
        if(!sw3) LED3=!LED3;
        if(!sw4) LED4=!LED4;
        delay(10000);
    }
}
  • 按键更改LED的状态,当我们按下按键,引脚为低电平(if条件),则更改LED状态,亮则熄灭,灭则点亮,(翻转状态)。

9.2.2 矩阵按键实验代码

  • 矩阵按键扫描代码。
#ifndef __SCAN_BUTTON_H__//引用外部文件
#define __SCAN_BUTTON_H__

//扫描矩阵按键
#include <reg52.h>
typedef unsigned int uint;
typedef unsigned char uchar;

sbit across1=P1^7;
sbit across2=P1^6;//按键-行
sbit across3=P1^5;
sbit across4=P1^4;

sbit vertical1=P1^3;
sbit vertical2=P1^2;//按键-列
sbit vertical3=P1^1;
sbit vertical4=P1^0;

uint Table16[4][4]={{0x3f,0x06,0x5b,0x4f},  //宏定义4X4矩阵
                    {0x66,0x6d,0x7d,0x07},
                    {0x7f,0x6f,0x77,0x7c},
                    {0x39,0x5e,0x79,0x71}};

//确定行
uint get_line(void){  //get_line函数用于确定按键所在的行。然后逐一检测引脚的状态,如果有一行引脚为低电平,则代表按键所在的行是这行
    uint retVal=4;//retVal初始值设置为4,当我们在检测时,如没检测到按键,返回一个错误值,可通过返回值是否为4判断是否有按键被按下。
    across1=0;//将列引脚全部置为低电平
    across2=0;
    across3=0;
    across4=0;
    if(!vertical1) retVal=1;//检测4个竖直方向的引脚,如果有为低,则将retVal变量设置为相应的值,分别为1234。如果有按键按下,则通过检测引脚的状态来确定是哪一个按键被按下,就设置为相应的值。
    if(!vertical2) retVal=2;
    if(!vertical3) retVal=3;
    if(!vertical4) retVal=4;
    across1=1;//将列引脚重置为默认状态,置为高电平
    across2=1;
    across3=1;
    across4=1;
    return retVal;//并返回按键所在的行。
}

//确定列
uint get_col(void){ 
    uint retVal=4;
    vertical1=0;
    vertical2=0;
    vertical3=0;
    vertical4=0;
    if(!across1) retVal=1;
    if(!across2) retVal=2;
    if(!across3) retVal=3;
    if(!across4) retVal=4;
    vertical1=1;
    vertical2=1;
    vertical3=1;
    vertical4=1;
    return retVal;
}
#endif

显示代码
#ifndef __DISPIAY_UTILS_H__
#define __DISPIAY_UTILS_H__

#include <reg52.h>
sbit P22=P2^2;
sbit P23=P2^3;
sbit P24=P2^4;

void  choose_dispiay(uint i){  //choose_diapiay此函数用于选择数码管显示,接收一个函数i,用来指定需显示的数码管,在函数内部,使用传入的参数i,通过P2的三个引脚,选择选择相应的数码管进行显示。其中,选择数码管的方法是通过设置P22、P23、P24三个引脚的输出电平来实现,共有八种不同的组合方式,对应8个数码管。
    switch(i){
        case 0:P24=1;P23=1;P22=1;break;
        case 1:P24=1;P23=1;P22=0;break;
        case 2:P24=1;P23=0;P22=1;break;
        case 3:P24=1;P23=0;P22=0;break;
        case 4:P24=0;P23=1;P22=1;break;
        case 5:P24=0;P23=1;P22=0;break;  
        case 6:P24=0;P23=0;P22=1;break;   
        case 7:P24=0;P23=0;P22=0;break;   
    }
}
#endif

9.2.2.1 实验一:主函数

  • 按下按键矩阵中的按键,在第一个数码管显示
#inlcude <Scan_Button.h>//引用外部文件
#include <dispiay_utils.h>

void delay (uint i){
    while(i--){}
}
void mian (){
    while(1){
        uint line=4;
        uint col=4;
        delay (10000);
        line = get_line();
        col = get_col();
        delay(10000);
        if(line<4 && col<4){
        P0=Table16[line][col];
        }
    }
}

9.2.2.2 实验二:主函数

  • 按下字符后依次显示
#include <Scan_Button.h>
#include <dispiay_utils.h>

void delay(uint i){
    while(i--){}
}
void main(){
    uint buffer[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
    int index=0;
    while(1){
        uint line=4;
        uint col=4;
        uinti;
        delay(6000);
        line=get_line();
        col=get_col;
        delay(6000);
        if(line<4 && col<4){
            if (index>7 )index=0;
            buffer[index++]=Teble16[line][col];
        }
        for(i=0; i<8; ++i){
            choose_display(i);
            delay(100);
            P0=buffer[i];
            delay(100);
            P0=0x00;
        }
    }
}

9.2.3 代码翻译

9.2.3.1 独立按键实验中的if语句?

  • 按键主要作用为改变LED的状态,如果按下按键,引脚置为低电平(if包含的条件),就更改LED状态,亮则熄灭,灭则点亮。

9.3 整体总结

  • 实验二中矩阵按键检测和数码管显示的时延很难调整,按键速度要够快,不然会出现误检测(出现多个按键同时操作)。
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

向明月和赵沟渠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值