五、用矩阵键盘实现密码锁

矩阵键盘

独立键盘与单片机进行连接时,每一个按键都需要单片机的一个I/O口,若某单片机系统较多按键,如果用独立按键便会占用较多的I/O口资源。为了尽可能节省I/O口线,引入矩阵键盘。

矩阵按键原理

  • 在键盘中按键数量较多时,为了减少I/O口的占用,通常将按键排列成矩阵形式
  • 采用逐行或逐列的“扫描”,就可以读出任何位置按键的状态

image-20221103204438277

以巫妖王单片机上的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;
}
//参数是 函数接收外面传进来的
//返回值 是函数从里面扔出去的

模块化代码

各模块具体代码如下

  1. 主函数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 间隔的时间太短 以至于人眼无法识别
    */
    
  2. MaxtrixKey.h

    #ifndef__MAXTRIXKRY_H__
    #define__MAXTRIXKRY_H__
    
    unsigned char MaxtrixKey();
    
    #endif
    
  3. 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
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值