C51单片机学习笔记——矩阵按键
矩阵按键通常是为了节省IO口而设计的,当有多个按键时,如果每个按键都单独接一个IO口,会占用太多资源。所以采用矩阵排列,比如4x4的矩阵,只需要8个IO口(4行+4列),可以支持16个按键,这样效率更高。
一、矩阵按键原理
矩阵按键主要是通过逐列或者逐行的方式进行扫描输出低电平,检测列(或行)输入状态。当某行被激活时,若某列检测到低电平,则对应交叉点的按键被按下。
1.扫描过程
-
步骤1:行线设置为输出模式,列线设置为输入模式(带内部或外部上拉电阻)。
-
步骤2:逐行拉低每一行(如Row1拉低,其他行置高),读取列线状态。
-
步骤3:若某列为低电平,则确定按键位置(如Row1+Column2对应按键5)。
-
步骤4:循环扫描所有行,完成一轮检测。
2.按键消抖
当按键被按下时,我们可以通过延时函数来进行对按键的消抖,可以选择10~20ms的延时进行消抖,避免误触发的现象。
3.原理图
二、代码演示
#include <REGX52.H>
#include "Delay.h"/*** @brief 矩阵按键按下所显示的数字* @param 无* @retval KeyNum显示1~16*///矩阵按键进行逐列扫描
unsigned char MatrixKey(void)
{unsigned char KeyNum = 0;P1 = 0xFF;//P1置高电平有效P1_3 = 0;if(P1_7 == 0){ Delay(20);//消抖while(P1_7==0);//检测松手Delay(20);KeyNum = 1;}if(P1_6 == 0){ Delay(20);while(P1_6==0);Delay(20);KeyNum = 5;}if(P1_5 == 0){ Delay(20);while(P1_5==0);Delay(20);KeyNum = 9;}if(P1_4 == 0){ Delay(20);while(P1_4==0);Delay(20);KeyNum = 13;}P1 = 0xFF;P1_2 = 0;if(P1_7 == 0){ Delay(20);while(P1_7==0);Delay(20);KeyNum = 2;}if(P1_6 == 0){ Delay(20);while(P1_6==0);Delay(20);KeyNum = 6;}if(P1_5 == 0){ Delay(20);while(P1_5==0);Delay(20);KeyNum = 10;}if(P1_4 == 0){ Delay(20);while(P1_4==0);Delay(20);KeyNum = 14;}P1 = 0xFF;P1_1 = 0;if(P1_7 == 0){ Delay(20);while(P1_7==0);Delay(20);KeyNum = 3;}if(P1_6 == 0){ Delay(20);while(P1_6==0);Delay(20);KeyNum = 7;}if(P1_5 == 0){ Delay(20);while(P1_5==0);Delay(20);KeyNum = 11;}if(P1_4 == 0){ Delay(20);while(P1_4==0);Delay(20);KeyNum = 15;}P1 = 0xFF;P1_0 = 0;if(P1_7 == 0){ Delay(20);while(P1_7==0);Delay(20);KeyNum = 4;}if(P1_6 == 0){ Delay(20);while(P1_6==0);Delay(20);KeyNum = 8;}if(P1_5 == 0){ Delay(20);while(P1_5==0);Delay(20);KeyNum = 12;}if(P1_4 == 0){ Delay(20);while(P1_4==0);Delay(20);KeyNum = 16;}return KeyNum;
}
#include <REGX52.H>
#include "Delay.h"
#include "LCD1602.h"
#include "MatrixKey.h"unsigned char KeyNumber;void main()
{LCD_Init();LCD_ShowString(1,1,"Show_KeyNumber:");while(1){KeyNumber = MatrixKey();if(KeyNumber)//判断按键按下{LCD_ShowNum(2,1,KeyNumber,2);}}
}
当矩阵按键被按下时,会显示该行该列对应的数字