|
这是一个用51单片机做的密码保险箱设计 带仿真+源程序等,密码锁上面的键盘按下数字的时候,密码不会直接显示。如果密码验证成功,锁就可以打开。下面是电路原理图:
单片机密码保险箱设计的源程序如下:
- #include<AT89x52.h>
- unsigned int num=10; //开始让数码管什么都显示
- bit set=0; //定义设置密码的位
- char count=-1; //开始让COUNT=-1,方便后面显示数码管
- sbit Beep=P1^2; //蜂鸣器
- unsigned char temp;
- unsigned char pws[6]={1,2,3,4,5,6}; //原始密码
- unsigned char pwx[6]; //按下的数字存储区
- bit rightflag; //密码正确标志位
- unsigned char workbuf[6];
- unsigned char code tabledu[]={
- 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00,0x40
- }; //段选码,共阴极
- unsigned char code tablewe[]={
- 0xfe,0xfd,0xfb,0xf7,0xef,0xdf
- }; //位选码
- unsigned int keyscan();
- void delay(unsigned char z) //延时,ms级
- {
- unsigned char y;
- for(;z>0;z--)
- for(y=120;y>0;y--);
- }
- void setpw() //设置密码函数
- {
- keyscan();
- }
- unsigned int keyscan() //键盘扫描函数
- {
- P3=0xfe;
- temp=P3;
- temp=temp&0xf0;
- if(temp!=0xf0)
- {
- delay(5); //键盘去抖,最好20ms以上,这里用了5ms
- temp=P3;
- temp=temp&0xf0;
- if(temp!=0xf0)
- {
- count++;//按键计数加1
- temp=P3;
- switch(temp)
- {
- case 0xee:
- {
- num=7;
- if(count<6) //六位密码,所以COUNT<6
- {
- if(set==0) //设置密码键没有按下时
- pwx[count]=num; //存储按下的数字
- else
- pws[count]=num; //设置密码键按下时,设置新密码
- workbuf[count]=tabledu[11]; //相应位的数码管显示"--",不显示相应的数字,密码是保密的
- }
- }
- break;
- case 0xde:
- {
- num=8;
- if(count<6) //以下扫描键盘的原理差不多同上
- {
- if(set==0)
- pwx[count]=num;
- else
- pws[count]=num;
- workbuf[count]=tabledu[11];
- }
- }
- break;
- case 0xbe:
- {
- num=9;
- {
- if(count<6)
- {
- if(set==0)
- pwx[count]=num;
- else
- pws[count]=num;
- workbuf[count]=tabledu[11];
- }
- }
- }
- break;
- case 0x7e: //设置密码键按下
- {
- set=1; //设置密码标志位置1
- P1_3=0; //设置密码指示灯亮
- workbuf[0]=0x00;//数码管第一位不显示
- workbuf[1]=0x00;//......
- workbuf[2]=0x00;//......
- workbuf[3]=0x00;
- workbuf[4]=0x00;
- workbuf[5]=0x00;//......
- count=-1; //按键计数复位为-1
- if(count<6) //密码没有设置完,继续设置密码
- {
- setpw(); //设置密码
- }
- }
- break;
- }
- while(temp!=0xf0) //按键抬起检测
- {
- temp=P3;
- temp=temp&0xf0;
- }
- }
- }
- P3=0xfd;
- temp=P3;
- temp=temp&0xf0;
- if(temp!=0xf0)
- {
- delay(5);
- temp=P3;
- temp=temp&0xf0;
- if(temp!=0xf0)
- {
- count++;
- temp=P3;
- switch(temp)
- {
- case 0xed:
- {
- num=4;
- if(count<6)
- {
- if(set==0)
- pwx[count]=num;
- else
- pws[count]=num;
- workbuf[count]=tabledu[11];
- }
- }
- break;
- case 0xdd:
- {
- num=5;
- if(count<6)
- {
- if(set==0)
- pwx[count]=num;
- else
- pws[count]=num;
- workbuf[count]=tabledu[11];
- }
- }
- break;
- case 0xbd:
- {
- num=6;
- if(count<6)
- {
- if(set==0)
- pwx[count]=num;
- else
- pws[count]=num;
- workbuf[count]=tabledu[11];
- }
- }
- break;
- }
- while(temp!=0xf0)
- {
- temp=P3;
- temp=temp&0xf0;
- }
- }
- }
- P3=0xfb;
- temp=P3;
- temp=temp&0xf0;
- if(temp!=0xf0)
- {
- delay(5);
- temp=P3;
- temp=temp&0xf0;
- if(temp!=0xf0)
- {
- count++;
- temp=P3;
- switch(temp)
- {
- case 0xeb:
- {
- num=1;
- if(count<6)
- {
- if(set==0)
- pwx[count]=num;
- else
- pws[count]=num;
- workbuf[count]=tabledu[11];
- }
- }
- break;
- case 0xdb:
- {
- num=2;
- if(count<6)
- {
- if(set==0)
- pwx[count]=num;
- else
- pws[count]=num;
- workbuf[count]=tabledu[11];
- }
- }
- break;
- case 0xbb:
- {
- num=3;
- if(count<6)
- {
- if(set==0)
- pwx[count]=num;
- else
- pws[count]=num;
- workbuf[count]=tabledu[11];
- }
- }
- break;
- }
- while(temp!=0xf0)
- {
- temp=P3;
- temp=temp&0xf0;
- }
- }
- }
- P3=0xf7;
- temp=P3;
- temp=temp&0xf0;
- if(temp!=0xf0)
- {
- delay(5);
- temp=P3;
- temp=temp&0xf0;
- if(temp!=0xf0)
- {
- count++;
- temp=P3;
- switch(temp)
- {
- case 0xd7:
- {
- num=0;
- if(count<6)
- {
- if(set==0)
- pwx[count]=num;
- else
- pws[count]=num;
- workbuf[count]=tabledu[11];
- }
- }
- break;
- case 0xe7: num=20;break; //确定键按下检测
- case 0x77: //复位键或者输入密码全部一次删除
- {
- P1_1=0; //锁关
- P1_3=1; //密码设置指示灯灭
- set=0; //不设置密码
- num=10; //num复位
- count=-1; //COUNT复位
- workbuf[0]=tabledu[10]; //第一位数码管不显示
- workbuf[1]=tabledu[10]; //第二位数码管不显示
- workbuf[2]=tabledu[10];
- workbuf[3]=tabledu[10];
- workbuf[4]=tabledu[10];
- workbuf[5]=tabledu[10]; //......
- P1_0=1; //锁关
- }
- break;
- case 0xb7: //输入密码删除键(一位一位删除)
- {
- count--;
- workbuf[count]=0x00; //因确定键按下时,COUNT也会加1,而确定键不是密码,所以这里是COUNT,而不是COUNT+1
- count--; //因确定键按下时,确定键不是密码,COUNT也会加1,这里COUNT再自减1
- if(count<=-1)
- count=-1;
- }
- break;
- }
- while(temp!=0xf0)
- {
- temp=P3;
- temp=temp&0xf0;
- }
- }
- }
- return(num);
- }
- void init() //利用定时显示数码管
- {
- TMOD=0x01;
- TH0=(65536-500)/200;
- TL0=(65536-500)%200;
- ET0=1;
- EA=1;
- TR0=1;
- }
- bit compare() //密码比较函数
- {
- if((pwx[0]==pws[0])&(pwx[1]==pws[1])&(pwx[2]==pws[2])&(pwx[3]==pws[3])&(pwx[4]==pws[4])&(pwx[5]==pws[5]))
- rightflag=1;
- else
- rightflag=0;
- return(rightflag);
- }
- void main()
- {
- unsigned int i,j;
- init();
- P0=0;
- P1_1=0; //锁关
- while(1)
- {
- keyscan();
- if(num==20) //如果确定键按下(修改密码和输入密码共用的确定键)
- {
- if(count==6)
- {
- if(set==1) //修改密码确定
- {
- P1_3=1;
- workbuf[0]=0;
- workbuf[1]=0;
- workbuf[2]=0;
- workbuf[3]=0;
- workbuf[4]=0;
- workbuf[5]=0;
- }
- else //输入密码确定
- {
- set=0;
- compare();
- if(rightflag==1) //如果密码正确
- {
- P1_0=0; //锁开
- P1_1=1;
- workbuf[0]=tabledu[8]; //数码管第一位显示"8"
- workbuf[1]=tabledu[8]; //数码管第二位显示"8"
- workbuf[2]=tabledu[8];
- workbuf[3]=tabledu[8];
- workbuf[4]=tabledu[8];
- workbuf[5]=tabledu[8]; //......
- }
- else
- {
- P1_1=0; //锁仍然是关
- workbuf[0]=0X71; //数码管第一位显示"F"
- workbuf[1]=0X71;
- workbuf[2]=0X71;
- workbuf[3]=0X71;
- workbuf[4]=0X71;
- workbuf[5]=0X71; //......
- for(i=0;i<1000;i++) //密码错误报警
- {
- for(j=0;j<80;j++);
- Beep=~Beep;
- }
- break;
- }
- }
- }
- else //若输入的密码位数不为6位时
- {
- P1_1=0; //锁仍然关
- workbuf[0]=0X71; //数码管第一位显示"F"
- workbuf[1]=0X71;
- workbuf[2]=0X71;
- workbuf[3]=0X71;
- workbuf[4]=0X71;
- workbuf[5]=0X71;
- for(i=0;i<1000;i++)
- {
- for(j=0;j<80;j++);
- Beep=~Beep;
- }
- break;
- }
- }
- }
- }
- void timer0() interrupt 1 //数码管驱动函数
- {
- unsigned char i;
- TH0=(65536-500)/200;
- TL0=(65536-500)%200;
- for(i=0;i<6;i++)
- {
- P0=workbuf[i]; //送出显示内容
- P2=tablewe[i]; //选中显示的行
- delay(5);
- P0=0;
- }
- }
复制代码
单片机密码保险箱设计仿真工程文件及其他完整资料下载:
http://www.51hei.com/bbs/dpj-54940-1.html
|
|