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