3*3矩陣按鍵
繼電器控制密碼正確與錯誤
兩個LED燈顯示報警和密碼正確
LCD1602顯示屏顯示密碼
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
51hei.gif (140.19 KB, 下載次數: 67)
下載附件
2021-6-24 00:46 上傳
單片機源程序如下:
- #include<reg51.h>
- #define ulong unsigned long
- #define uint unsigned int
- #define uchar unsigned char
- uchar temp,num,flag,r;
- uchar code table1[]="welcome! ";
- uchar code table2[]="enter password";
- uchar code table3[]="012345";
- uchar code table4[]="code is wrong!";
- uchar code table5[]="you are right!";
- uchar code table6[]="the second time!";
- uchar code table7[]="the last time!";
- uchar code table8[]="Input new code:";
- uchar code table9[]="calling.....";
- uchar code table10[]="password";
- uchar code table11[]=" ";
- uchar code table12[]="Modify right!!!";
- uchar code table13[]="Input again:";
- uchar code table14[]="Modify error!!!";
- uchar init_pswd[4]={2,3,0,5};
- uchar pswd[4]={0};
- sbit lcdrs=P2^0; //LCD數據/指令(H/L)選擇端
- sbit lcdrw=P2^1;
- sbit lcden=P2^2; //LCD使能
- sbit P1_6=P1^6;
- sbit P2_6=P2^6;//報警指示燈
- sbit P2_7=P2^7;
- sbit P3_7=P3^7; //蜂鳴器
- /****************子函數聲明*/
- void delay(uint z);
- void init();//初始化子函數
- void write_com(uchar com);//寫指令子函數
- void write_data(uchar dat1);//寫數據子函數
- uint keyscan();
- void mima();//密碼處理子函數
- void mima1();//修改密碼函數
- void Alarm(uchar t);//報警函數
- /***************液晶驅動*/
- void init()
- {
- lcden=0;
- write_com(0x38);
- write_com(0x0e);
- write_com(0x06);
- write_com(0x01);
- write_com(0x80);
- }
- void write_com(uchar com)
- {
- lcdrs=0;
- lcdrw=0;
- P0=com;
- delay(5);
- lcden=1;
- delay(5);
- lcden=1;
- delay(5);
- lcden=0;
- }
- void write_data(uchar dat1)
- {
- lcdrs=1;
- lcdrw=0;
- P0=dat1;
- delay(5);
- lcden=1;
- delay(5);
- lcden=0;
- }
- void delay(uint z) //延時子函數 z*1ms
- {
- uint x,y;
- for(x=z;x>0;x--)
- for(y=110;y>0;y--);
- }
- uint keyscan() //鍵盤掃描程序
- {
- P1=0xfe; //先選定第一行
- temp=P1;
- temp=temp&0xf8; //列線全為1,行線為0
- while(temp!=0xf8)
- {
- delay(15); //延時去抖
- temp=P1;
- temp=temp&0xf8;
- while(temp!=0xf8)
- {
- temp=P1;
- switch(temp) //判斷哪列按下
- {
- case 0xf6:num=0;flag=1;break;//第一列按下
- case 0xee:num=1;flag=1;break;//第二列按下
- case 0xde:num=2;flag=1;break;//第三列按下
- }
- while(temp!=0xf8)
- {
- temp=P1;
- temp=temp&0xf8;
- }
- }
- }
- P1=0xfd; //選定第二行,列線為1
- temp=P1;
- temp=temp&0xf8;
- while(temp!=0xf8)
- {
- delay(15);
- temp=P1;
- temp=temp&0xf8;
- while(temp!=0xf8)
- {
- temp=P1;
- switch(temp) //判斷哪列按下
- {
- case 0xf5:num=3;flag=1;//第一列按下
- break;
- case 0xed:num=4;flag=1;//第二列按下
- break;
- case 0xdd:num=5;flag=1;//第三列按下
- break;
- }
- while(temp!=0xf8)
- {
- temp=P1;
- temp=temp&0xf8;
- }
- }
- }
- P1=0xfb;//選定第三行
- temp=P1;
- temp=temp&0xf8;
- while(temp!=0xf8)
- {
- delay(15);
- temp=P1;
- temp=temp&0xf8;
- while(temp!=0xf8)
- {
- temp=P1;
- switch(temp)
- {
- case 0xf3:num=6;flag=1;break;
- case 0xeb:num=7;flag=1;break;
- case 0xdb:num=8;flag=1;break;
- }
- while(temp!=0xf8)
- {
- temp=P1;
- temp=temp&0xf8;
- }
- }
- }
- return(num);
- }
- void main()
- {
- uchar m=0,w=0;
- init();//LCD初始化
- write_com(0x80); //第一行顯示
- for(r=0;r<15;r++)
- {
- write_data(table1[r]);
- delay(5);
- }
- write_com(0x80+0x40);//第二行顯示
- for(r=0;r<15;r++)
- {
- write_data(table2[r]);
- delay(5);
- }
- write_com(0x0c);
- do
- {keyscan();}
- while(num!=8); //等待開鎖鍵按下
- mima(); //密碼輸入處理函數
- while((pswd[m]==init_pswd[m])&m<4)//密碼比較
- {
- m++;
- }
- if(m>=4)//密碼正確
- {
- P2_7=0;//開鎖指示燈亮
- keyscan();
- while(flag==1&&num==6);//是否修改密碼//
- mima1();//修改密碼函數
- }
- else//密碼有誤
- {
- m=0;
- write_com(0x80+0x40);//顯示第二行
- for(r=0;r<14;r++)
- {
- delay(20);
- write_data(table4[r]);
- }
- delay(3000);
- init();
- for(r=0;r<16;r++)
- {
- delay(20);
- write_data(table6[r]);
- }
- delay(3000);
- mima();
- while((pswd[m]==init_pswd[m])&m<4)
- {m++;}
- if(m>=4)
- {
- P2_7=0;
- mima1();
- }
- else
- {
- m=0;
- write_com(0x80+0x40);
- for(r=0;r<14;r++)
- {
- delay(20);
- write_data(table4[r]);
- }
- delay(3000);
- init();
- for(r=0;r<14;r++)
- {
- delay(20);
- write_data(table7[r]);
- }
- delay(3000);
- mima();
- while((pswd[m]==init_pswd[m])&m<4)
- {m++;}
- if(m>=4)
- {
- P2_7=0;
- mima1();
- }
- else
- {
- init();
- write_com(0x80+0x40);
- for(r=0;r<13;r++)
- {
- delay(20);
- write_data(table9[r]);
- }
- write_com(0x0c);
- while(1)
- {
- P2_6=~P2_6;
- delay(30);
- Alarm(90);
- Alarm(120);
- }
- }
- }
- }
- }
- void mima()//密碼輸入程序
- {
- uchar w=0;
- init();
- for(r=0;r<9;r++)
- {
- delay(20);
- write_data(table10[r]);
- }
- do
- {
- flag=0;
- keyscan();
- write_com(0x80+9+w);
- if(flag==1&&num<=5)
- {
- pswd[w]=num;
- write_data(table3[num]);
- w++;//輸入密碼
- if(w==4)
- write_com(0x0c);
- }
- if(flag==1&&num==7) //刪除誤輸入的密碼,即返回上一步.
- {
- w--; //刪除密碼
- if(w==255)//刪除完密碼
- w=w+1;
- write_com(0x80+9+w);
- write_data(table11[w+1]);
- if(flag==1&&num<=3)
- {
- pswd[w]=num;
- write_data(table3[num]);
- }
- }
- }
- while(w<=3);
- }
- void mima1()
- {
- uchar f=0,n=0,d=0;
- write_com(0x80+0x40);
- for(r=0;r<14;r++)
- {
- delay(20);
- write_data(table5[r]);
- }
- delay(3000);
- do
- {
- num=9;//按鍵不顯示,鎖住按鍵
- keyscan();
- }
- while(num!=6);
- if(flag==1&&num==6)
- {
- init();
- P2_7=0;
- for(r=0;r<15;r++)
- {
- delay(20);
- write_data(table8[r]);
- }
- write_com(0x0c);
- write_com(0x80+0x40+n);
- write_com(0x0e);
- }
- do
- {
- num=9;//按鍵不顯示, 鎖住按鍵
- keyscan();
- write_com(0x80+0x40+n);
- if(flag==1&&num<=5)
- {
- init_pswd[n]=num;
- write_data(table3[num]);
- n++;
- if(n==4)
- write_com(0x0c);
- }
- if(flag==1&&num==7)//刪除 誤輸入的密碼,即返回上一步
- {
- n--;
- if(n==255)
- n=n+1;
- write_com(0x80+0x40+n);
- write_data(table11[n]);
- if(flag==1&&num<=3)//顯示0-5鍵值
- {
- pswd[n]=num;
- write_data(table3[num]);
- }
- }
- }
- while(n<=3);
- init();
- for(r=0;r<12;r++)
- {
- delay(20);
- write_data(table13[r]);
- }
- do
- {
- flag=0;//鎖住按鍵
- keyscan();
- write_com(0x80+0x40+d);
- if(flag==1&&num<=5)
- {
- pswd[d]=num;
- write_data(table3[num]);
- d++;
- if(d==4)
- write_com(0x0c);
- }
- if(flag==1&&num==7)//刪除誤輸入的密碼,即返回上一步.
- {
- d--;
- if(d==255)
- d=d+1;
- write_com(0x80+0x40+d);
- write_data(table11[d+1]);
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
所有資料51hei提供下載:
新建文件夾 (3).zip
(101.18 KB, 下載次數: 36)
2021-6-23 22:42 上傳
點擊文件名下載附件
電子密碼鎖 下載積分: 黑幣 -5
|