高分求完整的单片机密码锁程序...

跪求完整程序代码~~~~!!!!C语言
单片机 机型是 89C52RC
要求:
密码锁:设定好8位数的密码,通过键盘输入8位数,如果正确蜂鸣器响。(扩展:限制n次输入机会,密码可通过键盘修改)
求高人帮我指导一下...1楼的程序要怎么改啊?
最好具体些...有个思路也行啊>_< 拜托啊~
最新回答
绝绝子

2024-07-28 02:19:27

/*变量的定义:
show_val[6]: 显示的值
init_val[6]: 密码初始值
key_val: 返回按键的值 255-表示无按键按下
key_index: 当前按键是哪一位密码
T1_cnt: 定时器计数溢出数
cnt_val_15s: 报启饥弊警计时的数值
cnt_val_5s: 待机时间计时
cnt_val_4s: 输入正确,等待4秒清除开锁信号
cnt_state: 计时状态
error_num: 错误次数
led_seg_code:数码管7段码
*/
#include "reg51.h"
/*说明key0=P1^0; key1=P1^1;key2=P1^2; key3=P1^3;key4=P1^4;key5=P1^5;enter=P1^6;esc=P1^7;*/
sbit relay_open=P3^0; //电磁锁开锁驱动
sbit pw_error=P3^1; //密码错误信号
sbit alarm_out=P3^2; //报警输出
sbit open_lock=P3^3; //已开锁指示信号
sbit audio_out=P3^4; //有源蜂鸣器
unsigned char data cnt_val_15s,cnt_val_5s,cnt_val_4s,cnt_state;
unsigned int data T1_cnt;
unsigned char data key_val,key_index,key_val_old;
unsigned char data state_val,error_num;
unsigned char data show_val[6];
char code init_val[6]={1,2,3,4,5,0};
char code led_seg_code[11]={0x3f,0x06,0x05b,0x04f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00};
//led_seg_code[0-9]代表0-9 led_seg_code[10]=0x00数码管不显示任何内容
//--------延时程序----------------
void delay(unsigned int i)//延时
{ while(--i); }
//--------清除输入内容----------
void init_variant()
{unsigned char i;
for(i=0;i<6;i++)
show_val[i]=10; //led_seg_code[10]=0x00表示数码管不显示任何内容
key_index=0; //没有任何输入或清除所有输入时,保存当前键的位置
}
//---------按键扫描---------------
unsigned char scan_key()
{ unsigned char i,k;
i=P1;
if (i==0xff && cnt_state!=2)
{ k=255; } //无键按下悄族
else //有键按下
{ delay(500); //延时去抖肢铅动
if(i!=P1)
{k=255;}
else
{ TR1=1; //有键按下则开定时器,启动待机计时
cnt_val_5s=0;
switch (i)
{ case 0xfe: k=0; break;
case 0xfd: k=1; break;
case 0xfb: k=2; break;
case 0xf7: k=3; break;
case 0xef: k=4; break;
case 0xdf: k=5; break;
case 0xbf: k=6; break;
case 0x7f: k=7; break;
}
}
}
return k;
}
//---------数码管显示---------------
void led_show()
{P0=led_seg_code[show_val[0]];
P2=0xdf;
delay(500);
P0=led_seg_code[show_val[1]];
P2=0xef;
delay(500);
P0=led_seg_code[show_val[2]];
P2=0xf7;
delay(500);
P0=led_seg_code[show_val[3]];
P2=0xfb;
delay(500);
P0=led_seg_code[show_val[4]];
P2=0xfd;
delay(500);
P0=led_seg_code[show_val[5]];
P2=0xfe;
delay(500);
}
//--------定时器T1中断服务程序-----------------
void timer1() interrupt 3 //T1中断
{ T1_cnt++;
if(T1_cnt>3999) //如果计数>3999, 计时1s
{ T1_cnt=0;
switch (cnt_state)
{ case 0: //待机,需要计时5s
if(cnt_val_5s<5)
{ cnt_val_5s++;}
else
{ cnt_val_5s=0;
init_variant();//待机计时到5秒时,清除输入的内容
TR1=0; //停止计时
}
break;
case 1://密码输入正确,需要计时4s
if(cnt_val_4s<4)
{ cnt_val_4s++;}
else
{ cnt_val_4s=0;
init_variant();//密码输入正确,计时到4秒时,清除输入的内容
open_lock=1; //已开锁信号清零
relay_open=1; //开锁信号清零
cnt_state=0;
TR1=0; //停止计时
}
break;
case 2: //密码输入错误3次,计时15s
if(cnt_val_15s<15)
{ cnt_val_15s++;}
else
{ cnt_val_15s=0;
init_variant();//三次密码错误时,计时15秒,清除输入的内容
open_lock=1; // 清除所有指示和报警
relay_open=1;
alarm_out=1;
pw_error=1;
cnt_state=0;
TR1=0; //停止计时
}
break;
}
}
}
//--------判断键盘输入内容与密码是否一致------
unsigned char check_input_pw()
{ unsigned char i,k;
k=1;
for(i=0;i<6;i++)
{ k=k && (show_val[i]==init_val[i]); }
return k;
}
//---------主程序----------------
main()
{ //初始化各变量
audio_out=1;
P3=0xff;
cnt_val_15s=0;
cnt_val_5s=0;
cnt_val_4s=0;
cnt_state=0;
//0-待机计时5s状态;1-密码正确,计时4s状态 ;2-三次密码错误,处于计时15秒状态。
T1_cnt=0;
error_num=0;
key_val_old=255;
init_variant();
//初始化51的寄存器
TMOD=0x20; //用T1计时 8位自动装载定时模式
TH1=0x19; //500微秒溢出一次; 250=(256-x)*12/11.0592 -> x=19
TL1=0x19;
EA=1; //开中断
ET1=1;
TR1=0; //开定时器T1
while(1)
{ key_val=scan_key(); //按键输入,有键按下key_val为0-7,无键按下key_val为255。
if (key_val!=key_val_old)
{ key_val_old=key_val;
if (key_val!=255&& cnt_state!=2)
{ audio_out=0;
delay(100); //延时去抖动
audio_out=1;
switch (key_val)
{ case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
if(key_index<6) //密码为6位,超过6位视为输入无效
{ show_val[key_index]=key_val;
key_index++; }
break;
case 6: //确认键
if(check_input_pw())
{//密码正确
error_num=0; //密码输入错误次数清零
//---------
pw_error=1; //密码错误指示灯灭
relay_open=0; //开锁驱动信号灯亮
open_lock=0; //已开锁信号灯亮
//---------
delay(50000); //两声短“滴”声
audio_out=0;
delay(50000);
audio_out=1;
delay(50000);
audio_out=0;
delay(50000);
audio_out=1;
//---------
cnt_state=1; //下一状态处于4秒计时的状态
TR0=1; //启动定时
}
else
{ if (error_num<2)
{error_num++; //输入错误次数小于3次时,没错一次error_num增一
pw_error=0; //密码错误指示灯亮
//-----------
delay(20000);//一声长“滴”声,提示错误
audio_out=0;
delay(60000);
audio_out=1;
//-----------
init_variant();//清除所有输入,等待下一次输入
}
else //输入错误次数超过3次
{ alarm_out=0; //报警灯亮
pw_error=0; //密码错误指示灯亮
error_num=0; //密码输入错误次数清零
//----------
audio_out=0; //长鸣声报警
delay(60000);
delay(60000);
delay(60000);
delay(60000);
delay(60000);
delay(60000);
delay(60000);
delay(60000);
delay(60000);
audio_out=1;
//-------------
TR1=1; //打开定时器计时
cnt_state=2; //下一状态处于15秒计时的状态
}
}
break;
case 7://取消键
init_variant();
break;
}
}
}
led_show();
}
}
//-----程序结束-----------------
沉默我的资本の

2024-07-28 04:12:16

看看一楼的程序,钻研吧!
に枯叶蝶的未来

2024-07-28 02:17:59

虽然帮不上忙= = 但是我是来看花花的- -
微浅笑°

2024-07-28 01:30:27

#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
void key_scan();
uchar count0,count1,count3,num,n=0,temp,a,j,count4;
uchar mima[8]; //初始斗埋密码存储区
uchar tab_key[50]; //输入密码存储区
uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
bit enterflag; //确认键按下与否的标志
bit mimaflag; //密码正确与否的标志
bit xiugaiflag; /稿孝/修改密码标志
bit enter1flag; //空敬蚂修改密码确认键标志
sbit red=P3^7;
sbit bell=P3^6;
sbit rs=P2^0;
sbit rw=P2^1;
sbit lcden=P2^2;
sbit scl=P3^4;
sbit sda=P3^5;
uchar code table1[]="input the passco";
uchar code table2[]="de: --------";
uchar code table3[]="*";
uchar code table4[]="right (^_^) ";
uchar code table5[]="first error!!!!";
uchar code table6[]="second error!!!!";
uchar code table7[]="third error see ";
uchar code table8[]="u tomorrow (^_^)";
uchar code table9[]="define the passc";
uchar code table10[]="ode: --------";
uchar code table11[]="code is new";
//******************************键盘消抖函数*******************************
void delay1()
{ ;; }
void delay2(uchar x)
{
uchar a,b;
for(a=x;a>0;a--)
for(b=100;b>0;b--);
}

void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}

//****************************e^2room的初始化*******************************
void start() //开始信号
{
sda=1;
delay1();
scl=1;
delay1();
sda=0;
delay1();
}

void stop() //停止
{
sda=0;
delay1();
scl=1;
delay1();
sda=1;
delay1();
}
//****************************应答信号*************************************
void respond()
{
uchar i;
scl=1;
delay1();
while((sda==1)&&(i<250))i++;
scl=0;
delay1();
}
//*****************************写字节操作函数**********************************
void write_byte(uchar date)
{
uchar i,temp;
temp=date;
for(i=0;i<8;i++)
{
temp=temp<<1; //保持最高位,左移到进位CY
scl=0;
delay1();
sda=CY;
delay1();
scl=1;
delay1();
}
scl=0;
delay1();
sda=1;//总线释放
delay1();
}
//*******************************读字节操作函数*****************************
uchar read_byte()
{
uchar i,k;
scl=0;
delay1();
sda=1;
delay1();
for(i=0;i<8;i++)
{
scl=1;
delay1();
k=(k<<1)|sda; //或运算,放到最低位
scl=0;
delay1();
}
return k;
}
//**********************************写地址函数******************************
void write_add(uchar address,uchar date)
{
start();
write_byte(0xa0);
respond();
write_byte(address);
respond();
write_byte(date);
respond();
stop();
}
//*******************************读地址函数*************************************
uchar read_add(uchar address)
{
uchar date;
start();
write_byte(0xa0);
respond();
write_byte(address);
respond();
start();
write_byte(0xa1);
respond();
date=read_byte();
stop();
return date;
}
//****************************LCD1602的初始化*******************************
void write_com(uchar com)
{
rs=0;
lcden=0;
P0=com;
delay(5);
lcden=1;
delay(5);
lcden=0;
}

void write_date(uchar date)
{
rs=1;
lcden=0;
P0=date;
delay(5);
lcden=1;
delay(5);
lcden=0;
}

//***************************************密码比较函数********************************
bit mimacmp()
{
bit flag;
uchar i;
for(i=0;i<8;i++)
{
if(mima[i]==tab_key[i])
flag=1;
else
{
flag=0;
i=8;
}
}
return(flag); //返回flag
}

////**********************************LCD显示函数开始**************************************
void lcd_display()
{
uchar i=0;
write_com(0x80+0x40+8);
for(i=0;i<n;i++)
{
write_date(table3[0]);
}
}

//****************************************键盘功能分配函数群开始****************************
//** 0 ** 1 **2 ** 3**
//** 4** 5** 6 **7 **
//**8** 9** 确认(A) **无效(B)
//**取消(C)**修改密码键(D)**确认修改键(E)**无效(F)

void key_manage1()
{
tab_key[n]=0;
n++;
if(xiugaiflag==1)
{
mima[count4]=0;
count4++;
}
}

void key_manage2()
{

tab_key[n]=1;
n++;
if(xiugaiflag==1)
{
mima[count4]=1;
count4++;
}
}

void key_manage3()
{

tab_key[n]=2;
n++;
if(xiugaiflag==1)
{
mima[count4]=2;
count4++;
}
}

void key_manage4()
{
tab_key[n]=3;
n++;
if(xiugaiflag==1)
{
mima[count4]=3;
count4++;
}
}

void key_manage5()
{
tab_key[n]=4;
n++;
if(xiugaiflag==1)
{
mima[count4]=4;
count4++;
}
}

void key_manage6()
{
tab_key[n]=5;
n++;
if(xiugaiflag==1)
{
mima[count4]=5;
count4++;
}
}
void key_manage7()
{
tab_key[n]=6;
n++;
if(xiugaiflag==1)
{
mima[count4]=6;
count4++;
}
}
void key_manage8()
{
tab_key[n]=7;
n++;
if(xiugaiflag==1)
{
mima[count4]=7;
count4++;
}
}

void key_manage9()
{
tab_key[n]=8;
n++;
if(xiugaiflag==1)
{
mima[count4]=8;
count4++;
}
}
void key_manage10()
{
tab_key[n]=9;
n++;
if(xiugaiflag==1)
{
mima[count4]=9;
count4++;
}
}
//**********************************确认键**************************************************************
void key_manage11()
{
enterflag=1; //确认键按下
if(n==8) //只有输入8个密码后按确认才做比较
mimaflag=mimacmp();
else
mimaflag=0;
if(enterflag==1)
{
enterflag=0;
n=0;
//用FFFFFFFF清除已经输入的密码
for(count3=0;count3<8;count3++)
{
delay(5);
tab_key[count3]=0x0f;
}

TR1=1; //打开计数器1
count1=0; //定时器1由50MS累计到1S所用的计数器
if(mimaflag==1)
{
a=0;

write_com(0x01);
write_com(0x80);
for(count3=0;count3<16;count3++)
{
write_date(table4[count3]); //密码正确,显示RIGHT,绿灯亮
delay(5);
}
}

else
{
n=0;
red=0;
bell=0;
a++;
if(a==1)
{
for(count3=0;count3<8;count3++) //ffffffff清除密码
{
delay(5);
tab_key[count3]=0x0f;
}
write_com(0x01);
write_com(0x80);
for(count3=0;count3<16;count3++)
{
write_date(table5[count3]); //密码错误,显示 first error,红灯亮
delay(5);
}
TR1=1;
}
if(a==2)
{
for(count3=0;count3<8;count3++) //ffffffff清除密码
{
delay(5);
tab_key[count3]=0x0f;
}
write_com(0x01);
write_com(0x80);
for(count3=0;count3<16;count3++)
{
write_date(table6[count3]); //密码错误,显示SECOND ERROR,红灯亮
delay(5);
}
TR1=1;
}

if(a==3)
{
for(count3=0;count3<8;count3++) //ffffffff清除密码
{
delay(5);
tab_key[count3]=0x0f;
}
write_com(0x01);
write_com(0x80);
for(count3=0;count3<16;count3++)
{
write_date(table7[count3]); //密码错误,显示third error see,红灯亮
delay(5);
}
write_com(0x80+0x40);
for(count3=0;count3<16;count3++)
{
write_date(table8[count3]);//密码错误,显示 U TOMORROW ,红灯亮
delay(5);
}
TR1=0;

}

}
}

}
void key_manage12()
{
tab_key[n]=11;
n++; //密码计数清零

}
//****************************************************取消键********************************************
void key_manage13()
{

n=0; //密码计数清零
write_com(0x80); //指针所指位置
for(count3=0;count3<16;count3++)
{
write_date(table1[count3]); //第一行显示INPUT THE PASSPORD:
delay(5);
}
write_com(0x80+0x40);
for(count3=0;count3<16;count3++)
{
write_date(table2[count3]); //开机显示--------
delay(5);
tab_key[count3]=0x0f; //用FFFFFFFF清楚已经输入的密码
}

}
//*******************************************修改密码键**********************************
void key_manage14()
{
uchar aa=0;
n=0;
xiugaiflag=1;
write_com(0x01);
write_com(0x80);
for(count3=0;count3<16;count3++)
{
write_date(table9[count3]); //显示define the password
delay(5);
tab_key[count3]=0x0f; //用FFFFFFFF清楚已经输入的密码
}
write_com(0x80+0x40);
for(count3=0;count3<16;count3++)
{
write_date(table10[count3]); //显示--------
delay(5);
}
TR0=1;

}
//******************************************修改密码键的确认键********************************
void key_manage15()
{
n=0;
enter1flag=1;
if(enter1flag==1)
{
enter1flag=0;
count4=0;
for(count3=0;count3<16;count3++)
{
tab_key[count3]=0x0f; //用FFFFFFFF清楚已经输入的密码
}
write_com(0x01);
write_com(0x80);
for(count3=0;count3<16;count3++)
{
write_date(table11[count3]);
delay(100);
}
TR1=1;
count1=0;
}
}
void key_manage16()
{
tab_key[n]=15;
n++;
}

//****************************************定时器1的50MS,共延时1秒*****************************
void time_1() interrupt 3
{

TH1=(65536-50000)/256;
TL1=(65536-50000)%256;
if(count1<20)
{
count1++;
}
else //计时到1S
{
TR1=0;
count1=0;
mimaflag=0;

red=1;
bell=1;
//显示FFFFFFFF
write_com(0x01);
write_com(0x80);
for(count3=0;count3<16;count3++)
{
write_date(table1[count3]); //显示INPUT THE PASSCODE
delay(5);
}
write_com(0x80+0x40);
for(count3=0;count3<16;count3++)
{
write_date(table2[count3]); //开机显示FFFFFFFF
delay(5);
}
}

}
//***********************************************定时0**********************************************
void time_0() interrupt 1
{

TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
if(count4<8)
{
key_scan();
}
else
{
TR0=0;
count4=0;
}
}

//初始化函数
void init()
{

uchar i;
lcden=0;
write_com(0x38); //打开显示模式设置
write_com(0x0c); //打开显示,光标等等设置未零
write_com(0x06); //当读或写一个字符后地址指针加一,且光标加一,当写一个字符后整频显示左移,
write_com(0x01); //清零指令
write_com(0x80); //指针所指位置

//定时器初始化
TMOD=0x11; //T0,T1工作方式1
TH0=(65536-2000)/256;
TL0=(65536-2000)%256; //T0初始化2MS

TH1=(65536-50000)/256;
TL1=(65536-50000)%256; //T1初始化50MS

TR1=0;
ET1=1;
EA=1;
TR0=0;
ET0=1;

count0=0; //初始没有密码输入,故为零
enterflag=0; //没有确认键按下
mimaflag=0; //密码正确与否键先置零

red=1; //红灯不亮
//************密码存入EPROM中**********************************
sda=1;
delay(5);
scl=1;
delay(5);
for(i=0;i<8;i++)
{
write_add(i,8);
delay2(100);
}
for(i=0;i<8;i++)
{
mima[i]=read_add(i);
delay(5);
}

}
void main()
{ rw=0;
init();
write_com(0x80); //指针所指位置
for(count3=0;count3<16;count3++)
{
write_date(table1[count3]); //第一行显示INPUT THE PASSPORD:
delay(5);
}
write_com(0x80+0x40);
for(count3=0;count3<16;count3++)
{
write_date(table2[count3]); //开机显示FFFFFFFF
delay(5);
}
while(1)
{
key_scan(); //调用键盘扫描函数
lcd_display();
}

}
//**************************************************键盘扫描函数开始********************************
void key_scan()
{
//**********扫描第一行*********
P1=0xfe;
temp=P1;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(100);
if(temp!=0xf0)
{
temp=P1;
switch(temp)
{
case 0xee:
key_manage1();
break;

case 0xde:
key_manage2();
break;

case 0xbe:
key_manage3();
break;

case 0x7e:
key_manage4();
break;
}
while(temp!=0xf0)
{
temp=P1;
temp=temp&0xf0;
}
}
}
//**************************************************扫描第二行***********************************
P1=0xfd;
temp=P1;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(100);
if(temp!=0xf0)
{
temp=P1;
switch(temp)
{
case 0xed:
key_manage5();
break;

case 0xdd:
key_manage6();
break;

case 0xbd:
key_manage7();
break;

case 0x7d:
key_manage8();
break;
}
while(temp!=0xf0)
{
temp=P1;
temp=temp&0xf0;
}
}
}
//*********************************************扫描第三行***********************************
P1=0xfb;
temp=P1;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(100);
if(temp!=0xf0)
{
temp=P1;
switch(temp)
{
case 0xeb:
key_manage9();
break;

case 0xdb:
key_manage10();
break;

case 0xbb:
key_manage11();
break;

case 0x7b:
key_manage12();
break;
}
while(temp!=0xf0)
{
temp=P1;
temp=temp&0xf0;
}
}
}

//***************************************************扫描第四行****************************************
P1=0xf7;
temp=P1;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(100);
if(temp!=0xf0)
{
temp=P1;
switch(temp)
{
case 0xe7:
key_manage13();
break;

case 0xd7:
key_manage14();
break;

case 0xb7:
key_manage15();
break;

case 0x77:
key_manage16();
break;
}
while(temp!=0xf0)
{
temp=P1;
temp=temp&0xf0;
}
}
}
}

** 0 ** 1 **2 ** 3**
** 4** 5** 6 **7 **
**8** 9** 确认(A) **未定义(B)
**取消(C)**修改密码键(D)**确认修改键(E)**未定义(F)