51单片机 AT89S52 矩阵按键密码锁 密码可修改程序
时间: 2023-07-06 22:41:27 浏览: 271
好的,这是一个关于51单片机AT89S52矩阵按键密码锁密码可修改程序的问题。为了回答这个问题,我需要先了解一下这个密码锁的工作原理和密码修改的流程。
该密码锁使用AT89S52单片机控制,矩阵按键输入密码,密码正确则开启锁。密码可以通过修改程序进行更改。
密码锁主要有以下几个模块:
1. 按键扫描模块:使用矩阵按键进行密码输入。
2. 密码验证模块:将输入的密码与预设密码进行对比,密码正确则开启锁。
3. LCD显示模块:显示密码输入和开锁状态。
4. 修改密码模块:通过按键输入进入修改密码模式,将新密码存入EEPROM中。
密码修改的流程如下:
1. 在密码锁关闭状态下,按下修改密码按键。
2. 在LCD上输入原密码,按下确认键。
3. 在LCD上输入新密码,按下确认键。
4. 在LCD上再次输入新密码,按下确认键。
5. 新密码存入EEPROM中,LCD显示密码修改成功。
关于具体的代码实现,我可以提供一些参考:
```
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
uchar code pwd[] = "123456"; // 初始密码
uchar code addr[] = {0x00, 0x01, 0x02}; // 存储密码的EEPROM地址
uchar pwd_input[6]; // 输入的密码
uchar pwd_index = 0; // 输入密码的下标
bit pwd_flag = 0; // 密码正确标志位
sbit RS = P2^6; // LCD1602的RS引脚
sbit RW = P2^5; // LCD1602的RW引脚
sbit EN = P2^7; // LCD1602的EN引脚
void delay(uint i) // 延时函数
{
uint j;
for(j = 0; j < i; j++);
}
void lcd_init() // 初始化LCD1602
{
RW = 0;
EN = 0;
delay(15);
P0 = 0x38; // 设置8位数据总线,2行显示,5*7点阵字符
EN = 1;
delay(5);
EN = 0;
delay(5);
P0 = 0x0c; // 显示开,光标关,不闪烁
EN = 1;
delay(5);
EN = 0;
delay(5);
P0 = 0x06; // 光标右移,字符不移动
EN = 1;
delay(5);
EN = 0;
delay(5);
P0 = 0x01; // 清屏
EN = 1;
delay(5);
EN = 0;
}
void lcd_write_com(uchar com) // 写指令函数
{
RS = 0;
EN = 0;
delay(5);
P0 = com;
EN = 1;
delay(5);
EN = 0;
}
void lcd_write_data(uchar dat) // 写数据函数
{
RS = 1;
EN = 0;
delay(5);
P0 = dat;
EN = 1;
delay(5);
EN = 0;
}
void lcd_write_string(uchar *s) // 写字符串函数
{
while(*s)
{
lcd_write_data(*s++);
}
}
void lcd_set_cursor(uchar x, uchar y) // 设置光标位置函数
{
uchar addr;
if(y == 0)
{
addr = 0x80 + x;
}
else
{
addr = 0xc0 + x;
}
lcd_write_com(addr);
}
void lcd_clear() // 清屏函数
{
lcd_write_com(0x01);
delay(5);
}
void key_scan() interrupt 0 // 按键扫描中断函数
{
uchar i, j, k;
uchar key_buf[4] = {0xee, 0xde, 0xbe, 0x7e}; // 矩阵按键的值
for(i = 0; i < 4; i++)
{
P1 = key_buf[i];
k = P1;
k = ~k;
for(j = 0; j < 4; j++)
{
if((k & 0x01) == 0)
{
delay(5);
if((k & 0x01) == 0)
{
pwd_input[pwd_index++] = i * 4 + j + 1;
lcd_write_data('*');
if(pwd_index == 6)
{
pwd_index = 0;
if(strcmp(pwd_input, pwd) == 0)
{
pwd_flag = 1;
lcd_clear();
lcd_set_cursor(0, 0);
lcd_write_string("Password Correct");
delay(1000);
lcd_clear();
lcd_set_cursor(0, 0);
lcd_write_string("Press # to Modify");
}
else
{
lcd_clear();
lcd_set_cursor(0, 0);
lcd_write_string("Password Error");
delay(1000);
lcd_clear();
lcd_set_cursor(0, 0);
lcd_write_string("Please Enter Again");
}
}
}
}
k >>= 1;
}
}
}
void main()
{
uchar i, c, pwd_temp[6];
lcd_init();
lcd_set_cursor(0, 0);
lcd_write_string("Please Enter Pwd:");
lcd_set_cursor(0, 1);
IE = 0x81; // 开启中断
while(1)
{
if(pwd_flag)
{
c = getchar();
if(c == '#')
{
pwd_flag = 0;
lcd_clear();
lcd_set_cursor(0, 0);
lcd_write_string("Enter Old Pwd:");
for(i = 0; i < 6; i++)
{
while(pwd_index == 0);
pwd_temp[i] = pwd_input[pwd_index - 1];
lcd_write_data('*');
pwd_index = 0;
}
if(strcmp(pwd_temp, pwd) == 0)
{
lcd_clear();
lcd_set_cursor(0, 0);
lcd_write_string("Enter New Pwd:");
for(i = 0; i < 6; i++)
{
while(pwd_index == 0);
pwd[i] = pwd_input[pwd_index - 1];
lcd_write_data('*');
pwd_index = 0;
}
for(i = 0; i < 6; i++)
{
c = pwd[i];
EA = 0;
while(1)
{
if(WR == 1)
{
WR = 0;
break;
}
}
P0 = c;
ADDR = addr[i];
EN = 1;
EN = 0;
EA = 1;
delay(5);
}
lcd_clear();
lcd_set_cursor(0, 0);
lcd_write_string("Modify Pwd Success");
}
else
{
lcd_clear();
lcd_set_cursor(0, 0);
lcd_write_string("Old Pwd Error");
pwd_flag = 1;
}
delay(1000);
lcd_clear();
lcd_set_cursor(0, 0);
lcd_write_string("Please Enter Pwd:");
lcd_set_cursor(0, 1);
}
}
}
}
```
这是一个基本的代码框架,具体实现需要根据实际情况进行调整。另外,需要注意保护好密码的安全,避免泄露。
阅读全文