該設(shè)計(jì)基于STC單片機(jī)設(shè)計(jì),電路主要由51單片機(jī)最小系統(tǒng)和按鍵部分、蜂鳴器報(bào)警部分、LCD液晶顯示部分等組成。該電路設(shè)計(jì)簡(jiǎn)單,單層板加上幾根跳線即可完成,適合電子初學(xué)者DIY制作。 電子密碼鎖具體功能介紹: 1、該電子密碼鎖默認(rèn)密碼為1234567890,密碼通過(guò)鍵盤輸入,若密碼正確,則將鎖打開(kāi)。 2、密碼可以由用戶自己修改設(shè)定(只支持6位密碼),鎖打開(kāi)后才能修改密碼。修改密碼之前必須再次輸入密碼,在輸入新密碼時(shí)候需要二次確認(rèn),以防止誤操作。 3、報(bào)警、鎖定鍵盤功能。密碼輸入錯(cuò)誤顯示器會(huì)出現(xiàn)錯(cuò)誤提示,若密碼輸入錯(cuò)誤次數(shù)超過(guò)3次,蜂鳴器報(bào)警并且鎖定鍵盤。 4、AT24C02保存密碼,支持復(fù)位保存,掉電保存功能。 附件內(nèi)容包括: 整個(gè)電子密碼鎖原理圖和PCB源文件,用AD軟件打開(kāi); BOM表; 源代碼(有詳細(xì)的中文注釋);
文件內(nèi)含PCB原理圖,元件清單,源程序。
Altium Designer畫的原理圖和PCB圖如下:(51hei附件中可下載工程文件)
單片機(jī)源程序如下:
- #include<reg52.h>
- #define uint unsigned int
- #define uchar unsigned char
- sbit l1=P1^0; //LED指示
- sbit bump=P2^2; //蜂鳴器控制
- sbit relay=P2^3;//繼電器輸出
- sbit lcden=P2^7;//LCD1602液晶控制端
- sbit lcdrs=P2^6;
- sbit sda=P2^0; //AT24C02數(shù)據(jù)端口
- sbit scl=P2^1; //時(shí)鐘端口
- /**********顯示內(nèi)容**************************/
- uchar code xianshi0[]="input password:";
- uchar code xianshi1[]="please come in!";
- uchar code xianshi2[]="*";
- uchar code xianshi3[]=" you are thief!";
- uchar code xianshi4[]=" new password:";
- uchar code xianshi5[]=" alter succeed!";
- uchar code xianshi6[]=" first error!";
- uchar code xianshi7[]=" second error!";
- uchar code xianshi8[]=" third error!";
- uchar code xianshi9[]=" alter fail!!";
- uchar table[8]; //給按鍵輸入留取存儲(chǔ)空間
- uchar table1[8]; //給密碼修改留取存儲(chǔ)空間
- uchar mima[8]; //給從存儲(chǔ)中讀取密碼留取存儲(chǔ)空間
- uchar num,num1,num2,num3,etimes,fanhui,kai;
- bit alterflog,cpflog,suoflog;//定義各種標(biāo)志位 修改密碼鍵按下標(biāo)志 密碼比較正確標(biāo)志 上鎖標(biāo)志
- void keyscan(); //聲明鍵盤掃描函數(shù)
- void init();
- void keydeal15();
- void keydeal16(); //聲明初始化函數(shù)
- /********************延時(shí)一毫秒函數(shù)**************/
- void delay_xs(uint x)
- { uint i,j;
- for(i=x;i>0;i--) for(j=110;j>0;j--);}
- void writecom(uchar com) //寫命令
- {
- lcdrs=0; P0=com; delay_xs(5);
- lcden=1; delay_xs(5); lcden=0;
- }
- /*********************液晶寫命令數(shù)據(jù)函數(shù)******************/
- void writedate(uchar date) //寫命令
- {
- lcdrs=1; P0=date; delay_xs(5);
- lcden=1; delay_xs(5); lcden=0;
- }
- /***************24c02讀取寫入數(shù)據(jù)初始化****************/
- void delay() //微妙級(jí)延時(shí)函數(shù)
- { ;; }
- void start() //開(kāi)始信號(hào)
- {
- sda=1; delay(); scl=1; delay(); sda=0; delay();
- }
- void stop() //停止
- {
- sda=0;delay();scl=1;delay();sda=1;delay();
- }
- void respons() //應(yīng)答
- {
- uchar i;
- scl=1; delay();
- while((sda==1)&&(i<250)) i++;
- scl=0; delay();
- }
- void write_byte(uchar date) //寫一位數(shù)據(jù)
- {
- uchar i,temp;
- temp=date;
- for(i=0;i<8;i++)
- {
- temp=temp<<1;
- scl=0; delay(); sda=CY; delay();
- scl=1; delay();
- }
- scl=0; delay();
- sda=1; delay();
- }
- uchar read_byte() //讀一位數(shù)據(jù)
- {
- uchar i,k;
- scl=0; delay();
- sda=1; delay();
- for(i=0;i<8;i++)
- {
- scl=1; delay();
- k=(k<<1)|sda;
- scl=0; delay();
- }
- return k;
- }
- void write24c02(uchar address,uchar date) //寫一字節(jié)函數(shù)
- {
- start();
- write_byte(0xa0);
- respons();
- write_byte(address);
- respons();
- write_byte(date);
- respons();
- stop();
- }
- uchar read24c02(uchar address) //讀一字節(jié)函數(shù)
- {
- uchar date;
- start();
- write_byte(0xa0);
- respons();
- write_byte(address);
- respons();
- start();
- write_byte(0xa1);
- respons();
- date=read_byte();
- stop();
- return date;
- }
- /************各按鍵對(duì)應(yīng)處理函數(shù)***************/
- /*************各按鍵功能********************
- 1-2-3-4-5-6-7-8-9-0-確認(rèn)-重新輸入-未定義-上鎖-密碼修改
- -密碼修改確認(rèn)-未定義*************************/
- void keydeal1() //按鍵1
- {
- table[num]=1;
- num++;
- if(alterflog==1){table1[num1]=1;num1++; }
- }
- void keydeal2() //按鍵2
- {
- table[num]=2;
- num++;
- if(alterflog==1){table1[num1]=2;num1++; }
- }
- void keydeal3() //按鍵3
- {
- table[num]=3;
- num++;
- if(alterflog==1){table1[num1]=3;num1++; }
- }
- void keydeal4() //按鍵4
- {
- table[num]=4;
- num++;
- if(alterflog==1){table1[num1]=4;num1++; }
- }
- void keydeal5() //按鍵5
- {
- table[num]=5;
- num++;
- if(alterflog==1) {table1[num1]=5;num1++;}
- }
- void keydeal6() //按鍵6
- {
- table[num]=6;
- num++;
- if(alterflog==1){table1[num1]=6;num1++; }
- }
- void keydeal7() //按鍵7
- {
- table[num]=7;
- num++;
- if(alterflog==1){table1[num1]=7;num1++; }
- }
- void keydeal8() //按鍵8
- {
- table[num]=8;
- num++;
- if(alterflog==1){table1[num1]=8;num1++; }
- }
- void keydeal9() //按鍵9
- {
- table[num]=9;
- num++;
- if(alterflog==1){table1[num1]=9; num1++; }
- }
- void keydeal10() //按鍵10
- {
- table[num]=0; num++;
- if(alterflog==1){table1[num1]=0;num1++; }
- }
- void compare() //比較密碼正確與否函數(shù)
- {
- uchar j;
- for(j=0;j<8;j++)
- {
- if(table[j]==mima[j]){cpflog=1;l1=0;}
- else cpflog=0;
- l1=1;
- }
- }
- void keydeal11() //確認(rèn)鍵
- {
- uchar j;
- if(alterflog==1)
- goto n; //如果密碼修改鍵按下再按此鍵無(wú)效
- if(num==8) //判斷是否輸入八個(gè)數(shù)字
- {
- num=0; //將輸入數(shù)字個(gè)數(shù)清零
- compare(); //進(jìn)行密碼比較
- for(j=0;j<8;j++) //用FFFFFFFF將輸入的數(shù)據(jù)清空
- {
- table[j]=0x0f;
- }
- }
- if(cpflog==1) //如果密碼正確,標(biāo)志位為1
- {
- l1=0; //點(diǎn)亮開(kāi)鎖燈
- cpflog=0; //使比較密碼標(biāo)志位歸零
- etimes=0; //使記錯(cuò)次數(shù)歸零
- kai=1; //使打開(kāi)鎖標(biāo)志位置1
- writecom(0x01); //液晶屏清空顯示
- writecom(0x80); //讓液晶顯示“please come in!”
- for(j=0;j<15;j++)
- {
- writedate(xianshi1[j]); delay_xs(3);
- }
- for(j=0;j<2;j++) //蜂鳴器響兩聲提示開(kāi)鎖成功
- {
- bump=0; delay_xs(200);
- bump=1; delay_xs(200);
- bump=0; delay_xs(200);
- bump=1; delay_xs(200);
- }
- /*********等待按下上鎖鍵或者密碼修改鍵**********/
- while((suoflog!=1)&(alterflog!=1))
- {
- P3=0xf7;
- if(P3==0xe7) suoflog=1; //上鎖鍵按下上鎖標(biāo)志位置1
- if(P3==0xd7) alterflog=1; //密碼修改鍵按下標(biāo)志位置1
- if(suoflog==1) //上鎖后進(jìn)行初始化
- {
- init();
- }
- n: if(alterflog==1) //密碼修改鍵按下顯示new passsword
- {
- writecom(0x01); writecom(0x38);
- for(j=0;j<15;j++){writedate(xianshi4[j]); }
- }
- }
- suoflog=0; //上鎖標(biāo)志位清零
- }
- else //否則密碼錯(cuò)誤,執(zhí)行密碼錯(cuò)誤指令
- {
- num=0; //將輸入數(shù)據(jù)個(gè)數(shù)清零
- num1=0; //將修改密碼輸入數(shù)字個(gè)數(shù)清零
- etimes++; //記錄錯(cuò)誤次數(shù)加1
- bump=0; //報(bào)警一聲
- delay_xs(500); bump=1;
- for(j=0;j<8;j++) //清空修改密碼輸入數(shù)據(jù)
- { table1[j]=0x0f; }
- if(etimes==1) //如果輸錯(cuò)一次
- {
- writecom(0x01); //清屏
- writecom(0x80);
- for(j=0;j<14;j++) //顯示first error
- { writedate(xianshi6[j]); }
- delay_xs(2000); //延時(shí)兩秒
- writecom(0xc);
- writecom(0x80);
- for(j=0;j<16;j++) //第一行顯示input passsword
- {
- writedate(xianshi0[j]); delay_xs(5);
- }
- writecom(0x80+0x40+4); //第二行顯示--------
- for(j=0;j<8;j++) {writedate('-'); }
- }
- if(etimes==2) //如果輸錯(cuò)兩次
- {
- writecom(0x01); writecom(0x80);
- for(j=0;j<15;j++) //顯示second error
- {
- writedate(xianshi7[j]);
- }
- delay_xs(2000); //延時(shí)兩秒
- writecom(0xc);
- writecom(0x80);
- for(j=0;j<16;j++) //第一行顯示input passsword
- {
- writedate(xianshi0[j]); delay_xs(5);
- }
- writecom(0x80+0x40+4);
- for(j=0;j<8;j++) //第二行顯示--------
- {
- writedate('-');
- }
- }
- if(etimes==3) //如果輸錯(cuò)三次
- {
- writecom(0x01);
- writecom(0x80);
- for(j=0;j<15;j++) //顯示you are thief!
- {
- writedate(xianshi3[j]);
- }
- for(j=0;j<10;j++) //報(bào)警十秒鐘
- {
- bump=0; delay_xs(500);
- bump=1; delay_xs(500);
- }
- init(); //初始化
- }
- }
- }
- void keydeal12() //重新輸入鍵
- {
- uint i;
- if(kai==0) //如果所沒(méi)被打開(kāi)
- { //初始化回到輸入密碼狀態(tài)
- init();
- }
- else //如果鎖被打開(kāi),則顯示new password:
- {
- if(alterflog==1)
- {
- num=0; num1=0;
- writecom(0x01); writecom(0x80);//清屏
- for(i=0;i<15;i++){writedate(xianshi4[i]); }
- }
- }
- }
- void keydeal15() //確認(rèn)密碼修改鍵
- {
- uchar i;
- alterflog=0; //修改標(biāo)志位歸零
- num=0; //數(shù)據(jù)輸入個(gè)數(shù)清零
- for(i=0;i<8;i++) //輸入數(shù)據(jù)清空
- {
- table[i]=0x0f;
- }
- if(num1==8) //如果輸入修改數(shù)字夠八個(gè)進(jìn)入
- {
- num1=0; //將輸入修改數(shù)字個(gè)數(shù)清零
- for(i=0;i<8;i++) //將修改后八個(gè)數(shù)字寫入存儲(chǔ)器中
- {
- write24c02(i+1,table1[i]); delay_xs(5);
- }
- writecom(0x01); //清屏
- writecom(0x80);
- for(i=0;i<15;i++) //顯示alter succeed!!
- {
- writedate(xianshi5[i]);
- }
- delay_xs(2000);
- }
- else //如果輸入數(shù)字不夠八個(gè)進(jìn)入
- {
- num1=0; //將輸入修改數(shù)字個(gè)數(shù)清零
- writecom(0x01); //清屏
- writecom(0x80);
- for(i=0;i<14;i++) //顯示alter error!
- {
- writedate(xianshi9[i]);
- }
- }
- /**************修改后將鍵入返回程序************/
- if(kai==1) //如果鎖被打開(kāi)
- {
- num=0; //輸入數(shù)字個(gè)數(shù)清零
- delay_xs(2000); //延時(shí)兩秒鐘
- writecom(0x01); //清屏
- writecom(0x80);
- for(i=0;i<15;i++) //顯示please come in!
- {
- writedate(xianshi1[i]);
- delay_xs(3);
- } //繼續(xù)等待上鎖或修改密碼
- while((suoflog!=1)&(alterflog!=1))
- {
- P3=0xf7;
- if(P3==0xe7) suoflog=1;
- if(P3==0xd7) alterflog=1;
- if(suoflog==1) { init(); }
- if(alterflog==1)
- {
- writecom(0x01); writecom(0x80);//清屏
- for(i=0;i<15;i++){ writedate(xianshi4[i]); }
- }
- }
- }
- else //如果所沒(méi)被打開(kāi),顯示alter error兩秒后
- { //進(jìn)行初始化
- delay_xs(2000); init();
- }
- }
- void keydeal16() //鍵16未定義
- {
-
- }
- /******************鍵盤掃描函數(shù)**************************/
- void keyscan()
- {
- uchar temp;
- /**************第一行掃描********************/
- P3=0xfe;
- temp=P3&0xf0;
- if(temp!=0xf0)
- {
- delay_xs(10);
- if(temp!=0xf0) temp=P3;
- switch(temp)
- {
- case 0xee: keydeal1(); break;
- case 0xde: keydeal2(); break;
- case 0xbe: keydeal3(); break;
- case 0x7e: keydeal4(); break;
- }
- while((P3&0xf0)!=0xf0); //松手檢測(cè)
- }
- /******************第二行掃描**********************/
- P3=0xfd;
- temp=P3&0xf0;
- if(temp!=0xf0)
- {
- delay_xs(10);
- if(temp!=0xf0) temp=P3;
- switch(temp)
- {
- case 0xed: keydeal5(); break;
- case 0xdd: keydeal6(); break;
- case 0xbd: keydeal7(); break;
- case 0x7d: keydeal8(); break;
- }
- while((P3&0xf0)!=0xf0); //松手檢測(cè)
- }
- /*****************第三行掃描*********************/
- P3=0xfb;
- temp=P3&0xf0;
- if(temp!=0xf0)
- {
- delay_xs(10);
- if(temp!=0xf0) temp=P3;
- switch(temp)
- {
- case 0xeb: keydeal9(); break;
- case 0xdb: keydeal10(); break;
- case 0xbb: keydeal11(); break;
- case 0x7b: keydeal12(); break;
- }
- while((P3&0xf0)!=0xf0);
- }
- /********************第四行掃描********************/
- P3=0xf7;
- temp=P3&0xf0;
- if(temp!=0xf0)
- {
- delay_xs(10);
- if(temp!=0xf0) temp=P3;
- switch(temp)
- {
- case 0xe7: // keydeal13();
- break;
- case 0xd7: // keydeal14();
- break;
- case 0xb7: keydeal15(); break;
- case 0x77: keydeal16(); break;
- }
- while((P3&0xf0)!=0xf0);
- }
- }
- /****************顯示函數(shù)*************/
- void display()
- {
- uint c;
- writecom(0x80+0x40+4);
- if(alterflog==0) //如果不處于修改密碼狀態(tài),顯示num個(gè)*
- {
- for(c=0;c<num;c++){ writedate('*'); delay_xs(5); }
- }
- else //如果處于密碼修改顯示num1個(gè)*
- {
- for(c=0;c<num1;c++){ writedate('*'); delay_xs(5);}
- }
- }
- /*******************初始化函數(shù)***********/
- void init()
- {
- uint i,a,b;
- num=0; //輸入數(shù)據(jù)個(gè)數(shù)清零
- num1=0;
- kai=0; //開(kāi)鎖標(biāo)志位清零
- l1=1; //關(guān)閉開(kāi)鎖燈
- alterflog=0; //修改密碼標(biāo)志位清零
- sda=1; //24c02進(jìn)行釋放總線
- delay(); scl=1; delay();
- writecom(0x38); //液晶初始化
- writecom(0x0c);
- writecom(0x06);
- writecom(0x01);
- for(i=0;i<8;i++) //讀取存儲(chǔ)器中密碼,并存放于mima[]中
- {
- mima[i]=read24c02(i+1);
- }
- writecom(0x01); //清屏
- writecom(0x80);
- for(a=0;a<16;a++) //顯示input password:
- {
- writedate(xianshi0[a]); delay_xs(5);
- }
- writecom(0x80+0x40+4); //第二行顯示--------
- for(b=0;b<8;b++){ writedate('-'); }
- }
- /*****************主函數(shù)******************/
- void main()
- {
- init(); //初始化
- while(1) //不停地對(duì)鍵盤和顯示進(jìn)行掃描
- {
- keyscan(); //鍵盤掃描和密碼輸入處理
- display(); //LCD顯示
- }
- }
復(fù)制代碼
附件里面只有代碼下載,其他還沒(méi)完成,求大佬指點(diǎn):
電子密碼鎖.rar
(1.47 MB, 下載次數(shù): 179)
2019-1-8 10:20 上傳
點(diǎn)擊文件名下載附件
|