【单片机/普中A2】学习笔记5-矩阵键盘

矩阵键盘原理

参考文献:点击前往


扫描模式

数码管扫描:输出扫描的一种,以人类肉眼无法分辨的速度进行扫描,呈现出同时显示的假象

矩阵键盘扫描:输入扫描的一种,高速逐行扫描,获取按键按下位置;目前的电脑显示器也是使用此方法检测,可以极大地压缩引脚数量(譬如 1920x1080,仅需引脚:1920+1080=3000)


实例展示

检测单点按键

首先我们来看一下检测按键的核心代码

代码清单 MatrixKey.c

#include 
#include "Delay.h"

/**
  * @brief  矩阵键盘读取按键键码
  * @param  无
  * @retval KeyNumber 按下按键的键码值
			如果按键按下不放,程序会停留在此函数,松手的一瞬间,返回按键键码,没有按键按下时,返回0
  */
unsigned char MatrixKey()
{
    // 当前点击的按键
	unsigned char KeyNumber=0;

    // 第一步:全局置1,即全部上拉
	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==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_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_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;
}

别忘了头文件 MatrixKey.h

#ifndef __MATRIXKEY_H__
#define __MATRIXKEY_H__

unsigned char MatrixKey();

#endif

之后总结我们之前的 Delay 和 LCD1602 模块,不难得出以下代码

代码清单 main.c

#include 
#include "Delay.h"
#include "LCD1602.h"
#include "MatrixKey.h"


unsigned char KeyNum;

void main(){

	LCD_Init();						           	//LCD初始化
	LCD_ShowString(1,1,"MatrixKey:");	        //LCD显示字符串
	while(1)
	{
		KeyNum=MatrixKey();				    //获取矩阵键盘键码
		if(KeyNum)						    //如果有按键按下
		{
			LCD_ShowNum(2,1,KeyNum,2);	//LCD显示键码
		}
	}
}

密码锁

仅需修改源文件即可

代码清单 main.c

#include 
#include "Delay.h"
#include "LCD1602.h"
#include "MatrixKey.h"
// 按键作用: S1~S9 设置数字为 1~9, S10定义为数字0, S11用作于是确认按键, S12用作于是取消按键 《《《 S13~S16,我们不去进行使用
unsigned char KeyNum;        // 全局变量初始化默认为:0
unsigned int Password,Count; // 如果用6位数字的密码就会超出这个 unsigned int 的一个数值的范围了 0~65535, Count作用:计次,防止输入过多的密码

int main(void)
{
	LCD_Init();
	LCD_ShowString(1,1,"Password:");
	while(1)
	{
		KeyNum=MatrixKey();
		if(KeyNum)
		{
			if(KeyNum<=10)	//如果S1~S10按键按下,输入密码
			{
				if(Count<4)	  //如果输入次数小于4
				{
					Password*=10;				        //密码左移一位 : Password = Password * 10
					Password+=KeyNum%10;		    //获取一位密码 : Password = password + KeyNum % 10, 1~9取模10还是为原来的数字~ 获取密码用取模%运算符然后进行赋值
					Count++;	 //计次加一
				}
				LCD_ShowNum(2,1,Password,4);	//更新显示   0000 0000 输入第一次(1) 显示0001 》》》 0001 0010 输入第二次(2) 显示0012
			}
			if(KeyNum==11)	//如果S11按键按下,确认 ----注意:这里不进行消抖的原因是:模块化编程的时候已经进行消抖了
			{
				if(Password==2345)	//如果密码等于正确密码 --------------------------- 定义密码
				{
					LCD_ShowString(1,14,"OK ");	// 显示OK
					Password=0;		// 密码清零
					Count=0;		  // 计次清零
					LCD_ShowNum(2,1,Password,4);	// 更新显示
				}
				else				//否则
				{
					LCD_ShowString(1,14,"ERR");	//显示ERR
					Password=0;		// 密码清零
					Count=0;		  // 计次清零
					LCD_ShowNum(2,1,Password,4);	//更新显示
				}
			}
			if(KeyNum==12)	//如果S12按键按下,取消
			{
				Password=0;		// 密码清零
				Count=0;		 // 计次清零
				LCD_ShowNum(2,1,Password,4);	//更新显示
			}
		}
	}
}

你可能感兴趣的:(Linux,单片机,学习,笔记)