|
這是一個用51單片機做的密碼保險箱設計 帶仿真+源程序等,密碼鎖上面的鍵盤按下數字的時候,密碼不會直接顯示。如果密碼驗證成功,鎖就可以打開。下面是電路原理圖:
0.png (28.46 KB, 下載次數: 52)
下載附件
2016-8-31 22: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;
- }
- }
復制代碼
0.png (73.29 KB, 下載次數: 45)
下載附件
2016-8-31 22:50 上傳
單片機密碼保險箱設計仿真工程文件及其他完整資料下載:
http://www.zg4o1577.cn/bbs/dpj-54940-1.html
|
|