06矩阵键盘


矩阵键盘

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

  • 原理图
    在这里插入图片描述
  • P17 ~ 14控制行;P13 ~ 10控制列
  • P1端是接到单片机上,单片机上电的时候所有I/O口默认都是高电平,如果按键没有按下,I/O口保持高电平;如果按下按键,I/O口变成低电平,因为接地了。所以按键给0时按下
  • 单片机“弱上拉,强下拉”。输出1,驱动能力很弱;输出0,驱动能力比较强。

矩阵键盘应用

显示键码值在LCD上

利用模块化编程、Templates自定义函数框架放置驱动代码,将重心放在主函数的逻辑代码上

  • 导入Delay、LCD1602头文件
  • 按键扫描——创建MatrixKey.h及.c文件

MatrixKey.h

#ifndef __MATRIXKEY_H__
#define __MATRIXKEY_H__

unsigned char MatrixKey();

#endif

  • P17 ~ 14控制行;P13 ~ 10控制列,
  • P1全部置高电平,对于列(P13 ~ 10)其中一列给0即扫描该列
  • 延迟消抖、检测松手,在同一列的基础上,扫描每一行
  • 判断当扫描到其中一行(P17~14)等于0时,表示按下,返回按键值

在这里插入图片描述

MatrixKey.c

#include <REGX52.H>
#include "Delay.h"
unsigned char MatrixKey() //扫描按键(先列后行)
{
	unsigned char KeyNumber=0; //初始化
	
	
	P1=0xFF; //P1全部置高电平
	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全部置高电平
	P1_2=0;  //第二列
	if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=2;}
	if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=6;}
	if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=10;}
	if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=14;}
	
	P1=0xFF; //P1全部置高电平
	P1_1=0;  //第三列
	if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=3;}
	if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=7;}
	if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=11;}
	if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=15;}
	
	P1=0xFF; //P1全部置高电平
	P1_0=0;  //第四列
	if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=4;}
	if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=8;}
	if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=12;}
	if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=16;}
	

	return KeyNumber;//用返回值代替按键值
}

main.c

#include <REGX52.H>
#include "Delay.h"
#include "LCD1602.h"
#include "MatrixKey.h"

unsigned char KeyNum;

void main()
{
	LCD_Init();
	LCD_ShowString(1,1,"MatrixKey:");
	
	while(1)
	{
		KeyNum=MatrixKey();
		if(KeyNum) //判断“当按键值不为零”为真时
		{
			LCD_ShowNum(2,1,KeyNum,2); //在LCD第二行第一列开始显示长度为2的按键值 
		}
	}
}

矩阵密码锁

  • 大框架的两个if语句都是在**判断按键按下if(KeyNum)**的条件下进行的
  • 输入密码:乘十数字左移,取余获得一位数
  • 确认密码:判断完毕后,计数与密码都要清零
  • 取消密码:全部取消or按位取消(注意计次变化

计次是防止输入数字超出正确密码位数

main.c

#include <REGX52.H>
#include "Delay.h"
#include "LCD1602.h"
#include "MatrixKey.h"

unsigned char KeyNum;
unsigned int Password,Count; //全局变量默认初始值为0

void main()
{
	LCD_Init();
	LCD_ShowString(1,1,"Password:");
	
	while(1)
	{
		KeyNum=MatrixKey();
		if(KeyNum)  //按键按下
		{
			if(KeyNum<=10)  //S1~S10按键按下,输入密码
			{
				if(Count<4)  //按下次数
				{
					Password*=10; //Password初始值默认为0,左移一位
					Password+=KeyNum%10; //获取一位密码
					Count++; //计次
				}
				LCD_ShowNum(2,1,Password,4);  //更新显示
					
			 }
			
			if(KeyNum==11) //如果S11按键按下,确认
			{
				if(Password==5678) //输入正确
				{
					LCD_ShowString(1,11,"OK "); //显示OK
					Password=0; //密码清零
					Count=0; //计次清零
					LCD_ShowNum(2,1,Password,4);
				}
				else //输入错误
				{
					LCD_ShowString(1,11,"ERR"); //显示OK
					Password=0; //密码清零
					Count=0; //计次清零
					LCD_ShowNum(2,1,Password,4);
				}
			}
			
			if(KeyNum==12) //如果S12按键按下,取消
			{
				Password=0; //密码清零
				Count=0; //计次清零
				LCD_ShowNum(2,1,Password,4);
			}
			
			if(KeyNum==13) //如果S13按键按下,按位取消
			{
				if(Count>0)
				{
					Password/=10; //右移一位
					Count--;  //取消一次计数
					LCD_ShowNum(2,1,Password,4);
				}
			}	
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值