工具
硬件:普中科技AT89C52系列单片机 编程软件:Keil5 烧录软件:STC-ISP
原理图
教学视频
B站矩阵键盘实现密码锁
实验代码
#include <REGX52.H>
#include "LCD1602.h"
#include "Delay.h"
#include "MatrixKey.h"
#define DEL 10
#define SURE 11
#define TRUE 1
#define FALSE 0
#define NONE 20
unsigned char value = NONE;
unsigned char times;
unsigned char password[] = {0,1,0,0,7};
unsigned char identify = TRUE;
unsigned char input[5]={0,0,0,0,0};
void main()
{
LCD_Init();
LCD_ShowString(1,1,"Password:");
LCD_ShowString(2,1,"XXXX");
while(1)
{
MatrixKey(&value,×);
if(value>=0 && value <=9){
LCD_ShowNum(2,times,value,1);
input[times] = value;
if(times==FULL){
unsigned int i;
for(i=1; i<=4; i++){
if(input[i] != password[i])
identify = FALSE;
}
}
}
if(value == DEL){
LCD_ShowString(2,times,"X");
times--;
value = NONE;
}
if(identify==FALSE && times==FULL && value==SURE ){
LCD_ShowString(1,12,"Error");
LCD_ShowString(2,1,"XXXX");
identify = TRUE;
value = NONE;
}else if(identify==TRUE && times==FULL && value==SURE){
LCD_ShowString(1,12,"Right");
}
}
}
#include <REGX52.H>
#include "Delay.h"
#define FULL 4
#define KEY_SCAN P1
void MatrixKey(unsigned char* keyValue,unsigned char* times)
{
KEY_SCAN = 0X0F;
if(KEY_SCAN!=0X0F)
{
Delay(10);
KEY_SCAN = 0X0F;
switch(KEY_SCAN)
{
case 0X07:*keyValue = 0;break;
case 0X0B:*keyValue = 1;break;
case 0X0D:*keyValue = 2;break;
case 0X0E:*keyValue = 3;break;
}
KEY_SCAN = 0XF0;
switch(KEY_SCAN)
{
case 0X70:*keyValue = *keyValue;break;
case 0XB0:*keyValue += 4;break;
case 0XD0:*keyValue += 8;break;
case 0XE0:*keyValue += 12;break;
}
if(*keyValue>=0 && *keyValue<=9){
*times = *times % 4 + 1;
}
while(KEY_SCAN!=0XF0)
{
Delay(10);
}
}
}
#include <REGX52.H>
sbit LCD_RS=P2^6;
sbit LCD_RW=P2^5;
sbit LCD_EN=P2^7;
#define LCD_DataPort P0
void LCD_Delay()
{
unsigned char i, j;
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
}
void LCD_WriteCommand(unsigned char Command)
{
LCD_RS=0;
LCD_RW=0;
LCD_DataPort=Command;
LCD_EN=1;
LCD_Delay();
LCD_EN=0;
LCD_Delay();
}
void LCD_WriteData(unsigned char Data)
{
LCD_RS=1;
LCD_RW=0;
LCD_DataPort=Data;
LCD_EN=1;
LCD_Delay();
LCD_EN=0;
LCD_Delay();
}
void LCD_SetCursor(unsigned char Line,unsigned char Column)
{
if(Line==1)
{
LCD_WriteCommand(0x80|(Column-1));
}
else if(Line==2)
{
LCD_WriteCommand(0x80|(Column-1+0x40));
}
}
void LCD_Init()
{
LCD_WriteCommand(0x38);
LCD_WriteCommand(0x0c);
LCD_WriteCommand(0x06);
LCD_WriteCommand(0x01);
}
void LCD_ShowChar(unsigned char Line,unsigned char Column,unsigned char Char)
{
LCD_SetCursor(Line,Column);
LCD_WriteData(Char);
}
void LCD_ShowString(unsigned char Line,unsigned char Column,unsigned char *String)
{
unsigned char i;
LCD_SetCursor(Line,Column);
for(i=0;String[i]!='\0';i++)
{
LCD_WriteData(String[i]);
}
}
int LCD_Pow(int X,int Y)
{
unsigned char i;
int Result=1;
for(i=0;i<Y;i++)
{
Result*=X;
}
return Result;
}
void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
unsigned char i;
LCD_SetCursor(Line,Column);
for(i=Length;i>0;i--)
{
LCD_WriteData(Number/LCD_Pow(10,i-1)%10+'0');
}
}
注意
- 每次输入键值为10(删除键)时,除了要使有效密码位数-1操作之外,还需将键值value赋值为无效值NONE;
- 若没有将value值赋值为无效值,在之后while(1)循环执行MatrixKey(&value,×),没有键入值之前,使每次循环都进入if(value == 10)判断语句,执行删除操作,输出"X",最终导致LCD屏幕全屏输出“X”,而出错
|