【普中】基于51单片机的矩阵电子密码锁LCD1602液晶显示 proteus仿真+程序+设计报告+讲解视频
【普中】基于51单片机的矩阵电子密码锁LCD1602液晶显示设计
- 1.主要功能:
- 讲解视频:
- 2.仿真
- 3. 程序代码
- 4. 设计报告
- 5. 设计资料内容清单&&下载链接
- 资料下载链接:
【普中】基于51单片机的矩阵电子密码锁LCD1602液晶显示设计
( proteus仿真+程序+设计报告+讲解视频)
仿真图proteus8.16(有低版本)
程序编译器:keil 4/keil 5
编程语言:C语言
设计编号:P14
1.主要功能:
基于51单片机AT89C51/52(与AT89S51/52、AT89C51/52、STC89C51/52等51内核单片机通用)
基于51单片机的密码锁LCD1602液晶显示设计
1.按键设置6位密码,输入密码若密码正确,则锁打开。显示open!开锁指示灯点亮。
2.密码可以自己修改(6位密码),必须是开始状态才能改密。为防止误操作,修改密码得输入两次。
3.若密码输入错误次数超过3次,蜂鸣器报警并且锁定键盘,需复位重新开始操作。
4.系统具有24C02有复位、掉电保存密码功能。
5.需要在Proteus软件和普中51开发板实现功能验证。
(目前仅完全适配普中开发板A234,其他普中开发板型号可能需要做代码修改或接线)
需注意仿真中51单片机芯片是兼容的,AT89C51,AT89C52是51单片机的具体型号,内核是一样的。相同的原理图里,无论stc还是at都一样,引脚功能都是一样的,程序是兼容的,芯片可以替换为STC89C52/STC89C51/AT89C52/AT89C51等51单片机芯片。
讲解视频:
仿真讲解+实物演示+代码讲解
2.仿真
开始仿真
打开仿真工程,双击proteus中的单片机,选择hex文件路径,然后开始仿真。
1、首次使用时输入:131420,对密码进行初始化,当显示:initpassword, 证明密码初始化完成,此时的密码为:000000。然后可以改密了。
(如密码忘记就再输入131420初始化,然后密码就是000000)
2.输入密码正确,LCD显示open,继电器导通模拟开锁动作。
3当输入密码错误后,LCD显示error,报警并锁定键盘3秒钟。
3. 程序代码
使用keil4或者keil5编译,代码有注释,可以结合报告理解代码含义。
//================================================================================================== //=======================================LCD1602==================================================== //================================================================================================== #define yi 0x80 //LCD第一行的初始位置,因为LCD1602字符地址首位D7恒定为1(100000000=80) #define er 0x80+0x40 //LCD第二行初始位置(因为第二行第一个字符位置地址是0x40) //----------------延时函数,后面经常调用---------------------- void delay(uint xms)//延时函数,有参函数 { uint x,y; for(x=xms;x>0;x--) for(y=110;y>0;y--); } //--------------------------写指令--------------------------- void write_1602com(uchar com)//****液晶写入指令函数**** { lcd1602_rs=0;//数据/指令选择置为指令 lcd1602_rw=0; //读写选择置为写 P0=com;//送入数据 delay(1); lcd1602_en=1;//拉高使能端,为制造有效的下降沿做准备 delay(1); lcd1602_en=0;//en由高变低,产生下降沿,液晶执行命令 } //-------------------------写数据----------------------------- void write_1602dat(uchar dat)//***液晶写入数据函数**** { lcd1602_rs=1;//数据/指令选择置为数据 lcd1602_rw=0; //读写选择置为写 P0=dat;//送入数据 delay(1); lcd1602_en=1; //en置高电平,为制造下降沿做准备 delay(1); lcd1602_en=0; //en由高变低,产生下降沿,液晶执行命令 } //-------------------------初始化------------------------- void lcd_init(void) { write_1602com(0x38);//设置液晶工作模式,意思:16*2行显示,5*7点阵,8位数据 write_1602com(0x0c);//开显示不显示光标 write_1602com(0x06);//整屏不移动,光标自动右移 write_1602com(0x01);//清显示 } //======================================================================================== //========================================================================================= //==============将按键值编码为数值========================= unsigned char coding(unsigned char m) { unsigned char k; switch(m) { case (1): k=1;break; case (2): k=2;break; case (3): k=3;break; case (4): k='A';break; case (5): k=4;break; case (6): k=5;break; case (7): k=6;break; case (8): k='B';break; case (9): k=7;break; case (10): k=8;break; case (11): k=9;break; case (12): k='C';break; case (13): k='*';break; case (14): k=0;break; case (15): k='#';break; case (16): k='D';break; } return(k); } //=====================按键检测并返回按键值=============================== void delay_uint(unsigned int i)//延时 { while(i--); } 完整代码见文末下载链接 unsigned char keynum(void) { unsigned char i, j; // 定义变量i和j分别存储行列索引 i = 0; j = 0; // 设置P1端口的低四位输出为0,高四位保持不变,准备读取键盘列信号 P1 = 0x0f; // 判断是否有键被按下(即P1端口的值不全为0x0f) if(P1 != 0x0f) { // 延时去抖,等待10ms再次检测,确保按键稳定 delay_uint(10000); // 再次检查,确认按键确实被按下 if(P1 != 0x0f) { // 根据P1的值判断是哪一行被按下 switch(P1) { case 0x0e: i = 3; break; // 第1行 case 0x0d: i = 2; break; // 第3行 case 0x0b: i = 1; break; // 第3行 case 0x07: i = 0; // 第4行 } // 设置P1端口的高四位输出为0,低四位保持不变,准备读取键盘行信号 P1 = 0xf0; // 根据P1的新值判断是哪一列被按下 switch(P1) { case 0xe0: j = 13; break; // 第1列 case 0xd0: j = 9; break; // 第2列 case 0xb0: j = 5; break; // 第3列 case 0x70: j = 1; // 第4列 } } } // 检查新获取的按键值(行列索引组合)是否与上一次的不同 if(key != i + j) { // 更新按键值并返回 key = i + j; return key; } else { // 如果按键值没有变化,返回0表示没有新按键事件 return 0; } } //=======================一声提示音,表示有效输入======================== void OneAlam(void) { beep_cnt=1; beep_time=BEEP_TIME; } //========================二声提示音,表示操作成功======================== void TwoAlam(void) { beep_cnt=2; beep_time=BEEP_TIME; } //========================三声提示音,表示错误======================== void ThreeAlam(void) { beep_cnt=3; beep_time=BEEP_TIME; } //=======================显示提示输入========================= void DisplayChar(void) { unsigned char i; if(pass==1) { //DisplayListChar(0,1,LockOpen); write_1602com(er); //在二行开始显示 for(i=0;i write_1602dat(LockOpen[i]); //显示open 开锁成功 } } else { if(N==0) { //DisplayListChar(0,1,Error); write_1602com(er); for(i=0;i write_1602dat(Error[i]); //显示错误 } } else { //DisplayListChar(0,1,start_line); write_1602com(er); for(i=0;i write_1602dat(start_line[i]);//显示开始输入 } } } } //========================重置密码================================================== //================================================================================== void ResetPassword(void) { unsigned char i; unsigned char j; if(pass==0) { pass=0; DisplayChar(); //显示错误 ThreeAlam(); //没开锁时按下重置密码报警3声 } else //开锁状态下才能进行密码重置程序 { if(ReInputEn==1) //开锁状态下,ReInputEn置1,重置密码允许 { if(N==6) //输入6位密码 { ReInputCont++; //密码次数计数 if(ReInputCont==2) //输入两次密码 { for(i=0;i if(TempPassword[i]==InputData[i]) //将两次输入的新密码作对比 i++; else //如果两次的密码不同 { //DisplayListChar(0,1,Error); write_1602com(er); for(j=0;j write_1602dat(Error[j]); //显示错误Error } ThreeAlam(); //错误提示 pass=0; //关锁 ReInputEn=0; //关闭重置功能, ReInputCont=0; DisplayChar(); break; } } if(i==6) { //DisplayListChar(0,1,ResetOK); write_1602com(er); for(j=0;j write_1602dat(ResetOK[j]); //密码修改成功,显示 } TwoAlam(); //操作成功提示 WrToROM(TempPassword,0,6); //将新密码写入24C02存储 ReInputEn=0; } ReInputCont=0; CorrectCont=0; } else //输入一次密码时 { OneAlam(); //DisplayListChar(0, 1, again); //显示再次输入一次 write_1602com(er); for(j=0;j write_1602dat(again[j]); //显示再输入一次 } for(i=0;i TempPassword[i]=InputData[i]; //将第一次输入的数据暂存起来 } } N=0; //输入数据位数计数器清零 } } } } //=======================输入密码错误超过三过,报警并锁死键盘====================== void Alam_KeyUnable(void) { P1=0x00; { beep_cnt=255; beep_time=BEEP_TIME; } } //=======================取消所有操作============================================ void Cancel(void) { unsigned char i; unsigned char j; //DisplayListChar(0, 1, start_line); write_1602com(er); for(j=0;j write_1602dat(start_line[j]); //显示开机输入密码界面 } TwoAlam(); //提示音 for(i=0;i InputData[i]=0; //将输入密码清零 } KEY=1; //关闭锁 pass=0; //密码正确标志清零 ReInputEn=0; //重置输入充许标志清零 ErrorCont=0; //密码错误输入次数清零 CorrectCont=0; //密码正确输入次数清零 ReInputCont=0; //重置密码输入次数清零 s3_keydown=0; key_disable=0; //锁定键盘标志清零 N=0; //输入位数计数器清零 }
- 资料下载链接: