簡介
大家好,這篇文章的內容是關于如何用51單片機來制作一個電子密碼鎖的教程,通過這篇教程可以讓剛入門的朋友了解矩陣鍵盤、LCD1602的使用方法,以及密碼輸入和修改的程序介紹,我會對每個部分進行詳細的介紹。
首先我們來看一下這個密碼鎖要實現哪些功能:
可通過矩陣鍵盤進行密碼的輸入和修改。
可通過LCD1602進行界面的顯示。
在了解了我們需要實現的功能后我們就可一開始進行軟硬件的設計了。本次密碼鎖的硬件部分我使用Proteus來進行仿真。
硬件設計
首先我們進行硬件的設計,密碼鎖的硬件部分還是很簡單的,首先我們需要一個51單片機的最小系統,在Proteus中芯片并不需要外接晶振,直接放上芯片就可以使用,我選擇AT89C52單片機,并給P0口外接一排上拉電阻來提升驅動能力,
接下來是界面顯示部分,之前說過顯示部分使用的是LCD1602,LCD的電路如下圖,
首先我來簡單介紹一下LCD1602的引腳功能:
VSS:接地
VDD:接電源
V0:對比度調整端,使用時可接電位器接地進行對比度調節
RS:寄存器選擇,高電平選擇數據寄存器,低電平選擇指令寄存器
RW:讀寫信號線,高電平讀,低電平寫
E:使能端,下降沿寫操作,高電平讀操作
DB0:數據總線最低位
DB1:數據總線1位
DB2:數據總線2位
DB3:數據總線3位
DB4:數據總線4位
DB5:數據總線5位
DB6:數據總線6位
DB7:數據總線7位
A:背光電源正極
K:背光電源負極
我們可以看到LCD1602一共有上述16個引腳,我來根據圖中的接法來介紹一下各個引腳的用法。
VDD和A分別用于給LCD和背光板供電,VSS和K為負極接地,仿真里面我們不需要接A、K引腳。
V0腳就是圖中的VEE,這個腳使用來調節LCD的字符對比度,直接接地的時候對比度最高,不過容易出現鬼影,在實際使用的時候我們可以將這個腳通過一個10K的電位器接地來進行對比度的調節,在仿真里我就直接接地了。
RS腳是寄存器選擇腳,這個腳我接到單片機的P3.5腳上,我們通過改變這個腳的高低電平可以選擇給LCD發送數據還是發送指令。
RW腳是用來設置對LCD的讀寫操作的,因為在這里我們不需要對LCD進行讀取操作,所以我就直接將這個腳接地了,也可以通過IO口來對RW進行設置。
E腳是LCD的使能端,仿真中接的單片機的P3.4腳。
最后的D0~D7腳就是LCD的數據腳,我們將這8個腳接到單片機接了上拉電阻的P0腳,這樣就可以給LCD發送指令或數據了。
然后我們需要一個鍵盤進行密碼的輸入和修改,在Proteus里我們可以直接搜索KEYPAD來添加矩陣鍵盤,在這里我們使用一個3*4的鍵盤就夠了,引腳與單片機的連接如下,
也可以使用按鍵自己連接一個矩陣鍵盤有助于對程序的理解。
軟件設計
在介紹完硬件部分的設計后,我們就可以開始編寫程序了,首先講一下矩陣鍵盤的程序,
int keyboard() //鍵盤掃描 { P2 = 0xf7; k = P2; k = k & 0xf0; if(k == 0xf0) { kf = 0; } if(k != 0xf0) { delay(4); k = P2; k = k & 0xf0; if(k != 0xf0) { switch(k) { case 0xe0: key = 88;mod = 1;kf = 1; break; case 0xd0: key = 0;kf = 1; break; case 0xb0: key = 88;kf = 1; break; case 0x70: key = 88;kf = 1; break; } } } P2 = 0xfb; k = P2; k = k & 0xf0; if(k != 0xf0) { delay(4); k = P2; k = k & 0xf0; if(k != 0xf0) { switch(k) { case 0xe0: key = 7;kf = 1; break; case 0xd0: key = 8;kf = 1; break; case 0xb0: key = 9;kf = 1; break; case 0x70: key = 88;kf = 1; break; } } } P2 = 0xfd; k = P2; k = k & 0xf0; if(k != 0xf0) { delay(4); k = P2; k = k & 0xf0; if(k != 0xf0) { switch(k) { case 0xe0: key = 4;kf = 1; break; case 0xd0: key = 5;kf = 1; break; case 0xb0: key = 6;kf = 1; break; case 0x70: key = 88;kf = 1; break; } } } P2 = 0xfe; k = P2; k = k & 0xf0; if(k != 0xf0) { delay(4); k = P2; k = k & 0xf0; if(k != 0xf0) { switch(k) { case 0xe0: key = 1;kf = 1; break; case 0xd0: key = 2;kf = 1; break; case 0xb0: key = 3;kf = 1; break; case 0x70: key = 88;kf = 1; break; } } } return key; }
上面這一段是矩陣鍵盤的程序,通過改變P1口的值來進行行列檢測,同時增加一個標志位kf來判斷按鍵是否松開。有了按鍵驅動下面就可以編寫密碼輸入的函數了:
void input() //密碼輸入函數 { keyboard(); if(key!=88) { while(kf) { keyboard(); } s = (char)key; s = s | 0x30; lcd_pos(d); write_date(s); in[i] = key; i++; d++; key = 88; } }
在密碼輸入函數里我們調用鍵盤掃描函數,當有按鍵按下時我們就將對應的鍵值保存到輸入密碼的數組里,然后將每一個輸入的按鍵的鍵值顯示在LCD的顯示屏上。LCD的驅動程序會在下面講解。
現在要開始編寫LCD的驅動用來顯示輸入的數字,我們首先需要兩個函數,分別給LCD發送數據和指令,程序如下:
void write_com(uchar com) //LCD寫指令 { P0=com; rs=0; lcden=0; delay(10); lcden=1; delay(10); lcden=0; } void write_date(uchar date) //LCD寫數據 { P0=date; rs=1; lcden=0; delay(10); lcden=1; delay(10); lcden=0; }
我們可以通過寫數據的函數發送給LCD要顯示的數據,可以通過寫命令函數向LCD發送指令來對LCD進行相應的設置,相關的指令大家可以自行到網上查閱,以下列出的函數分別用來改變光標位置,LCD初始化設置和清屏。
void lcd_pos(uchar pos) //設置LCD顯示位置 { write_com(pos | 0x80); } void init() //LCD初始化 { write_com(0x38); delay(20); write_com(0x0f); delay(20); write_com(0x06); delay(20); write_com(0x01); delay(20); write_com(0x0c); delay(20); } void clear() //LCD清屏 { write_com(0x01); delay(20); }
接下來我們可以對輸入的密碼進行判斷,
void judge() //密碼判斷函數 { if(i==6) { for(f = 0;f<6;f++) { if(password[f] == in[f]) m++; } if(m==6) { es = 0; clear(); lcd_pos(0x03); write_dates("Welcome!"); delay(1200); clear(); lcd_pos(0x00); write_dates("Password:"); lcd_pos(0x45); write_dates("******"); } else { es++; clear(); lcd_pos(0x04); write_dates("Error!"); delay(1200); if(es == 3) { lcd_pos(0x45); write_dates("WARNING"); delay(5000); es = 0; clear(); } lcd_pos(0x00); write_dates("Password:"); lcd_pos(0x45); write_dates("******"); } m = 0; i = 0; d = 0x45; } }
密碼鎖的密碼為6位,當輸入6位密碼后我們就可以對密碼進行判斷,判斷過程就是將輸入密碼的數組與保存的密碼的數組通過循環進行比較,當輸入密碼正確后就會顯示歡迎界面,等待一段時間再返回密碼輸入界面,如果密碼輸入錯誤則進入錯誤界面,然后返回密碼輸入界面,我們可以檢測錯誤的次數如果錯誤次數太多可以進行類似延長等待時間等操作。
最后就是密碼修改的操作。
void change() //修改密碼函數 { if(mod==1) { lcd_pos(0x00); write_dates("OldPassword:"); input(); if(i==6) { for(f = 0;f<6;f++) { if(password[f] == in[f]) m++; } if(m==6) { mod=2; clear(); lcd_pos(0x45); write_dates("******"); } else { clear(); lcd_pos(0x04); write_dates("Error!"); delay(1200); lcd_pos(0x00); write_dates("Password:"); lcd_pos(0x45); write_dates("******"); mod=0; } m = 0; i = 0; d = 0x45; } } if(mod==2) { lcd_pos(0x00); write_dates("NewPassword:"); input(); if(i==6) { for(f = 0;f<6;f++) { password[f] = in[f]; } lcd_pos(0x44); write_dates("success!"); delay(1200); clear(); lcd_pos(0x00); write_dates("Password:"); lcd_pos(0x45); write_dates("******"); i = 0; mod = 0; d = 0x45; } } }
修改密碼需要我們先輸入正確密碼,然后會進入修改界面,再次輸入新密碼就可以保存了。過程就是用循環來更新數組內的值,這樣一個簡單的密碼鎖就做好了,不過這樣的鎖有一個缺點,就是設置的密碼不會保存,等單片機再次上電后就會恢復到最初始的密碼,要想在斷電后繼續保存密碼,我們可以使用EEPROM來進行密碼的保存,由于篇幅原因,我會在之后單獨介紹EEPROM的讀寫操作。感謝各位的觀看。

點“閱讀原文”,文章!
相關產品推薦:樹莓派4B 現貨,268元起!