04 - 矩阵键盘
04 - 矩阵键盘
前言
LCD1602
液晶屏
在学习使用矩阵键盘之前,为了后续的调试和显示,有必要简单了解一下LCD1602
液晶屏的使用方法。江协科技已经给我们提供了模块化的代码,所以我们只需要调用对应方法就可以了,常用方法如下:
至于LCD1602
具体如何操作使用,后续会有,暂时就先放一边
扫描的概念
扫描的作用:节省I/O
口
-
数码管的扫描(输出扫描)
原理:显示第1位——>显示第2位——>显示第3位——>...,然后快速循环这个过程,最终实现所有数码管同时显示的效果
-
矩阵键盘的扫描(输入扫描)
原理:读取第1行(列)——>读取第2行(列)——>读取第3行(列)——>...,然后快速循环这个过程,最终实现所有按键同时检测的效果
矩阵键盘
-
在键盘中按键数量较多时,为了减少
I/O
口的占用,通常将按键排列成矩阵形式 -
采用逐行或逐列的“扫描”,就可以读出任何位置按键的状态
注意:看江协科技视频,提到由于其开发板内部的电路连接问题,如果采用逐行扫描的话,P15
端口的电平时高时低,而且蜂鸣器会一直响,无法关闭。所以为了避免这个问题,采用逐列扫描(但是我使用的开发板和其不一样,于是试了试逐行扫描,蜂鸣器并没有响。具体差异学完后面再回来看看)
一、读取矩阵键盘的键码值
#include <REGX52.H>
#include "LCD1602.H"
void Delay(unsigned int xms) //@12.000MHz
{
unsigned char i, j;
while(xms)
{
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
xms--;
}
}
/**
* @brief 矩阵键盘读取按键键码(逐列)
* @param 无
* @retval chKeyNum 按下按键的键码值
* 如果按键按下不放,程序会停留在此函数,松手返回按键键码。若没有按键按下,返回0
*/
unsigned char MatrixKey()
{
unsigned char chKeyNum = 0;
P1 = 0xFF;
P1_3 = 0;
if(P1_7 == 0){Delay(20);while(P1_7 == 0);Delay(20);chKeyNum=1;}
if(P1_6 == 0){Delay(20);while(P1_6 == 0);Delay(20);chKeyNum=5;}
if(P1_5 == 0){Delay(20);while(P1_5 == 0);Delay(20);chKeyNum=9;}
if(P1_4 == 0){Delay(20);while(P1_4 == 0);Delay(20);chKeyNum=13;}
P1 = 0xFF;
P1_2 = 0;
if(P1_7 == 0){Delay(20);while(P1_7 == 0);Delay(20);chKeyNum=2;}
if(P1_6 == 0){Delay(20);while(P1_6 == 0);Delay(20);chKeyNum=6;}
if(P1_5 == 0){Delay(20);while(P1_5 == 0);Delay(20);chKeyNum=10;}
if(P1_4 == 0){Delay(20);while(P1_4 == 0);Delay(20);chKeyNum=14;}
P1 = 0xFF;
P1_1 = 0;
if(P1_7 == 0){Delay(20);while(P1_7 == 0);Delay(20);chKeyNum=3;}
if(P1_6 == 0){Delay(20);while(P1_6 == 0);Delay(20);chKeyNum=7;}
if(P1_5 == 0){Delay(20);while(P1_5 == 0);Delay(20);chKeyNum=11;}
if(P1_4 == 0){Delay(20);while(P1_4 == 0);Delay(20);chKeyNum=15;}
P1 = 0xFF;
P1_0 = 0;
if(P1_7 == 0){Delay(20);while(P1_7 == 0);Delay(20);chKeyNum=4;}
if(P1_6 == 0){Delay(20);while(P1_6 == 0);Delay(20);chKeyNum=8;}
if(P1_5 == 0){Delay(20);while(P1_5 == 0);Delay(20);chKeyNum=12;}
if(P1_4 == 0){Delay(20);while(P1_4 == 0);Delay(20);chKeyNum=16;}
return chKeyNum;
}
/**
* @brief 矩阵键盘读取按键键码(逐行)
* @param 无
* @retval chKeyNum 按下按键的键码值
* 如果按键按下不放,程序会停留在此函数,松手返回按键键码。若没有按键按下,返回0
*/
unsigned char MatrixKey_2()
{
unsigned char chKeyNum = 0;
P1 = 0xFF;
P1_7 = 0;
if(P1_3 == 0){Delay(20);while(P1_3 == 0);Delay(20);chKeyNum=1;}
if(P1_2 == 0){Delay(20);while(P1_2 == 0);Delay(20);chKeyNum=2;}
if(P1_1 == 0){Delay(20);while(P1_1 == 0);Delay(20);chKeyNum=3;}
if(P1_0 == 0){Delay(20);while(P1_0 == 0);Delay(20);chKeyNum=4;}
P1 = 0xFF;
P1_6 = 0;
if(P1_3 == 0){Delay(20);while(P1_3 == 0);Delay(20);chKeyNum=5;}
if(P1_2 == 0){Delay(20);while(P1_2 == 0);Delay(20);chKeyNum=6;}
if(P1_1 == 0){Delay(20);while(P1_1 == 0);Delay(20);chKeyNum=7;}
if(P1_0 == 0){Delay(20);while(P1_0 == 0);Delay(20);chKeyNum=8;}
P1 = 0xFF;
P1_5 = 0;
if(P1_3 == 0){Delay(20);while(P1_3 == 0);Delay(20);chKeyNum=9;}
if(P1_2 == 0){Delay(20);while(P1_2 == 0);Delay(20);chKeyNum=10;}
if(P1_1 == 0){Delay(20);while(P1_1 == 0);Delay(20);chKeyNum=11;}
if(P1_0 == 0){Delay(20);while(P1_0 == 0);Delay(20);chKeyNum=12;}
P1 = 0xFF;
P1_4 = 0;
if(P1_3 == 0){Delay(20);while(P1_3 == 0);Delay(20);chKeyNum=13;}
if(P1_2 == 0){Delay(20);while(P1_2 == 0);Delay(20);chKeyNum=14;}
if(P1_1 == 0){Delay(20);while(P1_1 == 0);Delay(20);chKeyNum=15;}
if(P1_0 == 0){Delay(20);while(P1_0 == 0);Delay(20);chKeyNum=16;}
return chKeyNum;
}
void main()
{
unsigned char chKeyNum = 0;
LCD_Init();
LCD_ShowString(1, 1, "MatrixKey: ");
while(1)
{
chKeyNum = MatrixKey();
if(chKeyNum)
{
LCD_ShowNum(2, 1, chKeyNum, 2);
}
}
}
二、矩阵键盘密码锁
#include <REGX52.H>
#include "LCD1602.H"
void Delay(unsigned int xms) //@12.000MHz
{
unsigned char i, j;
while(xms)
{
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
xms--;
}
}
/**
* @brief 矩阵键盘读取按键键码(逐列)
* @param 无
* @retval chKeyNum 按下按键的键码值
* 如果按键按下不放,程序会停留在此函数,松手返回按键键码。若没有按键按下,返回0
*/
unsigned char MatrixKey()
{
unsigned char chKeyNum = 0;
P1 = 0xFF;
P1_3 = 0;
if(P1_7 == 0){Delay(20);while(P1_7 == 0);Delay(20);chKeyNum=1;}
if(P1_6 == 0){Delay(20);while(P1_6 == 0);Delay(20);chKeyNum=5;}
if(P1_5 == 0){Delay(20);while(P1_5 == 0);Delay(20);chKeyNum=9;}
if(P1_4 == 0){Delay(20);while(P1_4 == 0);Delay(20);chKeyNum=13;}
P1 = 0xFF;
P1_2 = 0;
if(P1_7 == 0){Delay(20);while(P1_7 == 0);Delay(20);chKeyNum=2;}
if(P1_6 == 0){Delay(20);while(P1_6 == 0);Delay(20);chKeyNum=6;}
if(P1_5 == 0){Delay(20);while(P1_5 == 0);Delay(20);chKeyNum=10;}
if(P1_4 == 0){Delay(20);while(P1_4 == 0);Delay(20);chKeyNum=14;}
P1 = 0xFF;
P1_1 = 0;
if(P1_7 == 0){Delay(20);while(P1_7 == 0);Delay(20);chKeyNum=3;}
if(P1_6 == 0){Delay(20);while(P1_6 == 0);Delay(20);chKeyNum=7;}
if(P1_5 == 0){Delay(20);while(P1_5 == 0);Delay(20);chKeyNum=11;}
if(P1_4 == 0){Delay(20);while(P1_4 == 0);Delay(20);chKeyNum=15;}
P1 = 0xFF;
P1_0 = 0;
if(P1_7 == 0){Delay(20);while(P1_7 == 0);Delay(20);chKeyNum=4;}
if(P1_6 == 0){Delay(20);while(P1_6 == 0);Delay(20);chKeyNum=8;}
if(P1_5 == 0){Delay(20);while(P1_5 == 0);Delay(20);chKeyNum=12;}
if(P1_4 == 0){Delay(20);while(P1_4 == 0);Delay(20);chKeyNum=16;}
return chKeyNum;
}
void main()
{
unsigned char chKeyNum = 0;
unsigned int nPassword = 0;
unsigned int nCnt = 0;
LCD_Init();
LCD_ShowString(1, 1, "Password: ");
while(1)
{
chKeyNum = MatrixKey();
if(chKeyNum > 0 && chKeyNum < 11) // 密码输入
{
if(nCnt < 4)
{
nPassword *= 10;
nPassword += chKeyNum;
LCD_ShowNum(2, 1, nPassword, 4);
}
nCnt++;
}
else if(chKeyNum == 11) // 清零键
{
nCnt = 0;
nPassword = 0;
LCD_ShowNum(2, 1, nPassword, 4);
}
else if(chKeyNum == 12) // 确定键
{
if(nPassword == 1234)
{
LCD_ShowString(1, 14, "OK ");
}
else
{
LCD_ShowString(1, 14, "ERR");
}
nCnt = 0;
nPassword = 0;
LCD_ShowNum(2, 1, nPassword, 4);
}
}
}