-
在键盘中按键数量较多时,为了减少I/O口的占用,通常将按键排列成矩阵形式,采用逐行或逐列的“扫描”,就可以读出任何位置按键的状态
扫描的概念:
数码管扫描(输出扫描)
原理:显示第1位→显示第2位→显示第3位→……,然后快速循环这个过程,最终实现所有数码管同时显示的效果
矩阵键盘扫描(输入扫描)
原理:读取第1行(列)→读取第2行(列) →读取第3行(列) → ……,然后快速循环这个过程,最终实现所有按键同时检测的效果 以上两种扫描方式的共性:节省I/O口
矩阵键盘原理:矩阵键盘有按行和按列扫描两种形式,由于I/O口都默认接高电平的,所以按行扫描就是将每一行的I/O口接地,然后依次读取列I/O口的状态来判断是否按下按键,例如扫描第一行(p17),给p17接地,置0,然后检测p10~13是否为0,如果为0则表示按键按下(由于p17置0,所以按下时对应I/O口相当于接地),为1则表示没有按下。
一、LCD1602显示矩阵按键值
第一种:由于P15和蜂鸣器复用,所以采用逐列扫描的方式,首先将对应的行置0,在依次读取列的值来判定该 按键值是否被按下。
//mian.c
#include <REGX52.H>
#include "Delay.h"
#include "LCD1602.h"
#include "Matrix.h"
unsigned char keyNumber;
void main()
{
LCD_Init();
LCD_ShowString(1,1,"MatrixKey:");
while(1)
{
keyNumber = Matrixkey();
if(keyNumber)
{
LCD_ShowNum(2,1,keyNumber,2);
}
}
}
//Matrix.c
#include <REGX52.H>
#include "Delay.h"
unsigned char Matrixkey()
{
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_5 == 0); Delay(20); KeyNumber = 5;}
if(P1_5 == 0){ Delay(20); while(P1_7 == 0); Delay(20); KeyNumber = 9;}
if(P1_4 == 0){ Delay(20); while(P1_7 == 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_5 == 0); Delay(20); KeyNumber = 6;}
if(P1_5 == 0){ Delay(20); while(P1_7 == 0); Delay(20); KeyNumber = 10;}
if(P1_4 == 0){ Delay(20); while(P1_7 == 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_5 == 0); Delay(20); KeyNumber = 7;}
if(P1_5 == 0){ Delay(20); while(P1_7 == 0); Delay(20); KeyNumber = 11;}
if(P1_4 == 0){ Delay(20); while(P1_7 == 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_5 == 0); Delay(20); KeyNumber = 8;}
if(P1_5 == 0){ Delay(20); while(P1_7 == 0); Delay(20); KeyNumber = 12;}
if(P1_4 == 0){ Delay(20); while(P1_7 == 0); Delay(20); KeyNumber = 16;}
return KeyNumber;
}
//Matrix.h
#ifndef __MATRIX_H_
#define __MATRIX_H_
unsigned char Matrixkey();
#endif
//Delay.c
void Delay(xms) //@11.0592MHz
{
unsigned char i, j;
while(xms)
{
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
xms--;
}
}
//Delay.h
#ifndef __Delay_H_
#define __Delay_H_
void Delay(xms);
#endif
二、矩阵键盘密码锁
//main.c
include <REGX52.H>
#include "Delay.h"
#include "LCD1602.h"
#include "Matrix.h"
unsigned char keyNumber;
unsigned int passwold,count;
void main()
{
LCD_Init();
LCD_ShowString(1,1,"PassWold:");
while(1)
{
keyNumber = Matrixkey();
if(keyNumber)
{
if(keyNumber <= 10)
{
if(count < 4)
{
passwold*=10; //密码左移一位
passwold+=keyNumber;
count++;
}
}
if(keyNumber == 11)
{
if(passwold == 2345)
{
LCD_ShowString(1,14,"ok");
}
else
{
LCD_ShowString(1,14,"err");
}
passwold = 0;
count = 0;
}
if(keyNumber == 12)
{
passwold = 0;
count = 0;
}
LCD_ShowNum(2,1,passwold,4);
}
}
}