標(biāo)題: 電子鎖相關(guān)提問(wèn) [打印本頁(yè)]
作者: 玄佑 時(shí)間: 2017-4-28 14:38
標(biāo)題: 電子鎖相關(guān)提問(wèn)
這是網(wǎng)上找的一個(gè)電子鎖程序,自己進(jìn)行仿真了,但是輸入密碼環(huán)節(jié)不知道初始密碼,也好像沒(méi)法設(shè)定初始密碼,有沒(méi)有大神可以幫我看一下,是不是程序問(wèn)題,還是我自己沒(méi)搞懂?
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit lcden=P1^2;
sbit lcdrs=P1^0;
sbit lcdrw=P1^1;
sbit p17=P1^7; //開(kāi)門指示:指示燈和蜂鳴器
uchar table1[8]={'N','A','M','E',':'}; //定義數(shù)碼管的第一行"name: "
uchar table2[8]={'C','O','D','E',':'}; //定義數(shù)碼管的第二行"lode: "
uchar name[10]={'0','1','2','3'};
uchar cod[20]={'0','0','0','0','1','1','1','1','2','2','2','2','3','3','3','3'}; //定義四個(gè)用戶,并設(shè)置對(duì)應(yīng)的用戶和密碼,
//其中用戶0定義為超級(jí)用戶0,用戶1、用戶2和用戶3為普通用戶
uint in_name; //保存輸入的用戶名
uint error_num; //輸入密碼錯(cuò)誤的次數(shù)
uchar in_code1[4]; //保存第一次輸入的密碼
uchar in_code2[4]; //保存第二次輸入的密碼
uchar code sup[11]={'S','U','P','E','R',' ','U','S','E','R','!'}; //輸入用戶為超級(jí)用戶
uchar code nor[12]={'N','O','R','M','A','L',' ','U','S','E','R','!'}; //輸入用戶為普通用戶
uchar code err[6]={'E','R','R','O','R','!'}; //輸入用戶名或密碼錯(cuò)誤
uchar wait[8]={'W','A','I','T','I','N','G','!'}; //等待
uchar aga[11]={'I','N','P','U','T',' ','A','G','A','I','N'}; //再次輸入密碼
uchar ame[9]={'A','M','E','N','D','I','N','G','!'}; //正在修改密碼
uchar fun[6]={'a','b','c','d','e','f'}; //ABCDEF功能鍵
//====================延時(shí)函數(shù)======================//
void delay(uint x)
{
uint a,b;
for(a=x;a>0;a--)
for(b=110;b>0;b--);
}
//=================1602寫(xiě)指令===============//
void write_com(uchar com)
{
lcdrs=0;
P0=com;
delay(10);
lcden=1;
delay(10);
lcden=0;
}
//==============1602寫(xiě)數(shù)據(jù)================//
void write_data(uchar dat)
{
lcdrs=1;
P0=dat;
delay(10);
lcden=1;
delay(10);
lcden=0;
}
//===============1602在指定的位置顯示一個(gè)字符=============//
void disp_char(uchar x,uchar y,uchar dat)
{
uint i;
uchar addr;
if(y==1)
addr=0x80+x;
else
addr=0xc0+x;
write_com(addr);
for(i=0;i<2;i++);
write_data(dat);
for(i=0;i<2;i++);
}
//==================1602數(shù)碼管初始化函數(shù)==================//
void display()
{
lcden=0;
lcdrw=0;
write_com(0x38);
write_com(0x0c);
write_com(0x06);
write_com(0x01);
write_com(0x80);
}
//=============4*4鍵盤掃描函數(shù)=================//
uint keyscan()
{
uchar temp;
uint key=16; //key=16表示沒(méi)有按下任何鍵
P2=0xfe; //第一行被置為低電平,開(kāi)始掃描第一行
temp=P2;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(1);
temp=P2;
temp=temp&0xf0;
if(temp!=0xf0)
{
temp=P2;
switch(temp)
{
case(0xee):
key=0;
break;
case(0xde):
key=1;
break;
case(0xbe):
key=2;
break;
case(0x7e):
key=3;
break;
}
while(temp!=0xf0) //等待按鍵釋放
{
temp=P2;
temp=temp&0xf0;
}
}
}
///////////////////////////////////////////
P2=0xfd; //第二行被置為低電平,開(kāi)始掃描第二行
temp=P2;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(1);
temp=P2;
temp=temp&0xf0;
if(temp!=0xf0)
{
temp=P2;
switch(temp)
{
case(0xed):
key=4;
break;
case(0xdd):
key=5;
break;
case(0xbd):
key=6;
break;
case(0x7d):
key=7;
break;
}
while(temp!=0xf0) //等待按鍵釋放
{
temp=P2;
temp=temp&0xf0;
}
}
}
////////////////////////////////////////
P2=0xfb; //第三行被置為低電平,開(kāi)始掃描第三行
temp=P2;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(1);
temp=P2;
temp=temp&0xf0;
if(temp!=0xf0)
{
temp=P2;
switch(temp)
{
case(0xeb):
key=8;
break;
case(0xdb):
key=9;
break;
case(0xbb):
key=10;
break;
case(0x7b):
key=11;
break;
}
while(temp!=0xf0) //等待按鍵釋放
{
temp=P2;
temp=temp&0xf0;
}
}
}
//////////////////////////////////////////////
P2=0xf7; //第四行被置為低電平,開(kāi)始掃描第四行
temp=P2;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(1);
temp=P2;
temp=temp&0xf0;
if(temp!=0xf0)
{
temp=P2;
switch(temp)
{
case(0xe7):
key=12;
break;
case(0xd7):
key=13;
break;
case(0xb7):
key=14;
break;
case(0x77):
key=15;
break;
}
while(temp!=0xf0) //等待按鍵釋放
{
temp=P2;
temp=temp&0xf0;
}
}
}
return(key);
}
/*/---------------B鍵的功能,刪除用戶--------------------//
void delete_user()
{
;
}
//--------------D鍵的功能,添加用戶----------------------//
void add_user()
{
;
} */
//----------------E鍵的功能,修改密碼-------------//
void amend_code()
{
uint i,j,k=16;
display();
for(i=0;i<5;i++)
disp_char(i,1,table1); //第一行顯示NAME:及對(duì)應(yīng)的用戶名
disp_char(5,1,name[in_name]);
for(i=0;i<5;i++)
disp_char(i,2,table2); //第二行顯示CODE:AMENDING!
for(i=0;i<9;i++)
disp_char(i+5,2,ame);
for(j=0;j<4;j++)
{k=keyscan();
while(k==16)
k=keyscan();
cod[in_name*4+i]=fun[k-10];
}
}
//================F鍵的功能,開(kāi)門,蜂鳴器間斷響================//
void open_door()
{
uint i,j;
for(i=0;i<6;i++)
for(j=0;j<10000;j++)
{
if((j/5000)%2==0)
p17=1;
else
p17=0;
}
p17=0;
}
//===================超級(jí)用戶相關(guān)操作======================//
void super_user()
{
uint k=16;
uint flag=0;
while(flag==0)
{
k=keyscan();
while(!(k==10||k==11||k==13||k==14||k==15)) //當(dāng)A、B、D、E、F均未被按下時(shí),繼續(xù)掃描
k=keyscan();
if(k==10) // 當(dāng)A鍵被按下時(shí),返回
flag=1;
if(k==11) // 當(dāng)B鍵被按下時(shí),刪除用戶
{
flag=1;
// delete_user();
}
if(k==13) // 當(dāng)D鍵被按下時(shí),添加用戶
{
flag=1;
// add_user();
}
if(k==14) // 當(dāng)E鍵被按下時(shí),修改密碼
{
flag=1;
amend_code();
}
if(k==15) // 當(dāng)F鍵被按下時(shí),開(kāi)門
{
flag=1;
open_door();
}
}
delay(6000);
}
//===================普通用戶相關(guān)操作:改密、開(kāi)門========================//
void normal_user()
{
uint k=16;
uint flag=0;
while(flag==0)
{
k=keyscan();
while(!(k==14||k==15)) //當(dāng)沒(méi)有按下E、F鍵時(shí),繼續(xù)掃描
k=keyscan();
if(k==14); //對(duì)應(yīng)于E鍵
{
flag=1; //普通用戶完成一項(xiàng)操作
amend_code(); //修改當(dāng)前用戶的密碼
}
if(k==15)
{
flag=1; //普通用戶完成一項(xiàng)操作
open_door(); //F鍵的功能,開(kāi)門
}
}
delay(6000);
}
//=================第二次輸入密碼函數(shù)====================//
void input_code2()
{
uint i,j,flag2=0;
uint k2=16;
error_num=0;
while(flag2==0&&error_num<3)
{
for(i=0;i<4;i++) //輸入4位數(shù)密碼,保存在in_code2中
{
k2=keyscan();
while(k2==16)
k2=keyscan();
in_code2=fun[k2-10];
display();
for(j=0;j<5;j++)
disp_char(j,1,table1[j]); //第一行顯示NAME:及對(duì)應(yīng)的用戶名
disp_char(5,1,name[in_name]);
for(j=0;j<5;j++)
disp_char(j,2,table2[j]); //第二行先后顯示CODE:*,CODE:**,CODE:***,CODE:****
for(j=0;j<i+1;j++)
disp_char(5+j,2,'*');
delay(10);
}
delay(10);
//------檢驗(yàn)輸入的密碼是否與第一次輸入的密碼一致-------//
if(in_code2[0]==in_code1[0]&&in_code2[1]==in_code1[1]&&in_code2[2]==in_code1[2]&&in_code2[3]==in_code1[3])
{
flag2=1; //輸入密碼正確,退出while循環(huán)
p17=1; //指示燈亮,蜂鳴器響,表示密碼正確
delay(400);
p17=0;
}
else
{
flag2=0; //輸入密碼錯(cuò)誤重新輸入
error_num++;
display();
for(j=0;j<5;j++) //第一行顯示NAME:及對(duì)應(yīng)的用戶名
disp_char(j,1,table1[j]);
disp_char(5,1,name[in_name]);
for(j=0;j<5;j++) //第二行顯示CODE:ERROR!2
disp_char(j,2,table2[j]);
for(j=0;j<6;j++)
disp_char(j+5,2,err[j]);
disp_char(11,2,'2');
delay(10);
}
}
}
//=================第一次輸入密碼函數(shù)====================//
void input_code1()
{
uint i,j,n,flag1=0,k1=16;
error_num=0;
while(flag1==0&&error_num<3)
{
for(i=0;i<4;i++) //輸入4位數(shù)密碼,保存在in_code1中
{
k1=16;
k1=keyscan();
while(k1==16)
k1=keyscan();
in_code1=fun[k1-10];
display();
for(j=0;j<5;j++)
disp_char(j,1,table1[j]); //第一行顯示NAME:及對(duì)應(yīng)的用戶名
disp_char(5,1,name[in_name]);
for(j=0;j<5;j++)
disp_char(j,2,table2[j]); //第二行先后顯示CODE:*,CODE:**,CODE:***,CODE:****
for(n=0;n<i+1;n++)
disp_char(5+n,2,'*');
delay(10);
}
delay(600);
//-------------檢驗(yàn)輸入的密碼是否正確---------//
if(in_code1[0]==cod[in_name*4+0]&&in_code1[1]==cod[in_name*4+1]&&in_code1[2]==cod[in_name*4+2]&&in_code1[3]==cod[in_name*4+3])
{
flag1=1; //輸入密碼正確,退出wlile循環(huán),等待第二次輸入密碼
display();
for(j=0;j<5;j++)
disp_char(j,1,table1[j]); //第一行顯示NAME:及對(duì)應(yīng)的用戶名
disp_char(5,1,name[in_name]);
for(j=0;j<5;j++)
disp_char(j,2,table2[j]); //第二行顯示CODE:INPUT AGAIN
for(j=0;j<11;j++)
disp_char(j+5,2,aga[j]); //INPUT AGAIN
delay(10);
p17=0; //指示燈亮,蜂鳴器響,表示密碼正確
delay(400);
p17=1;
}
else
{
flag1=0; //輸入密碼錯(cuò)誤重新輸入
error_num++;
display();
for(j=0;j<5;j++) //第一行顯示NAME:及對(duì)應(yīng)的用戶名
disp_char(j,1,table1[j]);
disp_char(5,1,name[in_name]);
for(j=0;j<5;j++) //第二行顯示CODE:ERROR!1
disp_char(j,2,table2[j]);
for(j=0;j<6;j++)
disp_char(j+5,2,err[j]);
disp_char(11,2,'1');
delay(100);
}
}
}
//=================輸入用戶名函數(shù)===================//
void input_name()
{
uint j,flag0=0,error_num=0;
uint k0=16;
while(flag0==0)
{
k0=keyscan();
while(k0==16) //k0=16表示未輸入用戶名
k0=keyscan();
//-----------------------------//
if(k0>=0&&k0<4) //輸入為用戶0、用戶1、用戶2、用戶3
{
flag0=1; //flag=1表示輸入一個(gè)正確的用戶
in_name=k0; //記下所輸入的正確用戶的序號(hào)
display();
for(j=0;j<5;j++) //第一行顯示NAME:及輸入的用戶
disp_char(j,1,table1[j]);
disp_char(5,1,k0);
for(j=0;j<5;j++) //第二行顯示CODE:
disp_char(j,2,table2[j]);
delay(10);
p17=0; //指示燈亮,蜂鳴器響,表示用戶名正確
delay(400);
p17=1;
}
//-------------------------------//
if((k0>=4&&k0<=15)) //輸入的用戶錯(cuò)誤
{
flag0=0;
error_num++;
display();
for(j=0;j<5;j++) //第一行顯示NAME:ERROR!
disp_char(j,1,table1[j]);
disp_char(5,1,fun[k0-10]);
for(j=0;j<6;j++)
disp_char(j+7,1,err[j]);
for(j=0;j<5;j++) //第二行顯示CODE:
disp_char(j,2,table2[j]);
delay(10);
}
}
}
void init()
{
uint m;
p17=0;
display(); //等待輸入用戶名
for(m=0;m<5;m++)
disp_char(m,1,table1[m]);
for(m=0;m<8;m++)
disp_char(m+7,1,wait[m]);
for(m=0;m<5;m++) //第二行顯示CODE:
disp_char(m,2,table2[m]);
delay(10);
}
//====================主函數(shù)=====================//
void main()
{
uint m;
init();
while(1)
{
input_name(); //進(jìn)入用戶名輸入函數(shù)
input_code1(); //用戶名正確,接下來(lái)第一次輸入密碼
if(error_num<3)
{
input_code2(); //第一次輸入密碼正確,第二次輸入密碼
if(error_num<3)
{
if(in_name==0)
{
// display();
for(m=0;m<5;m++) //第一行顯示NAME:及對(duì)應(yīng)的用戶名
disp_char(m,1,table1[m]);
disp_char(5,1,name[in_name]);
for(m=0;m<11;m++) //第二行顯示輸入用戶為超級(jí)用戶
disp_char(m,2,sup[m]);
delay(10);
super_user(); //進(jìn)入超級(jí)用戶相關(guān)操作
}
else
{
// display();
for(m=0;m<5;m++) //第一行顯示NAME:及對(duì)應(yīng)的用戶名
disp_char(m,1,table1[m]);
disp_char(5,1,name[in_name]);
for(m=0;m<12;m++) //第二行顯示輸入用戶為普通用戶
disp_char(m,2,nor[m]);
delay(10);
normal_user(); //進(jìn)入普通用戶相關(guān)操作
}
}
}
delay(500);
}
}
作者: zl2168 時(shí)間: 2017-4-28 21:52
本帖最后由 zl2168 于 2017-4-29 11:03 編輯
網(wǎng)上亂七八糟的,大都有bug,看看我給你推薦的。
功能齊全的電子密碼鎖
⑴ 電路設(shè)計(jì) …
電子密碼鎖電路.jpg (98.1 KB, 下載次數(shù): 77)
下載附件
2017-4-28 22:47 上傳
⑵ 功能設(shè)計(jì) …
電子密碼鎖功能1.jpg (171.96 KB, 下載次數(shù): 95)
下載附件
2017-4-28 22:47 上傳
電子密碼鎖功能2.jpg (181.75 KB, 下載次數(shù): 78)
下載附件
2017-4-28 22:47 上傳
電子密碼鎖功能3.jpg (192.6 KB, 下載次數(shù): 72)
下載附件
2017-4-28 22:47 上傳
⑶ 程序設(shè)計(jì) …
電子密碼鎖流程圖.jpg (147.99 KB, 下載次數(shù): 84)
下載附件
2017-4-28 22:47 上傳
⑷ Proteus仿真 …
先Proteus仿真一下,確認(rèn)有效,驗(yàn)證上述功能。
電子密碼鎖1.rar
(1.13 MB, 下載次數(shù): 12)
2017-4-28 22:49 上傳
點(diǎn)擊文件名下載附件
仿真電路和Hex文件能在清華出版社網(wǎng)站免費(fèi)下載,程序源代碼只能到書(shū)上看了。到圖書(shū)館借,或到新華書(shū)店翻閱,或到網(wǎng)上書(shū)店打折購(gòu)買。
以上摘自張志良編著《80C51單片機(jī)實(shí)用教程》ISBN978-7-04-044532-9,高教社出版。書(shū)中電路和程序設(shè)計(jì)有詳細(xì)說(shuō)明,程序語(yǔ)句條條有注解。
歡迎咨詢,zzlls@126.com
| 歡迎光臨 (http://m.raoushi.com/bbs/) |
Powered by Discuz! X3.1 |