用51单片机和at24c02储存密码的密码锁,密码对比程序怎么写,C语言

2024-11-24 21:43:19
推荐回答(3个)
回答1:

#include
#include
#define uchar unsigned char
#define uint unsigned int
#define No_key 20 //定义无按键时的默认值
#define KEY P3 //定义按键输入口
uchar m=0; //定义密码删除次数//输入新密码用
#define lcddata P0 //定义液晶数据入口
uchar data save[6]; //定义用户输入密码保存数组
sbit lcden= P3^4; //定义液晶使能端
sbit lcdrs= P3^5; //液晶数据 指令信号转换端口
sbit dula=P2^6; //定义段选
sbit wei=P2^7; //定义位选
unsigned char yinyue=0;
uchar password[]={2,2,2,2,2,2} ; //定义初始密码
uchar code table[]= " Hello! ";
uchar code table1[]=" OK! ";
uchar code table2[]="Enter please";
uchar code table3[]="word wrong ";
uchar code table4[]="old word! ";
uchar code table5[]="new word! ";
uchar wrong=0;
sbit Beep = P2^3 ;
/*void delayms(unsigned char a) //豪秒延时子程序
{
while(--a); //采用while(--a) 不要采用while(a--); 各位可编译一下看看汇编结果就知道了!
}
void ydelay (unsigned char m) //控制频率延时
{
unsigned i=3*m;
while(--i);
}
unsigned char yn=0; //n为节拍常数变量
unsigned char yp,ym; //m为频率常数变量
unsigned char code music_tab[] ={
0x18, 0x30, 0x1C , 0x10, //格式为: 频率常数, 节拍常数, 频率常数, 节拍常数,
0x20, 0x40, 0x1C , 0x10,
0x18, 0x10, 0x20 , 0x10,
0x1C, 0x10, 0x18 , 0x40,
0x1C, 0x20, 0x20 , 0x20,
0x1C, 0x20, 0x18 , 0x20,
0x20, 0x80, 0xFF , 0x20,
0x30, 0x1C, 0x10 , 0x18,
0x20, 0x15, 0x20 , 0x1C,
0x20, 0x20, 0x20 , 0x26,
0x40, 0x20, 0x20 , 0x2B,
0x20, 0x26, 0x20 , 0x20,
0x20, 0x30, 0x80 , 0xFF,
0x20, 0x20, 0x1C , 0x10,
0x18, 0x10, 0x20 , 0x20,
0x26, 0x20, 0x2B , 0x20,
0x30, 0x20, 0x2B , 0x40,
0x20, 0x20, 0x1C , 0x10,
0x18, 0x10, 0x20 , 0x20,
0x26, 0x20, 0x2B , 0x20,
0x30, 0x20, 0x2B , 0x40,
0x20, 0x30, 0x1C , 0x10,
0x18, 0x20, 0x15 , 0x20,
0x1C, 0x20, 0x20 , 0x20,
0x26, 0x40, 0x20 , 0x20,
0x2B, 0x20, 0x26 , 0x20,
0x20, 0x20, 0x30 , 0x80,
0x20, 0x30, 0x1C , 0x10,
0x20, 0x10, 0x1C , 0x10,
0x20, 0x20, 0x26 , 0x20,
0x2B, 0x20, 0x30 , 0x20,
0x2B, 0x40, 0x20 , 0x15,
0x1F, 0x05, 0x20 , 0x10,
0x1C, 0x10, 0x20 , 0x20,
0x26, 0x20, 0x2B , 0x20,
0x30, 0x20, 0x2B , 0x40,
0x20, 0x30, 0x1C , 0x10,
0x18, 0x20, 0x15 , 0x20,
0x1C, 0x20, 0x20 , 0x20,
0x26, 0x40, 0x20 , 0x20,
0x2B, 0x20, 0x26 , 0x20,
0x20, 0x20, 0x30 , 0x30,
0x20, 0x30, 0x1C , 0x10,
0x18, 0x40, 0x1C , 0x20,
0x20, 0x20, 0x26 , 0x40,
0x13, 0x60, 0x18 , 0x20,
0x15, 0x40, 0x13 , 0x40,
0x18, 0x80, 0x00
};
*/
uchar temp,flag=0,conflag;//定义temp做为键盘检测 flag做密码标志
uchar k,xiugai; //k为密码计数标志
uchar j=0 ; //用户输入次数统计
sbit a=P1^0; //闪光端
char liang=1; //闪光次数控制量
void display_enter();
void reset();
void enter_code(uchar t);
uchar changepassword ();
void confirm();
void delete() ;
void change_code(uchar t);
void delay(uint z) //延时函数,z的取值为这个函数的延时ms数,如delay(200);大约延时200ms.
{ //delay(500);大约延时500ms.
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
/*void InitTimer0(void) //闪光定时器
{
TMOD = 0x01;
TH0 = 0x0D8;
TL0 = 0x0F0;
EA = 1;
ET0 = 1;
TR0 = 1;
}
void InitTimer1(void)
{
TMOD = 0x10;
TH1 = 0x0FF;
TL1 = 0x9C;
EA = 1;
ET1 = 1;
TR1 = 1;
}
void shanguang()
{
a=0;
delay(500);
a=1;
delay(500);
} */
/******1602写入指令************/
void wright_com(uchar com)
{
lcdrs=0;
lcddata=com;
delay(1);
lcden=1;
delay(1);
lcden=0;
}
/******1602写入数据***********/
void wright_data(uchar date)
{
lcdrs=1;
lcddata=date;
delay(1);
lcden=1;
delay(1);
lcden=0;
}
/**********4x4矩阵键盘扫描函数*********/
uchar keyscan()
{
uchar temp,num=No_key; //num的初值要为无键盘按下时的返回值
/*********扫描第一行****************/
KEY=0xfe;
temp=KEY;
temp=temp&0xf0; //读出高四位
while(temp!=0xf0)
{

delay(10); //延时消抖
temp=KEY;
temp=temp&0xf0;
while(temp!=0xf0) //确认确实有按键按下
{

temp=KEY;
switch(temp) //根据这八个电平可以确定是哪个按键按下
{
case 0xee:num=1;
break;
case 0xde:num=2;
break;
case 0xbe:num=3;
break;
case 0x7e:num=10;
break;
}
while(temp!=0xf0) //等待松手
{
temp=KEY;
temp=temp&0xf0;
}

}
}
/*********扫描第二行***************/
KEY=0xfd;
temp=KEY;
temp=temp&0xf0;
while(temp!=0xf0)
{
delay(15);
temp=KEY;
temp=temp&0xf0;
while(temp!=0xf0)
{

temp=KEY;
switch(temp)
{
case 0xed:num=4;
break;
case 0xdd:num=5;
break;
case 0xbd:num=6;
break;
case 0x7d:num=11;
break;
}
while(temp!=0xf0)
{
temp=KEY;
temp=temp&0xf0;
}

}
}
/*********扫描第三行****************/
KEY=0xfb;
temp=KEY;
temp=temp&0xf0;
while(temp!=0xf0)
{
delay(10);
temp=KEY;
temp=temp&0xf0;
while(temp!=0xf0)
{
temp=KEY;
switch(temp)
{
case 0xeb:num=7;
break;
case 0xdb:num=8 ;
break;
case 0xbb:num=9;
break;
case 0x7b:num=12;
break;
}
while(temp!=0xf0)
{
temp=KEY;
temp=temp&0xf0;
}

}
}
/*********扫描第四行****************/
KEY=0xf7;
temp=KEY;
temp=temp&0xf0;
while(temp!=0xf0)
{
delay(10);
temp=KEY;
temp=temp&0xf0;
while(temp!=0xf0)
{
temp=KEY;
switch(temp)
{
case 0xe7:num=0;
break;
case 0xd7:num=13;
break;
case 0xb7:num=14;
break;
case 0x77:num=15;
break;
}
while(temp!=0xf0)
{
temp=KEY;
temp=temp&0xf0;
}

}
}

return num;
}
void display_OK()
{
uchar num;
wright_com(0x80);
for(num=0;num<12;num++)
{

wright_data(table1[num]);
}
}
void display_fired()
{
uchar num;
wright_com(0x80);
for(num=0;num<12;num++)
{

wright_data(table3[num]);
wrong++;
if(wrong==2)
{
Beep=0;
while(1) //进行键盘扫描
{
temp=keyscan();
if(temp!=No_key)//如果不是空值
{ if(temp==11) //是否是密码删除键
{
delete();
}
enter_code(temp); //将该密码保存
if(temp==12) //如果是确认键
{
confirm();// 对比密码 判断是否正确
if(conflag==1) //密码正确
{
Beep=1;}}}}

}
}
}
void display_hello()
{
uchar num;
wright_com(0x80);
for(num=0;num<12;num++)
{

wright_data(table[num]);
}
}
void display_old()
{
uchar num;
wright_com(0x80);
for(num=0;num<12;num++)
{

wright_data(table4[num]);
}
}
void display_new()
{
uchar num;
wright_com(0x80);
for(num=0;num<12;num++)
{

wright_data(table5[num]);
}
}
void init()
{
uchar num;
/****1602初始化******/
dula=0;
wei=0;//这个必须要置 零,否则无法正常显示
lcden=0;
wright_com(0x38) ; //初始化
wright_com(0x0c) ; //打开光标 0x0c不显示光标 0x0e光标不闪,0x0f光标闪
wright_com(0x01) ; //清显示
wright_com(0x01) ; //清显示
wright_com(0x80) ;
for(num=0;num<7;num++)
{
wright_data(table[num]);
delay(1);
}
}
void main()
{
//InitTimer0();
init();
while(1)
{
temp=keyscan();
if(temp!=No_key)
{
if(temp==10) //判断是否是密码输入键重新输入键
{
reset();
flag=1;
}
if(flag==1)
{
enter_code(temp);
}
if(temp==11) //是否是密码删除键
{
delete();
}
if(temp==12) //判断是否是密码确认键
{
confirm();
if(conflag==1)
{
display_OK();//开锁 //是否按下密码修改改键
}
if(conflag==0) //显示密码错误
{
display_fired();
}
}
if(temp==15)
{
changepassword();
}
}
}
}
void reset()
{
uchar num;
wright_com(0x01) ;
display_enter();
wright_com(0x80+0x40); //擦除屏幕上的显示
for(num=0;num<6;num++)
{
save[num]=0; //对输入的数值进行清零
wright_data(' '); //显示的是空格
}
wright_com(0x80+0x40); //下次再输入时可以又从起始位置输入 //各种变量要清零回起始状态
flag=0;
conflag=0; //标志位没分开 大bug
j=0;
}
void enter_code(uchar t)
{

if(t>=0&&t<10)
{

if(j==0)
{
wright_com(0x80+0x40) ; //第一输入时要先写入地址指令,否则无法显示
wright_data('*') ;
}
else
{
wright_data('*') ;//不是第一个输入则不用再写地址
}
save[j++]=t; //保存输入的数据
}
}
void confirm()
{
uchar k;
for(k=0;k<6;k++)
{
if(password[k]!=save[k]) //对数组中的内容进行逐一比较,一旦有数据不对马上退出循环
{
break;
}
}
if(k==6) //要是条件退出的话说明六个数全对密码
{
conflag=1; // 进行标志密码正确
}

}
/****** 删除最后一个********/
void delete()
{ if(j>0)
{
wright_com(0x80+0x40+j-1); //确定删除对象
wright_data(' '); //显示空格即为删除
save[--j]=0;
//删除后数据清零
wright_com(0x80+0x40+j); //为下次输入数据时写好位置,必须是在最后一个后面
}
}
void Timer0Interrupt(void) interrupt 1
{ TR0=0;
if(P1==0x8f)
{
a=0;
TR0 = 1; //关定时器1
}

}
/****** 显示enter********/
void display_enter()
{
uchar num;
wright_com(0x80);
for(num=0;num<12;num++)
{
wright_data(table2[num]);
}
}
uchar changepassword () //定义修改密码函数
{
display_old(); //显示 old word
while(1) //进行键盘扫描
{ if(P3==0x1f) //无线检测模块
{
P1=0x00;
}
if(P3==0x2f)
{
P1=0x00;
Beep=0;}
temp=keyscan();
if(temp!=No_key)//如果不是空值
{ if(temp==11) //是否是密码删除键
{
delete();
}
enter_code(temp); //将该密码保存
if(temp==12) //如果是确认键
{
confirm();// 对比密码 判断是否正确
if(conflag==1) //密码正确
{
display_new();// 显示新密码
for(m=0;m<6;m++)
delete();
k=0;
while(1) //扫描键盘
{ temp=keyscan();
if(temp!=No_key) //如果不是空
if(temp==11) //是否是密码删除键
{
delete();
}
change_code(temp); //将按键保存 放进password
if(temp>=0&&temp<10)
k++;

if(k==6)
{ display_OK();//显示修改成功
for(m=0;m<6;m++)
delete();
delay(500);
display_hello();
flag=0;
return 0;
}
}
}
else
display_fired();
return 0;
}
}
}
}
void change_code(uchar t)
{
if(t>=0&&t<10)
{

if(j==0)
{
wright_com(0x80+0x40) ; //第一输入时要先写入地址指令,否则无法显示
wright_data('*') ;
}
else
{
wright_data('*') ;//不是第一个输入则不用再写地址
}
password[j++]=t; //保存输入的数据
}
}
/*void Timer1Interrupt(void) interrupt 3
{
TH0=0xd8;
TL0=0xef;
yn--;

} */
没有iic结构 你自己加就好

回答2:

党规党法

回答3:

你既然存进去了 那就读出来 和现在输入的密码核对一下不就行了