1. 首先,需要以下元器件:数码管(用来人机交互),矩阵键盘(用于输入密码等操作),AT24c02(用于存储密码,掉电不丢失),51单片机最小系统板,电源及稳压模块等,锁结构(这部分自己想办法实现,可能还需要电机这些东西)。2. 工作原理是:首先将初始密码存入AT24C02中,IIC协议通讯的,网上例程很多。然后,在数码管显示字符,提示输入密码。其次,通过矩阵键盘输入密码,并确认,如果密码输入正确即开锁,反之,即提示错误,并提示重新输入,但次数不超过几次。最后,还可以通过矩阵键盘输入,进入设置,可以设置密码。3.代码实现,我就编写了,具体实现过程可参考工作原理即可。
#include<reg52.h> #define uint unsigned int #define uchar unsigned char #define KEY P3 //键盘输入端 #define No_key 20 //无按键时返回值 #define lcddata P2 //1602的数据输入端口 sbit lcden=P2^7; sbit lcdrs=P2^6; //0输入指令,1输入数据 sbit lcdrw=P2^5; //0向LCD写入数据或指令,1从LCD读取信息 sbit light_red=P3^4; sbit buzzer=P3^5; uchar j; //用来统计输入个数的全局变量 uchar aa; //用来在定时器中计数的全局变量 uchar code table[]="WELCOME! "; uchar code table1[]="LOCK SUCCESS!"; uchar code table3[]="LOCK FAILURE!"; uchar code table2[]="ENTER PASSWORD:"; uchar code key_table[]={12310 45611 78912 0131415}; uchar password[]={201710}; //设定初始密码 uchar save[6]; //保存输入数据 uchar conflag; uchar startflag; uchar lockflag; void delay(uint z); void wright_com(uchar com); //写命令函数 void wright_data(uchar date); //写数据函数 void init(); void display_OK(); //显示OK void delete(); uchar keyscan(); void enter_code(uchar t); //输入密码,并把输入的数据存入数组中 void confirm(); //输入密码逐一对比 void succeed_an(); void fail_an(); void lockkey(); void reset(); void display_enter(); void display_wrong(); void main(void) { uchar temp; init(); while(1) { if(lockflag) //输入错误,才会锁存 { temp=keyscan(); if(temp != No_key) { aa=0; //重新计时 if(temp==10) { lcdrw=0; //清屏 lcden=0; wright_com(0x01); reset(); light_red=1; startflag=1; //开始标志置位 } } } else { temp=keyscan(); if(temp != No_key) { if(temp==10) { lcdrw=0; //清屏 lcden=0; wright_com(0x01); reset(); startflag=1; //开始标志置位 } if(startflag) { enter_code(temp); if(temp==13) { confirm(); if(conflag) { succeed_an(); } else { fail_an(); } } if(temp==14) { delete(); } } } } } } /*显示enter*/ void display_enter() { uchar num; wright_com(0x80); for(num=0;num<13;num++) { wright_data(table2[num]); } } /*显示OK*/ void display_ok() { uchar num; wright_com(0x80); for(num=0;num<13;num++) { wright_data(table1[num]); } } /*显示错误*/ void display_wrong() { uchar num; wright_com(0x80); for(num=0;num<14;num++) { wright_data(table3[num]); } } void delete() { wright_com(0x80+0x40+j); wright_data(' '); save[--j]=0; wright_com(0x80+0x40+j); } /*复位各种变量*/ void reset() { uchar num; display_enter(); wright_com(0x80+0x40); for(num;num<6;num++) { save[num]=0; wright_data(' '); } wright_com(0x80+0x40); lockflag=0; conflag=0; j=0; } void succeed_an() { buzzer=0; display_ok(); delay(1000); buzzer=1; } void fail_an() { display_wrong(); lockkey(); } void lockkey() { lockflag=1; } void enter_code(uchar t) { if(t>=0&&t<10) { if(j==0) { wright_com(0x80+0x40); wright_data('*'); } else { wright_data('*'); } save[j++]=t; } } void confirm() { uchar k; for(k=0;k<6;k++) { if(password[k]!=save[k]) { break; } } if(k==6) { conflag=1; } } void timer0() interrupt 1 { TH0=(65536-50000)/256; TL0=(65536-50000)%256; if(lockflag) { aa++; light_red=0; if(aa>=60) { aa=0; light_red=1; lockflag=0; } } } void init() { uchar num; TMOD=1; ET0=1; EA=1; TR0=1; lcdrw=0; lcden=0; wright_com(0x38); wright_com(0x0c); wright_com(0x01); wright_com(0x80); for(num=0;num<9;num++) { wright_data(table[num]); delay(1); } } void wright_com(uchar com) { lcdrs=0; lcddata=com; delay(1); lcden=1; delay(1); lcden=0; } void wright_data(uchar date) { lcdrs=1; lcddata=date; delay(1); lcden=1; delay(1); lcden=0; } void delay(uint z) { uint xy; for(x=z;x>0;x--) for(y=110;y>0;y--); } /*键盘扫描 逐行扫描*/ uchar keyscan() { uchar temp; uchar num=No_key; KEY=0xfe; temp=KEY; temp=temp&0xf0; while(temp !=0xf0) { delay(5); temp=KEY; temp=temp&0xf0; while(temp!=0xf0) { temp=KEY; switch(temp) { case 0xee:num=1; break; case 0xde:num=2; break; case 0xbe:num=3; break; case 0x7e:num=10; break; } while(temp!=0xf0) { temp=KEY; temp=temp&0xf0; } } } KEY=0xfd; temp=KEY; temp=temp&0xf0; while(temp!=0xf0) { delay(5); temp=KEY; temp=temp&0xf0; while(temp!=0xf0) { temp=KEY; switch(temp) { case 0xed:num=4; break; case 0xdd:num=5; break; case 0xbd:num=6; break; case 0x7d:num=11; break; } while(temp!=0xf0) { temp=KEY; temp=temp&0xf0; } } } KEY=0xfb; temp=KEY; temp=temp&0xf0; while(temp!=0xf0) { delay(5); temp=KEY; temp=temp&0xf0; while(temp!=0xf0) { temp=KEY; switch(temp) { case 0xeb:num=7; break; case 0xdb:num=8; break; case 0xbb:num=9; break; case 0x7b:num=12; break; } while(temp!=0xf0) { temp=KEY; temp=temp&0xf0; } } } KEY=0xf7; temp=KEY; temp=temp&0xf0; while(temp!=0xf0) { delay(5); temp=KEY; temp=temp&0xf0; while(temp!=0xf0) { temp=KEY; switch(temp) { case 0xe7:num=0; break; case 0xd7:num=13; break; case 0xb7:num=14; break; case 0x77:num=15; break; } while(temp!=0xf0) { temp=KEY; temp=temp&0xf0; } } } return num; }
设计思路可以参考这个
https://wenku.baidu.com/view/26dce49758fafab068dc02be.html
可参考一下文章:https://www.ixueshu.com/document/3578c093f19075a0318947a18e7f9386.html
有详细的说明的