51单片机(六):矩阵键盘的扫描

本文介绍了单片机中独立式和矩阵式按键的工作原理,以及矩阵键盘的扫描方法,包括行扫描和列扫描。同时,展示了带返回值的函数在处理矩阵键盘中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、独立式按键与矩阵式按键

常用的键盘电路有两种形式:独立式按键和矩阵式按键。

1. 独立式按键

e0ce5bad7c06442989d3c096e4e7c0d5.jpeg

        独立式按键比较简单,它们各自与独立的输入线相连接,如上图所示。4条输入线接到单片机的 I / O 口上,当按下按键K1时,+5V依次通过电阻R1和按键K1最终进入 GND 形成一条通路,这条线路的全部电压都加到电阻R1上,引脚 KeyInl 就是一个低电平。当松开按键后,线路断开,不会有电流通过, KeyInl 和+5V应该是等电位,是一个高电平。因此,可以通过引脚 KeyInl 这个 I / O 口的高低电平来判断是否有按键按下。

        实际上在单片机 I / O 口内部,也有一个上拉电阻。按键是接到P2口上,P2口上电默认是准双向 I / O 口,下面来简单了解一下准双向 I / O 口的电路,电路如上图所示。方框内的电路都是指单片机内部部分,方框外的就是外接的上拉电阻和按键。这个地方大家要注意一下,就是当要读取外部按键信号的时候,单片机必须先给该引脚写"1",也就是高电平,这样才能正确读取到外部按键信号,下面来分析一下缘由。

        当内部输出是高电平时,经过一个反向器变成低电平, NPN 三极管不会导通,单片机 I / O 口从内部来看,由于上拉电阻 R 的存在,所以是一个高电平。当外部没有按键按下将电平拉低, VCC 也是+5V,它们之间虽然有两个电阻,但是没有压差,就不会有电流,线上所有的位置是高电平,这时就可以正常读取按键的状态了。

        当内部输出是低电平时,经过一个反相器变成高电平, NPN 三极管导通,单片机的内部 I / O 口就是一个低电平,这时,外部虽然也有上拉电阻的存在,但是两个电阻是并联关系,不管按键是否按下,单片机的 I / O 口上输入单片机内部的状态都是低电平,因此无法正常读取按键的状态。

2. 矩阵式按键

        在某一个系统设计中,当需要使用很多按键时,做成独立按键会大量占用I / O口,因此引入了矩阵按键的设计。如下图所示的矩阵按键电路原理图,使用8个 I / O 口实现16个按键。

6ff41b630a8b4d948170a2b170c18ebf.jpeg

        如果理解了独立按键,就不难理解矩阵按键,下面来分析一下。图中一共有4组按键,我们只看其中一组,如下图所示。大家认真看一下,如果 KeyOutl 输出一个低电平,则KeyOut1相当于 GND ,此时,K1、K2、K3、K4相当于4个独立按键。当然这时KeyOut2、KeyOut3、KeyOut4必须都输出高电平,才能保证与它们相连的3路按键不会对这一路产生干扰,大家可以对照两张原理图分析一下。

6a07f621e87f440082add797a343ef0c.jpeg

3. 矩阵键盘的扫描

        矩阵键盘的逐行逐列扫描方法可以先进行行扫描,也可以先进行列扫描。这取决于具体的实现方式和需求。在行扫描中,逐行检测按键状态,而在列扫描中,逐列检测按键状态。无论是先进行行扫描还是列扫描,最终都可以获取到按键的状态信息。 在逐行逐列扫描方法中,键盘的按键布局被组织成多行和多列的矩阵。每一行的按键都连接到一个行线上,而每一列的按键则连接到一个列线上。

        扫描过程中可以从第一行开始,逐行扫描每一行。在扫描过程中,将当前行的行线置为低电平(相当于是接GND),然后检测该行上每一列的列线上是否有按键按下。如果有按键按下,相应的列线会被置低电平,就可以确定按下的按键是哪一个。

        类似地,在逐列扫描方法中,扫描过程从第一列开始,逐列扫描每一列。将当前列的列线置为低电平(相当于接GND),然后检测每一行的行线上是否有按键按下。如果有按键按下,相应的行线会被置低电平,就可以确定按下的按键是哪一个。

97203cffcab04cacaaa9ecf134f3f138.png

#include <regx52.h>
#include "DELAY.h"

unsigned char MatrixKey()
{
	unsigned char Keynumber=0;
	
	P0=0xff;   //初始化 使用P0寄存器控制 都接入高电平
	P0_4=0;    //第一列置0 逐次扫描该列的每一行
	if(P0_0==0){Delay(20);while(P0_0==0);Delay(20);Keynumber=1;}//按键消抖
	if(P0_1==0){Delay(20);while(P0_1==0);Delay(20);Keynumber=5;}
	if(P0_2==0){Delay(20);while(P0_2==0);Delay(20);Keynumber=9;}
	if(P0_3==0){Delay(20);while(P0_3==0);Delay(20);Keynumber=13;}
	
	P0=0xff;   //初始化 都接入高电平
	P0_5=0;    //第二列置0 逐次扫描该列的每一行
	if(P0_0==0){Delay(20);while(P0_0==0);Delay(20);Keynumber=2;}
	if(P0_1==0){Delay(20);while(P0_1==0);Delay(20);Keynumber=6;}
	if(P0_2==0){Delay(20);while(P0_2==0);Delay(20);Keynumber=10;}
	if(P0_3==0){Delay(20);while(P0_3==0);Delay(20);Keynumber=14;}
	
	P0=0xff;   //初始化 都接入高电平
	P0_6=0;    //第三列置0 逐次扫描该列的每一行
	if(P0_0==0){Delay(20);while(P0_0==0);Delay(20);Keynumber=3;}
	if(P0_1==0){Delay(20);while(P0_1==0);Delay(20);Keynumber=7;}
	if(P0_2==0){Delay(20);while(P0_2==0);Delay(20);Keynumber=11;}
	if(P0_3==0){Delay(20);while(P0_3==0);Delay(20);Keynumber=15;}
	
	P0=0xff;   //初始化 都接入高电平
	P0_7=0;    //第四列置0 逐次扫描该列的每一行
	if(P0_0==0){Delay(20);while(P0_0==0);Delay(20);Keynumber=4;}
	if(P0_1==0){Delay(20);while(P0_1==0);Delay(20);Keynumber=8;}
	if(P0_2==0){Delay(20);while(P0_2==0);Delay(20);Keynumber=12;}
	if(P0_3==0){Delay(20);while(P0_3==0);Delay(20);Keynumber=16;}
	
	return Keynumber;
}

        上述程序展现的只是简单的“矩阵键盘扫描”的函数模块,主要是用来帮助大家理解矩阵键盘扫描的原理及程序实现。

二、带返回值的函数

在单片机中,函数的定义格式与一般的C语言函数定义格式相同。以下是函数定义的一般格式:

返回类型 函数名(参数列表)
{
    数据定义;
    函数体;
    return 返回值;
}

        返回类型指定了函数返回的数据类型,可以是整数、浮点数、字符等。函数名是函数的标识符,用于调用该函数。参数列表是函数接受的输入参数,可以有零个或多个参数,每个参数由参数类型和参数名组成。函数体是函数的具体实现,包含了函数要执行的操作。return语句返回处理后的结果数据。

例如,下面是一个简单的函数定义示例:

int add(int a, int b) 
{
    int sum;
    sum = a + b;
    return sum;
}

这个函数名为add,返回类型为整数类型int,接受两个整数类型的参数a和b。函数体中计算了a和b的和,并将结果存储在sum变量中,最后通过return语句返回sum的值。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值