6-矩阵键盘
1.矩阵键盘原理
在键盘中按键数量较多时,为了减少I/O口的占用,通常将按键排列成矩阵形式
采用逐行或逐列的“扫描”,就可以读出任何位置按键的状态
数码管是输出扫描:
原理:显示第1位→显示第2位→显示第3位→……,然后快速循环这个过程,最终实现所有数码管同时显示的效果
矩阵键盘是输入扫描:
原理:读取第1行(列)→读取第2行(列) →读取第3行(列) → ……,然后快速循环这个过程,最终实现所有按键同时检测的效果
将矩阵按键进行按列扫描,例如,先设置P13,P12,P11,P10为0111,在此基础上,P17=0,说明S1按下,P16=0,说明S5按下,P15=0,说明S9按下,P14=0,说明S13按下。(因为按行进行扫描会出现冲突)这里的原理刚好与下面的函数代码相对应。
2.弱上拉
简单点说就是1的驱动力是有限的,0的驱动能力比较强,弱上拉,强下拉这就是这种单片机IO口的工作模式
简单模型
在这种模型下,虽然VCC输出的是1电平,但由于中间有一个电阻,后面直接接地,所以检测点检测到的输出也是0
具体了解可以看STC89C52的官方手册
3.基础操作
先将原来的模块化文件copy过来
测试LCD1602是否有效
#include <STC89C5xRC.H>
#include "Delay.h"
#include "LCD1602.h"
void main()
{
LCD_Init();//可以右键点击追踪到函数的声明为止
LCD_ShowString(1,1,"HelloWorld");
while(1)
{
}
}
由于每次生成这些.h文件,都要敲一些相同的代码,可以通keil自带的Templates来配置自己的模板
用到其他一些高重复性的代码时也可以生成相应的模板
在2处空白处右键可以设置模板,4处的竖杆表明生成模板后的鼠标位置
4.代码实现
独立按键显示相应键值
Matrix.c
#include <STC89C5xRC.H>
#include "Delay.h"
/**
* @brief 矩阵键盘读取按键键码
* @param 无
* @retval KeyNumber 按下的按键的键值
如果按键按下不放,程序会留在此函数,松手时才返回相应的键码值,没有按键按下时
返回0
*/
unsigned char MatrixKey()
{
unsigned char KeyNumber=0;
P1=0xFF;
P13=0;
if(P17==0){Delay(20);while(P17==0);Delay(20);KeyNumber=1;}
if(P16==0){Delay(20);while(P16==0);Delay(20);KeyNumber=5;}
if(P15==0){Delay(20);while(P15==0);Delay(20);KeyNumber=9;}
if(P14==0){Delay(20);while(P14==0);Delay(20);KeyNumber=13;}
P1=0xFF;
P12=0;
if(P17==0){Delay(20);while(P17==0);Delay(20);KeyNumber=2;}
if(P16==0){Delay(20);while(P16==0);Delay(20);KeyNumber=6;}
if(P15==0){Delay(20);while(P15==0);Delay(20);KeyNumber=10;}
if(P14==0){Delay(20);while(P14==0);Delay(20);KeyNumber=14;}
P1=0xFF;
P11=0;
if(P17==0){Delay(20);while(P17==0);Delay(20);KeyNumber=3;}
if(P16==0){Delay(20);while(P16==0);Delay(20);KeyNumber=7;}
if(P15==0){Delay(20);while(P15==0);Delay(20);KeyNumber=11;}
if(P14==0){Delay(20);while(P14==0);Delay(20);KeyNumber=15;}
P1=0xFF;
P10=0;
if(P17==0){Delay(20);while(P17==0);Delay(20);KeyNumber=4;}
if(P16==0){Delay(20);while(P16==0);Delay(20);KeyNumber=8;}
if(P15==0){Delay(20);while(P15==0);Delay(20);KeyNumber=12;}
if(P14==0){Delay(20);while(P14==0);Delay(20);KeyNumber=16;}
return KeyNumber;
}
Matrix.h
#ifndef __MATRIXKEY_H__
#define __MATRIXKEY_H__
unsigned char MatrixKey();
#endif
main.c
#include <STC89C5xRC.H>
#include "Delay.h"
#include "LCD1602.h"
#include "Matrix.h"
unsigned char KeyNum;
void main()
{
LCD_Init();
LCD_ShowString(1,1,"HelloWorld");
while(1)
{
KeyNum=MatrixKey();
if(KeyNum)
{
LCD_ShowNum(2,1,KeyNum,2);
}
}
}
5.矩阵键盘密码锁
#include <STC89C5xRC.H>
#include "Delay.h"
#include "LCD1602.h"
#include "MatrixKey.h"
unsigned char KeyNum;
unsigned int Password,Count;
void main()
{
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+=KeyNum%10;//获取一位密码
}
Count++;
LCD_ShowNum(2,1,Password,4);//更新显示
}
if(KeyNum==11) //按下S11表示确认
{
if(Password==6666)//如果密码正确,显示OK
{
LCD_ShowString(1,14,"OK ");
Count=0;//计数清0
Password=0;//密码清0
LCD_ShowNum(2,1,Password,4);//更新显示
}
else //如果密码错误,显示ERR
{
LCD_ShowString(1,14,"ERR");
Count=0;//计数清0
Password=0;//密码清0
LCD_ShowNum(2,1,Password,4);//更新显示
}
}
if(KeyNum==12) //S12为取消键,按下密码清0
{
Count=0;//计数清0
Password=0;//密码清0
LCD_ShowNum(2,1,Password,4);//更新显示
}
}
}
}
其他文件和上述文件一样