protues 利用51單片機、24c02、鍵盤及LCD1602/12864液晶顯示器件設計一個密碼鎖; 設置初始密碼為“123456”;在鎖已開狀態下,能通過矩陣鍵盤重置密碼;輸入密碼連續錯誤三次,則禁止輸入密碼一分鐘。 /**************************************************************
二、單片機密碼鎖的設計
設計要求:1)利用51單片機、鍵盤及LCD1602/12864液晶顯示器件設計一個密碼鎖;
2)密碼允許3~6位;設置初始密碼為“123456”;
3)在鎖已開狀態下,能通過矩陣鍵盤重置密碼;
4)輸入密碼時,LCD顯示“*”。密碼輸入正確在LCD1602顯示“OPEN”,并用LED亮顯示開鎖的狀態;
5)密碼輸入錯誤在LCD1602顯示“ERROR”,并用LED熄滅表示關鎖;
6)輸入密碼連續錯誤三次,則禁止輸入密碼一分鐘。
**************************************************************/
- #include<reg52.h>
- #include <intrins.h>
- #define uint unsigned int
- #define uchar unsigned char
-
- void shuru();
- sbit sda=P2^0; //IO口定義
- sbit scl=P2^1;
- sbit rs=P2^2;
- sbit lcden=P2^3;
- sbit led=P1^0;
- bit flag;
- uchar password[]={1,2,3,4,5,6};
- uchar enter[]={0,0,0,0,0,0,0};
- uchar str[]="0123456789";
- uchar wei,key,temp;
- uchar new1,new2,new3,new4,new5,new6;
- bit allow,change,sure,wanbi,retry,close,reset;
- char key_buf[] = {0xee, 0xde, 0xbe, 0x7e,0xed, 0xdd, 0xbd, 0x7d,//定義鍵值
- 0xeb, 0xdb, 0xbb, 0x7b};
- uchar p,time,a;
- void delay(uint x)
- {
- uint a,b;
- for(a=x;a>0;a--)
- for(b=10;b>0;b--);
- }
- /*****************************************************
- LCD1602初始化
- *****************************************************/
- void write_com(uchar com) //些命令,RS=0
- {
- P0=com;
- rs=0;
- lcden=0;
- delay(10);
- lcden=1;
- delay(10);
- lcden=0;
-
- }
- void write_data(uchar dat) //寫數據,RS=1
- {
- P0=dat;
- rs=1;
- lcden=0;
- delay(10);
- lcden=1;
- delay(10);
- lcden=0;
-
- }
- void lcdinit()
- {
- write_com(0x38); //00111000工作方式設置:16×2顯示,5×7點陣,8位數據接口
- write_com(0x0c);
- write_com(0x06); //00000110輸入方式設置:光標右移,字符不移
- write_com(0x01); //清屏幕指令,將以前的顯示內容清除
- write_com(0x80);
-
- }
- /******************************************************
- 24c02初始化
- *******************************************************/
- void nop()
- {
- _nop_();
- _nop_();
- }
- void init() //24c02初始化子程序
- {
- scl=1;
- nop();
- sda=1;
- nop();
- }
- void start() //啟動I2C總線
- {
- sda=1;
- nop();
- scl=1;
- nop();
- sda=0;
- nop();
- scl=0;
- nop();
- }
- void stop() //停止I2C總線
- {
- sda=0;
- nop();
- scl=1;
- nop();
- sda=1;
- nop();
- }
- void writebyte(unsigned char j) //寫一個字節
- {
- unsigned char i,temp;
- temp=j;
- for (i=0;i<8;i++)
- {
- temp=temp<<1;
- scl=0;
- nop();
- sda=CY; //temp左移時,移出的值放入了CY中
- nop();
- scl=1; //待sda線上的數據穩定后,將scl拉高
- nop();
- }
- scl=0;
- nop();
- sda=1;
- nop();
- }
- unsigned char readbyte() //讀一個字節
- {
- unsigned char i,j,k=0;
- scl=0; nop(); sda=1;
- for (i=0;i<8;i++)
- {
- nop(); scl=1; nop();
- if(sda==1)
- j=1;
- else
- j=0;
- k=(k<<1)|j;
- scl=0;
- }
- nop();
- return(k);
- }
- void clock() //I2C總線時鐘
- {
- unsigned char i=0;
- scl=1;
- nop();
- while((sda==1)&&(i<255))
- i++;
- scl=0;
- nop();
- }
- unsigned char read24c02(unsigned char address)
- {
- unsigned char i;
- start();
- writebyte(0xa0);
- clock();
- writebyte(address);
- clock();
- start();
- writebyte(0xa1);
- clock();
- i=readbyte();
- stop();
- delay(100);
- return(i);
- }
- void write24c02(unsigned char address,unsigned char info)
- {
- start();
- writebyte(0xa0);
- clock();
- writebyte(address);
- clock();
- writebyte(info);
- clock();
- stop();
- delay(5000); //這個延時一定要足夠長,否則會出錯。因為24c02在從sda上取得數據后,還需要一定時間的燒錄過程。
- }
- /*******************************************
- 矩陣鍵盤
- ********************************************/
- void keyscan()
- {
- P3=0xff; //獨立按鍵優先
- temp=P3;
- temp=temp&0xf0;
- if(temp!=0xf0)
- {
- delay(10);
- if(temp!=0xf0)
- {
- if(temp==0xe0) retry=1; //重試
- if(temp==0xd0) close=1; //關鎖
- if(temp==0x70) reset=1; //清內存密碼為000000
- }
- }
- P3=0xfe;
- temp=P3;
- temp=temp&0xf0;
- if(temp!=0xf0)
- {
- delay(10);
- if(temp!=0xf0)
- {
- temp=P3;
- switch(temp)
- {
- case 0xee:
- key=0;
- if(wei<6)
- {
- enter[wei]=key;
- write_data('*');
- }
- wei++;
- break;
- case 0xde:
- key=1;
- if(wei<6)
- {
- enter[wei]=key;
- write_data('*');
- }
- wei++;
- break;
- case 0xbe:
- key=2;
- if(wei<6)
- {
- enter[wei]=key;
- write_data('*');
- }
- wei++;
- break;
- case 0x7e:
- key=3;
- if(wei<6)
- {
- enter[wei]=key;
- write_data('*');
- }
- wei++;
- break;
- }
- while(temp!=0xf0)
- {
- temp=P3;
- temp=temp&0xf0;
- }
- }
- }
- P3=0xfd;
- temp=P3;
- temp=temp&0xf0;
- if(temp!=0xf0)
- {
- delay(10);
- if(temp!=0xf0)
- {
- temp=P3;
- switch(temp)
- {
- case 0xed:
- key=4;
- if(wei<6)
- {
- enter[wei]=key;
- write_data('*');
- }
- wei++;
- break;
- case 0xdd:
- key=5;
- if(wei<6)
- {
- enter[wei]=key;
- write_data('*');
- }
- wei++;
- break;
- case 0xbd:
- key=6;
- if(wei<6)
- {
- enter[wei]=key;
- write_data('*');
- }
- wei++;
- break;
- case 0x7d:
- key=7;
- if(wei<6)
- {
- enter[wei]=key;
- write_data('*');
- }
- wei++;
- break;
- }
- while(temp!=0xf0)
- {
- temp=P3;
- temp=temp&0xf0;
- }
- }
- }
- P3=0xfb;
- temp=P3;
- temp=temp&0xf0;
- if(temp!=0xf0)
- {
- delay(10);
- if(temp!=0xf0)
- {
- temp=P3;
- switch(temp)
- {
- case 0xeb:
- key=8;
- if(wei<6)
- {
- enter[wei]=key;
- write_data('*');
- }
- wei++;
- break;
- case 0xdb:
- key=9;
- if(wei<6)
- {
- enter[wei]=key;
- write_data('*');
- }
- wei++;
- break;
-
- case 0xbb:
- change=1; //改密
- wei=0;
- break;
- case 0x7b:
- if(allow) //改后確認
- sure=1;
- break;
- }
- while(temp!=0xf0)
- {
- temp=P3;
- temp=temp&0xf0;
- }
- }
- }
-
- /* P3=0xf7;
- temp=P3;
- temp=temp&0xf0;
- if(temp!=0xf0)
- {
- delay(10);
- if(temp!=0xf0)
- {
- temp=P3;
- switch(temp)
- {
- case 0xe7:
- retry=1;
- break;
- case 0xd7:
- close=1;
- break;
- }
- while(temp!=0xf0)
- {
- temp=P3;
- temp=temp&0xf0;
- beep=0;
- }
- beep=1;
- }
- } */
- }
- void compare()
- {
- if(wei==6)
- {
- if((enter[0]==password[0])&(enter[1]==password[1])&(enter[2]==password[2])&(enter[3]==password[3])&(enter[4]==password[4])&(enter[5]==password[5]))
- allow=1;
- }
- }
- void main()
- {
- uchar b,c,d;
- init();
- lcdinit();
-
- /****************************
- // write24c02(110,0x01);
- // write24c02(111,0x02);//24c02的第110到115地址單元作為密碼存儲區
- // write24c02(112,0x03);
- // write24c02(113,0x04);
- // write24c02(114,0x05);
- // write24c02(115,0x06);
-
- *****************************/
-
- /*password[0]=read24c02(110);
- password[1]=read24c02(111);
- password[2]=read24c02(112);
- password[3]=read24c02(113);
- password[4]=read24c02(114);
- password[5]=read24c02(115);*/
-
- while(1)
- {
- keyscan();
- compare();
- if(allow)
- {
- P1=0x00;
- write_com(0xc0);
- write_data('O');
- write_data('P');
- write_data('E');
- write_data('N');
- delay(500);
-
- }
-
- if(change)
- {
- change=0;
- if(allow)
- {
- allow=0;
- write_com(0x01);
- write_com(0xc0);
- write_data('N');
- write_data('E');
- write_data('W');
- write_com(0x80);
- while(wei<6)
- {
- keyscan();
- }
-
- }
- }
- if(sure)
- {
- sure=0;allow=0; wei=0;
- change=0;
- for(b=0;b<6;b++)
- {
- password[b]=enter[b];
- }
- write24c02(110,enter[0]);
- write24c02(111,enter[1]);
- write24c02(112,enter[2]);
- write24c02(113,enter[3]);
- write24c02(114,enter[4]);
- write24c02(115,enter[5]);
- write_com(0x01);
- }
- if(close)
- {
- close=0;change=0;//所有變量均被清零。
- wei=0;
- allow=0;
- P1=0xff;
- write_com(0x01);
- }
- }
-
- }
復制代碼
|