矩阵键盘
独立键盘与单片机进行连接时,每一个按键都需要单片机的一个I/O口,若某单片机系统较多按键,如果用独立按键便会占用较多的I/O口资源。为了尽可能节省I/O口线,引入矩阵键盘。
矩阵按键原理
- 在键盘中按键数量较多时,为了减少I/O口的占用,通常将按键排列成矩阵形式
- 采用逐行或逐列的“扫描”,就可以读出任何位置按键的状态
以巫妖王单片机上的4×4矩阵键盘为例,讲解矩阵键盘的原理和检测方法,其原理图如上图所示。将16个按键排成4行4列,第一行将每个按键的一端连接在一起构成行线,第一列将每个按键的另一端连接在一起构成列线,这样一共有4行4列共八根线,我们将这八根线连接到单片机的8个I/O口上,通过程序扫描键盘就可检测16个键。用这种办法我们也可以实现3行3列9个键,5行5列25个键等。
无论是独立键盘还是矩阵键盘,单片机检测其是否被按下的依据都是一样的,也就是检测与该键对应的I/O口是否为低电平。独立键盘有一端固定为低电平,单片机写程序检测时比较方便,但是矩阵键盘两端都与单片机I/O口相连,因此在检测时需要人为通过单片机的I/O口送出低电平。
下面着重介绍一下扫描的概念:
-
数码管扫描(输出扫描)
原理:显示第1位→显示第2位→显示第3位→……,然后快速循环这个过程,最终实现所有数码管同时显示的效果
-
矩阵键盘扫描(输入扫描)
原理:读取第1行(列)→读取第2行(列) →读取第3行(列) → ……,然后快速循环这个过程,最终实现所有按键同时检测的效果
-
以按行扫描为例:
当P1.4-P1.7口赋值为1101时,此时先看P17所在的行,无论S1、S2、S3和S4谁按下,两端都是高电平,同理P15和P14同样如此,而P16所在的行因为P1.6口赋值为0,只要在此基础检测P1.0-P1.3口电平情况就可以判断究竟是S5、S6、S7还是S8被按下。具体的说,当P1.4-P1.7口赋值为1101时,如果P1.0-P1.3口赋值为:1110(P1 .3为0),则S5被按下,其他同理,并以此类推即可。
在写代码前,再介绍C51子函数带返回值的写法
//格式
类型 函数名(形参)
{
函数体;
return 数据;
}
例如:
int getSum(int num1,int num2)
{
int sum = num1 + num2;
return sum;
}
//参数是 函数接收外面传进来的
//返回值 是函数从里面扔出去的
模块化代码
各模块具体代码如下
-
主函数
main()
#include <REGX52.H> #include "Delay.h" #include "LCD1602.h" #include "MaxtrixKey.h" unsigned char KeyNum; //定义变量 接一下返回值 void main() { LCD_Init(); LCD_ShowString(1,1,"Hello World!"); while(1) { KeyNum=MaxtrixKey(); if(KeyNum) { LCD_ShowNum(2,1,KeyNum,2); } } } /* 为什么需要加上if(KeyNum)进行判断,这是因为如果不加的话有一下一种情况: 当你没有按下键时,开始执行KeyNum=MaxtrixKey()语句,即KeyNum通过调用MaxtrixKey函数获取键值,此时KeyNum获取的值为0(不按下键,MaxtrixKey函数内的值就是初始化的值0) 然后开始执行LCD_ShowNum函数,这样1602上就会显示00 当你按下某个键,不松手,会卡在执行KeyNum=MaxtrixKey()语,显示0 显示的键值和显示0 间隔的时间太短 以至于人眼无法识别 */
-
MaxtrixKey.h
#ifndef__MAXTRIXKRY_H__ #define__MAXTRIXKRY_H__ unsigned char MaxtrixKey(); #endif
-
MaxtrixKey.c
#include <REGX52.H> #include "Delay.h" /** * @brief 矩阵键盘读取按键键码 * @param 无 * @retval KeyNumer 按下按键的键码值 如果按下不放,程序会停留在此函数,松手一瞬间,返回按键码,没有按键时,返回0 */ unsigned char MaxtrixKey() { unsigned char KeyNumber=0; P1=0xff; P1_3=0; if(P1_7==0){ Delay(20);while(P1_7==0);Delay(20);KeyNumber=1;} if(P1_6==0){ Delay(20);while(P1_6==0);Delay(20);KeyNumber=5;} if(P1_5==0){ Delay(20);while(P1_5==0);Delay(20);KeyNumber=9;} if(P1_4==0){ Delay(20);while(P1_4==0);Delay(20);KeyNumber=13;} P1=0xff; P1_2=0; if(P1_7