![]() |
發布時間: 2020-4-4 08:11
正文摘要:自行DIY電磁密碼鎖 在我的設計中有24c02存儲器,在程序沒用到。程序在仿真中是沒有問題 我也做過實物 實物也實驗成功,繼電器和蜂鳴器還沒有實驗。按鍵和顯示功能實現實現了。還有我的程序還有不足的地方 ... |
更新:PCB |
我會在單獨開個帖子 重新發布修改后的PCB、原理圖和程序。 |
更新程序:#include<reg51.h> #define uchar unsigned char #define uint unsigned int uchar code szjianzhibiao[]={0x77,0x7b,0x7d, 0xb7,0xbb,0xbd, //矩陣數字鍵盤鍵值 0xd7,0xdb,0xdd, 0xeb}; uchar code gnjianzhibiao[]={0x7e,0xbe,0xde, //矩陣功能鍵盤鍵值 0xee,0xed,0xe7}; uchar code mima[]={0x77,0x7d,0x77,0xb7, //設定的密碼 0x77,0x7d,0x77,0xb7}; uchar code table[]="HOLLE! User"; uchar code table1[]="Password"; uchar code table2[]="********"; uchar code table3[]=" error!"; uchar code table4[]=" OK! "; uchar code table5[]=" "; //抹除輸入痕跡的空字符串 uchar code table6[]="0123456789"; uchar code table7[]="012345"; sbit green=P3^2; //綠燈 sbit blue=P3^3; //藍燈 sbit red=P3^4; //紅燈 sbit bao=P1^3; //蜂鳴器 sbit jdq=P3^7; //繼電器 sbit en=P1^2; //定義LCD1602使能端 sbit rw=P1^1;//定義LCD1602讀/寫選擇端 sbit rs=P1^0;//定義LCD1602數據/命令選擇端 uchar T1_NUM=0,T1_NUM1=0,T0_NUM=0,T0_NUM1=0; uchar j=0,k=0,h=0,y=0,l=0,z=0,flag=0,flag1=0,flag2=0,p=0,d=0; void delay (uchar del) { uint i,j; for(i=0;i<del;i++) //延時程序 for(j=0;j<130;j++) ; } void lcd_wcom(uchar com) { rs=0; //選擇指令寄存器 rw=0; //選擇寫 P0=com; //把命令字送入P0 delay(10); en=0; delay(10); //延時一小會兒,讓1602準備接收數據 en=1; delay(10); //使能線電平變化,命令送入1602的8位數據口 en=0; } void lcd_wdat(uchar dat) //1602寫數據函數 { rs=1; //選擇數據寄存器 rw=0; //選擇寫 P0=dat; //把要顯示的數據送入P2 delay(10); en=0; delay(10); //延時一小會兒,讓1602準備接收數據 en=1; delay(10); //使能線電平變化,數據送入1602的8位數據口 en=0; } void lcd_init() { lcd_wcom(0x38); //8位數據,雙列,5*7字形 lcd_wcom(0x0c); //開啟顯示屏,關光標,光標不閃爍 lcd_wcom(0x06); //顯示地址遞減,即寫一個數據后,顯示位置右移一位 lcd_wcom(0x01); //清屏 } void xianshi() { uchar n,m=0; lcd_wcom(0x80+0x02); //顯示地址上排第三位 for(m=0;m<12;m++) //將table[]中的數據依次寫入1602顯示 { lcd_wdat(table[m]); delay(5); } lcd_wcom(0x80+0x40);//顯示地址為0xc4,即下排第1位 for(n=0;n<8;n++) //將table1[]中的數據依次寫入1602顯示 { lcd_wdat(table1[n]); delay(5); } } void xianshi1(uchar s) { uchar m; lcd_wcom(0x80+0x48); //顯示地址上排第九位,顯示輸入的*號 for(m=0;m<s;m++) //將table[]中的數據依次寫入1602顯示 { lcd_wdat(table2[m]); delay(1); } } void xianshi2() { uchar m; lcd_wcom(0x80+0x48); //顯示地址上排第九位,顯示OK for(m=0;m<8;m++) //將table[]中的數據依次寫入1602顯示 { lcd_wdat(table4[m]); delay(100); } } void xianshi3() { uchar m; lcd_wcom(0x80+0x48); //顯示地址上排第九位,顯示error for(m=0;m<8;m++) //將table[]中的數據依次寫入1602顯示 { lcd_wdat(table3[m]); delay(100); } } void xianshi5() { uchar m=0; lcd_wcom(0x80+0x48); //顯示地上排第九位,清除顯示 for(m=0;m<8;m++) //將table[]中的數據依次寫入1602顯示 { lcd_wdat(table5[m]); delay(1); } } void jishuqi( ) { TMOD=0x10; TH1=(65536-40000)/256; TL1=(65536-40000)%256; //定時器T1,設置40ms ET1=1; EA=1; TR1=1; } void time1() interrupt 3 { TH1=(65536-40000)/256; TL1=(65536-40000)%256; T1_NUM++; if(T1_NUM==25) //定時1S { T1_NUM=0; T1_NUM1++; p++; lcd_wcom(0x80+0x0f); //顯示個位秒 lcd_wdat(table6[p]); } if(T1_NUM1==5) //定時5S { T1_NUM1=0; if(flag==1) { red=~red; bao=1; //紅燈狀態反轉 flag=0; TR1=0; lcd_wcom(0x80+0x0e); lcd_wdat(table6[d]); //顯示十位秒 } } if(p==10) { p=0; //計時秒開始 d++; if(d==6) //計時分開始 d=0; } } void jishuqi1( ) { TMOD=0x10; TH0=(65536-40000)/256; TL0=(65536-40000)%256; //定時器T1 ET0=1; EA=1; TR0=1; } void time0() interrupt 1 { TH0=(65536-50000)/256; TL0=(65536-50000)%256; //設置50ms T0_NUM++; if(T0_NUM==100) //定時1S(正常來說T0_NUM應該=20就是1S,由于有誤差,所以設置為100) { T0_NUM=0; T0_NUM1++; l++; if(l==10) { l=0; //個位定時 z++; if(z==6) //十位定時 z=0; } if(j-1!=flag2) //每1S檢測是否有按鍵按下 flag1=1; //沒有按下,則賦值為1; } if(T0_NUM1==50) //定時50S { T0_NUM1=0; if(flag1>0&&flag1==1) //按鍵沒有按下 { flag1=0; //清零 if(j==flag2&&P2==0xf0) //按鍵未操作且鍵盤按下次數未增加 { red=0; delay(30); red=1; //超過50S未動作,清除數據并且清屏 xianshi5(); j=0; k=0; } } } } void key () { uchar lie,jianzhi,szjianhao,szjianpan1,gnjianhao,caijimima[7],szjianhao2[7],sign,i; if(flag==1) { xianshi3(); delay(100); //鎖定鍵盤并且報警 xianshi5(); } else { P2=0xf0; if(P2!=0xf0) { //按鍵去抖動 delay(10); if(P2!=0xf0) { j=j+1; //數字按鍵計數 k=k+1; //功能按鍵計數 lie=P2; P2=0x0f; jianzhi=lie|P2; for(i=0;i<10;i++) { if(jianzhi==szjianzhibiao[i]) { szjianhao=szjianzhibiao[i]; //對比數字按鍵 szjianpan1=i; //具體按鍵數字保存起來,可作用數碼管顯示,此可以不用理會 sign=0; //是數字按鍵按下標記 break; } } for(i=0;i<6;i++) { if(jianzhi==gnjianzhibiao[i]) { gnjianhao=i; //對比功能按鍵 sign=1; //是功能按鍵按下標記 break; } } while(P2!=0x0f); delay(10); } if(sign==0) //數字按鍵按下判斷 { bao=0; delay(30); //蜂鳴器提示音 bao=1; if(j==9) //連續九次輸入數字按鍵 { xianshi3(); delay(30000); xianshi5(); j=0; k=0; //錯誤提示、報警并且清除數據 red=0; delay(150); red=1; for(i=0;i<8;i++) caijimima[i]=0; } else { for(i=j-1;i<j;i++) { caijimima[i]=szjianhao; //正確輸入并且暫存儲密碼 szjianhao2[i]=szjianpan1; //具體按鍵數字保存起來,可作用數碼管顯示,此可以不用理會 green=0; delay(150); green=1; } xianshi1(i); } } if(sign==1) //功能按鍵判斷 { flag1=0; if(gnjianhao==3) //確認鍵判斷 { if(k==9) { for(i=0;i<8;i++) { if(mima[i]==caijimima[i]) { h=h+1; //對比計數 } else { h=1; break; } } if(h==8) //密碼正確 { k=0; j=0; h=0; blue=0; delay(150); blue=1; for(i=0;i<8;i++) caijimima[i]=0; xianshi2(); delay(10000); xianshi5(); //開鎖 jdq=0; delay(100); jdq=1; } if(h==1) //密碼錯誤 { bao=0; delay(200); bao=1; y++; //密碼錯誤次數標記 h=0; k=0; j=0; red=0; delay(150); red=1; for(i=0;i<8;i++) caijimima[i]=0; xianshi3(); delay(30000); xianshi5(); if(y==3) { y=0; red=0; flag=1; //三次密碼錯誤,鎖定鍵盤參數賦值 bao=0; jishuqi(); //鎖定10S計數開始 } } } else { k=0; j=0; xianshi3();//請繼續輸入8位完整密碼后在按確認鍵! delay(30000); xianshi5(); } } if(gnjianhao==2) //清零鍵判斷 { for(i=0;i<7;i++) { caijimima[i]=0; } lcd_wcom(0x01); xianshi(); k=0; j=0; } if(gnjianhao==1) //退格鍵判斷 { if(k==1&&j==1) { xianshi3();//錯誤,請輸入8位完整密碼! delay(30000); xianshi5(); red=0; delay(200); red=1; delay(200); red=0; delay(200); red=1; j=j-1; k=k-1; } if(j!=0&&k!=0) { j=j-2; k=k-2; xianshi5(); xianshi1(j); } } if(gnjianhao==4) ; if(gnjianhao==5) ; } } } } void main () { lcd_init(); //液晶初始化 delay(30); xianshi(); jishuqi1(); while (1) { key(); //按鍵子程序 flag2=j; //將按鍵次數參數賦值給flag2 if(flag2==9) //超過九次,清零 flag2=0; lcd_wcom(0x80+0x01); lcd_wdat(table6[flag2]); //顯示按鍵次數 if(P2==0xf0) //判斷有沒有按鍵按下 { lcd_wcom(0x80+0x0f); lcd_wdat(table6[l]); //沒按鍵按下,就顯示倒計時 lcd_wcom(0x80+0x0e); lcd_wdat(table6[z]); } else { l=0; z=0; //有按鍵按下,這停止倒計時并且清零 T0_NUM=0; T0_NUM1=0; } } } |
a2463696241 發表于 2020-5-21 01:23 有的 你需要 我可以給你 |
老哥還有板子嗎? |
最近幾天會更新新的PCB電路圖和加了注釋的程序。![]() ![]() |
4、還有1602的接口反了,液晶需要反插。 5、矩陣鍵盤的鍵值需要更改!(現在的程序里已修改過來) 6、液晶顯示的程序后面的注釋未修改,不影響程序的運行。 改天把24C02和定時模塊添加到程序后,再繼續更新。 |
更正一下PCB設計: 1、10K可調電阻的2腳和3腳接反了,需要反過來接。 2、繼電器的的1.2引腳接反了,需要反接。 3、蜂鳴器電路需要重新設計。 |
我這里還有多余的印制電路板,感興趣的小伙伴可以聯系我,我免費送板子,你只需付運費即可! |