学习笔记之51单片机键盘篇(非编码键盘与编码键盘、非编码键盘的扫描方式、独立键盘、矩阵键盘)

(一)基础补充

1.键盘的任务

(1)判别是否有键按下?若有,进入下一步。
(2)识别哪一个键被按下,并求出相应的键值。
(3)根据键值,找到相应键值的处理程序入口。

2.键盘的识别

在这里插入图片描述
按键的闭合与否,反映在行线输出电压上就是呈现高电平或低电平,单片机通过对行线电平的高低状态的检测,便可以确认按键是否按下或松开。为了确保单片机对一次按键动作只确认一次按键有效(所谓按键有效,是指按下按键后,一定要再松开),必须消除抖动期t1和t3的影响。

3.如何消除按键的抖动

(1)用软件延时来消除按键抖动,基本思路是:在检测到有键按下时,该键所对应的行线为低电平,执行一段延时10ms的子程序后,确认该行线电平是否仍为低电平,如果仍为低电平,则确认该行确实有键按下。当按键松开时,行线的低电平变为高电平,执行一段延时10ms的子程序后,检测该行线为高电平,说明按键确实已经松开。
(2)采用专用的键盘/显示器接口芯片,这类芯片中都有自动去抖动的硬件电路。

4.非编码键盘与编码键盘

(1)非编码键盘是指按下按键,键号信息不能直接得到,要通过软件来获取。非编码键盘常见的有独立式键盘和矩阵式键盘两种结构。
(2)编码键盘是指当按键按下后,能直接得到按键的键号,例如使用专用的键盘接口芯片。

5.非编码键盘的扫描方式

(1)查询扫描:

利用单片机空闲时,调用键盘扫描子程序,反复扫描键盘,来响应键盘的输入请求,如果单片机的查询频率过高,虽能及时响应键盘的输入,但也会影响其他任务的进行。如果查询的频率过低,有可能出现键盘输入的漏判现象。所以要根据单片机系统的繁忙程度和键盘的操作频率,来调整键盘扫描的频率。

(2)定时扫描:

单片机可每隔一定的时间对键盘扫描一次,即定时扫描。这种方式通常是利用单片机内的定时器产生的定时中断,进入中断子程序后对键盘进行扫描,在有键按下时识别出按下的键,并执行相应键的处理程序。由于每次按键的时间一般不会小于100ms,所以为了不判漏有效的按键,定时中断的周期一般小于100ms。

(3)中断扫描:

为了进一步提高单片机扫描键盘的工作效率,可采用中断扫描方式,即键盘只有在有按键按下时,才会向单片机发出中断请求信号。单片机响应中断,执行键盘扫描中断服务子程序,识别出按下的按键,并跳向该按键的处理程序。如果无键按下,单片机将不理睬键盘。该方式的优点是只有有按键按下时才会进行处理,所以实时性强,工作效率高。

(二)独立键盘

1.独立键盘原理图

在这里插入图片描述

独立式键盘的特点是各键相互独立,每个按键各接一条I/O口线,通过检测I/O口输入线的电平状态,很容易判断哪个按键被按下。

2.独立键盘K1控制LED1代码实现

#include<reg52.h>
sbit led1=P2^0;//因为led1由p2^0口控制
sbit k1=P3^1;//P31口的输出电平由按键k1控制
void delay(int i)
{
	while(i--);
}
void keyproc()
{
	if(k1==0)
	{
		delay(1000);//延时消抖
		if(k1==0)
		{
			led1=~led1;
		}
		while(!k1) ;
		
	}
}
void main()
{
	while(1)
	{
		keyproc();
	}
}

(三)矩阵键盘

1.矩阵键盘原理图

在这里插入图片描述
矩阵式(也称行列式)键盘通常用于按键数目较多的场合,它由行线和列线组成,按键位于行、列交叉点上,其接口电路如上图。

2.矩阵键盘对应数码管输出0到代码实现

#include "reg52.h"
typedef unsigned char uchar;
typedef unsigned int uint;
#define GPIO_DIG P0
#define GPIO_KEY P1
 
uchar code smgduan[16]= {0x3f, 0x06, 0x5b, 0x4f,
                         0x66, 0x6d, 0x7d, 0x07,
					     0x7f, 0x6f, 0x77, 0x7c,
					     0x39, 0x5e, 0x79, 0x71};//静态数码管码值
 
uint KeyColValue;
uint KeyLineValue;
 
void delay(uint i) //延时函数
{
    while(i --);
}
 
void KeyDown() //键盘按键扫描函数
{
    char a; 
    GPIO_KEY = 0x0f;
    if(GPIO_KEY != 0x0f)//检测4行中哪一行按键是否按下
    {
        delay(1000); //延时消抖
        if(GPIO_KEY != 0x0f) //再次检测4行中哪一行按键是否按下
        {
            switch(GPIO_KEY) //根据IO的值来确定哪一行按键按下
            {
                case(0x07): KeyColValue = 0; break;
                case(0x0b): KeyColValue = 1; break;
                case(0x0d): KeyColValue = 2; break;
                case(0x0e): KeyColValue = 3; break;
            }
        }
    }
    GPIO_KEY = 0xf0;
    if(GPIO_KEY != 0xf0) //检测4行中哪一列按键是否按下
    {
        delay(1000);  //延时消抖
        if(GPIO_KEY != 0xf0) //再次检测4行中哪一列按键是否按下
        {
            switch(GPIO_KEY) //根据IO的值来确定哪一列按键按下
            {
                case(0x70): KeyLineValue = 0; break;
                case(0xb0): KeyLineValue = 1; break;
                case(0xd0): KeyLineValue = 2; break;
                case(0xe0): KeyLineValue = 3; break;
            }
        }
 
        while((a < 50) && (GPIO_KEY != 0xf0))  //延时,确保没有按键再按下
        {
            delay(1000);
            a ++;
        }
    }
}
 
void main()
{
    while(1)
    {
        KeyDown();//检测按键是否按下
        GPIO_DIG = smgduan[KeyLineValue*4 + KeyColValue];//根据按键的行列值,静态数码管显示相应的值
    }
}

最后还想说的是,看到最后的朋友们,如果对你有用,点赞收藏哦!
创作不易,还需要你们的支持,后续持续更新51单片机系列。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

是北豼不太皮吖

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

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

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

打赏作者

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

抵扣说明:

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

余额充值