单片机系统课程设计成绩评定表设计课题:基于89C51的电子密码锁的设计学院名称:电气工程学院专业班级:学生姓名:学号:指导教师:设计地点:设计时间:单片机系统课程设计课程设计名称:基于89C51的电子密码锁的设计专业班级:自动F1203学生姓名:学号:指导教师:课程设计地点:课程设计时间:单片机系统课程设计任务书目录1 硬件组成与方案设计 (5)1.1 硬件组成 (5)1.2 方案设计 (5)2 单元电路设计 (5)2.1 时钟电路设计 (5)2.2 复位电路设计 (6)2.3 键盘电路设计 (7)2.4 显示电路设计 (7)2.5 整体电路图设计 (10)3 系统软件工作流程图 (10)3.1 主程序工作流程 (10)3.2 键盘扫描程序 (11)4 系统功能实际测试 (12)4.1 程序实际编译测试 (12)4.2 单片机实际操作演示 (12)总结 (18)参考文献 (19)附录A:整体电路图 (20)附录B:详细程序 (21)概述:自从人类开始制造锁以来长期所使用的锁都是机械锁,通俗的讲就是弹子芯锁。
而传统的弹子芯锁,由于其本身锁芯密齿的有限加之开锁工具钥匙的容易复制性,使得其安全性大大降低。
随着人们生活质量的提高,如何实现安全有效的防盗这一问题受到越来越多人的关注。
传统的机械锁由于安全性能太差,被撬的事件屡见不鲜。
相比之下,电子密码锁因其保密性强,使用灵活性好,安全系数高,受到了广大用户的欢迎。
电子密码锁作为一种新型的锁,安全性有了较大的提高,还省去了传统机械锁的钥匙,使用者只要记得其密码,便可以开启,从而大大提高了防盗功能。
本文主要设计了一种以单片机AT89C51为核心的电子密码锁。
详细地介绍了该电子密码锁以及其外围电路的设计过程。
电子密码锁主要由三部分组成:键盘输入部分、单片机最小系统部分、液晶显示部分。
通过外围键盘来进行密码输入,单片机则负责把输入的密码与设定好的密码进行比对从而判断是否输入正确,而液晶显示部分则负责进行相关提示信息的显示。
1 硬件组成与方案设计1.1 硬件组成硬件组成如图1.1所示:图1.1硬件组成示意图1.2 方案设计该系统采用外围矩阵键盘来进行密码的输入,单片机则执行键盘扫描程序来获取相应的键值从而达到输入密码的功能,同时,单片机与1602液晶显示屏相连,来显示输入密码等相关提示信息方便用户使用。
当用户连续输入错误密码三次时则电子密码锁自锁,无法继续输入密码,从而提高了电子密码锁的安全2 单元电路设计2.1 时钟电路设计时钟是单片机的心脏,单片机各功能部件的运行都是以时钟频率为基准,有条不紊地工作。
因此时钟频率直接影响单片机的速度。
常用的时钟产生方法有两种:内部时钟方式以及外部时钟方式。
本设计采用的是内部时钟方式。
其中内部时钟方式是利用芯片内部的振荡器,然后在引脚XTAL1和XTAL2两端跨接晶体或陶瓷谐振器,就构成了稳定的自激振荡器。
其发出的脉冲直接送入内部时钟电路。
外接晶振时,C1和C2的值通常选择为30pF左右,C1和C2对频率有微调作用。
晶体的频率选择12MHz。
为了减少寄生电容,更好地保证振荡器稳定可靠地工作,振荡器和电容应尽可能安装得遇单片机芯片靠近。
如图2.1所示图2.1 时钟电路2.2 复位电路设计复位是单片机的初始化操作,单片机在启动运行时,都需要先复位,它的作用是CPU和系统中的其它部件都处于一个确定的初始状态,并从这个状态开始工作。
故复位关系到一个单片机系统能否可靠地工作。
本设计采用的是按键电平复位,按复位键之后复位端通过电阻与Vcc电源连通。
为保证复位可靠,应保证复位高电平持续时间大于两个机器周期,R4电阻值为200欧姆,R5电阻值为10K,C3电容值为22uF。
如图2.2所示图2.2 复位电路2.3 键盘电路设计计算机所使用的键盘有全编码键盘和非编码键盘两种,本设计采用的是非编码键盘。
非编码键盘只是简单地提供行和列的矩阵,其它工作都靠软件来完成,由于其经济实用,目前在单片机应用系统中多采用这种方法。
本设计中采用了非编码矩阵键盘,通过四根行线四根列线与单片机相连,通过单片机内部程序从而实现计算键值,进行密码输入的功能。
如图2.3所示图2.3键盘电路2.4 显示电路设计单片机的显示方式有点阵显示,数码管显示以及液晶屏显示。
本设计采用的是液晶屏显示方式。
液晶显示模块已作为很多电子产品中都可以看到,显示的主要是数字、专用符号和图形。
1602型LCD显示模块具有体积小,功耗低,显示内容丰富等特点。
1602型LCD可以显示2行16个字符,有8位数产品的通过器件,如在计算器、万用表、电子表及很多家用电子据总线D0-D7和RS,R/W,EN 三个控制端口,工作电压为5V,并且具有字符对比度调节和背光功能。
引脚功能说明:第1脚:VSS为地电源。
第2脚:VDD接5V正电源。
第3脚:VL为液晶显示器对比度调整端,接正电源时对比度最弱,接地时对比度最高,对比度过高时会产生“鬼影”,使用时可以通过一个10K的电位器调整对比度。
第4脚:RS为寄存器选择,高电平时选择数据寄存器、低电平时选择指令寄存器。
第5脚:R/W为读写信号线,高电平时进行读操作,低电平时进行写操作。
当RS和R/W共同为低电平时可以写入指令或者显示地址,当RS为低电平R/W为高电平时可以读忙信号,当RS为高电平R/W为低电平时可以写入数据。
第6脚:E端为使能端,当E端由高电平跳变成低电平时,液晶模块执行命令。
第7~14脚:D0~D7为8位双向数据线。
第15脚:背光源正极。
第16脚:背光源负极。
如图2.4.1所示图2.4.1显示部分电路如图2.4.2所示图2.4.2 1602型LCD外形尺寸图2.5 整体电路图设计如图2.5所示图2.5 整体电路图3 系统工作流程图3.1 主程序工作流程主程序首先初始化外围显示电路,并显示相关信息提示用户输入密码。
用户按下确认键开始输入密码。
单片机则执行键盘扫描程序,获取相应键值与设定密码进行比对,若正确则执行解锁。
输入错误则提醒用户再一次输入,若连续错误输入三次时电子密码锁自锁,用户无法继续输入密码。
程序流程图如图3-1所示图3.1 主程序流程图3.2 键盘扫描程序键盘扫描程序是本设计的核心程序,是单片机能否正确读取按键对应键值的关键所在。
通过软件延时来去除按键时的抖动影响,之后通过单片机内部程序来获取相应键值。
键盘扫描流程图如图3-2所示。
图3.2 键盘扫描流程图4 系统功能实际测试4.1 程序实际编译测试在Keil编译环境下编译通过,0错误,0警告。
生成HEX文件4.2 单片机实际操作演示在单片机实际操作过程中,使用的程序烧录软件为STC-ISP软件,该软件可以对51内核的单片机进行相关程序的烧写,使用十分方便。
启动软件之后,首先软件进行相应的设置。
选择单片机的型号,由于51内核的单片机具有一定的通用性,故选择了STC89C52RC型号的单片机。
接着打开前面所生成好的HEX文件。
然后设置端口,本次实际操作中选用的是端口3(COM3)与笔记本相连,故端口设置为COM3。
设置完之后的软件截图如图4.3所示。
图4.1 烧录软件设置设置完成之后点击DownLoad下载按钮,并按下单片机上的电源按键,程序烧录到单片机中,单片机开始运行程序。
(1)程序开始运行时,如下图所示。
图4.2 开始运行画面(2)按下confirm按键,开始输入密码。
如下图所示。
图4.3开始输入密码(3)密码的输入。
如下图所示。
图4.4 密码输入(4)密码输入错误时,显示相应信息。
如下图所示。
图4.5 密码输入错误(5)当连续三次输入密码错误时,显示相应提示信息。
如下图所示。
图4.6 连续密码错误输入3次(6)密码正确输入。
如下图所示。
图4.7 密码正确输总结学习了一年的单片机课程,自己对单片机的设计也有了一定的了解,通过这次课程设计,我得到了很多收获和体会,以及一个工程设计的基本过程。
增强了查阅参考资料,查阅手册,图表和文献资料的自学能力。
在进行本系统的设计过程中虽然遇到很多的问题,比如说画图,设计等各种问题都让自己懊恼不已。
但是通过自己的思考以及与同学之间的探讨得到了一定程度的解决。
在该设计完成之后进行了模拟仿真,最终的效果还是令人满意的。
同时,由于设计的时间以及能力有限,本设计还存在着一些不合理的地方,比如用户无法自己设定密码,只能靠原始程序来进行设定。
同时采用的过于简陋的机械键盘,在用户输入密码时可能会产生误操作等。
但是从整体来看,通过这一个设计我还是得到了不少的锻炼。
使用Proteus软件进行模拟仿真,使用Keil 来进行源程序的编写,使用Visio软件来绘制流程图等。
这些都大大提高了我的动手能力,为以后的设计打下了良好的基础。
参考文献[1] 张迎新.单片微型计算机原理、应用及接口技术(第2版)[M].北京:国防工业出版社,2004[2] 祁伟, 杨亭. 单片机C51程序设计教程与实验[M].北京:北京航空航天大学出版社.[3] 楼然苗.李光飞.单片机课程设计指导[M].北京:北京航空航天大学出版社.附录A:整体电路图附录B:详细程序主函数部分:#include <reg52.h>#include"key.h"#include"lcd.h"uchar code show_0[]="Please input the password:"; uchar code show_1[]="The cipher is:" ;uchar code show_2[]="********";uchar code show_3[]="The password is wrong!";uchar code show_4[]="This is the last time,";uchar code show_5[]="Please try it tomorrow!";uchar code show_6[]="you are right!";uchar init_pswd[]={8,8,8,8,8,8,8,8};uchar pswd[8]={0};uchar pswd_1[8]={0};void play(uchar *j,uchar k) //K是显示的个数,j是地址{uchar i;for(i=0;i<k;i++){dat_w(*(j+i));delay(20);}}main(){uchar j=0,i=0,sum_1=0; loop:init();clear();gotoxy(1,0);play(show_0,16); gotoxy(2,0);play(show_0+17,10);/****密码输入****/do{key();}while(ki!=15);clear();gotoxy(1,0);play(show_1,15);do{flag=0;key();gotoxy(2,0);if(flag==1&&ki<=9){pswd[i]=ki;play(show_2,i);i++;}if(ki==14) //14则退出.break;}while(i<=8);for(i=0;i<=7;i++){sum_1=init_pswd[i]-pswd[i]+sum_1;if(sum_1!=0){clear();j++;if(j==3)clear();gotoxy(1,0);play(show_4,16);gotoxy(2,0);play(show_4+16,14);delay(500);delay(500);clear();gotoxy(1,0);play(show_5+7,16);while(1); //三次输入密码失败,自锁}gotoxy(1,0);play(show_3,16);gotoxy(2,5);play(show_3+15,7);delay(500);clear();goto loop;if(sum_1==0){clear();gotoxy(1,0);play(show_6,15);do{key();}while(ki!=13);loop1:clear();/****第一次输密码***/ i=0;do{flag=0;key();if(flag==1&&ki<=9){pswd[i]=ki;i++;clear();gotoxy(1,0);play(show_2,i);}}while(i<=7);clear();/***第二次输密码****/ i=0;sum_1=0;do{flag=0;key();if(flag==1&&ki<=9){pswd_1[i]=ki;i++;clear();gotoxy(1,0);play(show_2,i);}}while(i<=7);for(i=0;i<=7;i++){sum_1=sum_1+ pswd_1[i]-pswd[i]; }if(sum_1==0){clear();for(i=0;i<=7;i++){init_pswd[i]=pswd[1];}while(1);}if(sum_1!=0){clear();goto loop1;}}}}LCD部分#ifndef _lcd_h#include <reg52.h>#define uchar unsigned char #define uint unsigned int sbit E=P0^7;sbit RW=P0^6;sbit RS=P0^5;/***写命令***/void cmd_w(uchar cmd) {RW=0;RS=0;E=1;P2=cmd;delay(1);E=0;}/***写数据***/void dat_w(uchar dat){RW=0;RS=1;E=1;P2=dat;delay(1);E=0;}/***清屏****/void clear(void){cmd_w(0x01); //清屏cmd_w(0x02); //清屏回到左上角}/***初始化**/void init(void){cmd_w(0x38);cmd_w(0x0d);}/***光标定位****/void gotoxy(uchar x,uchar y) //x是行数,y是列数{if(x==1){cmd_w(0x80+y);}else{cmd_w(0xc0+y);}}#endifKEY部分#ifndef _key_h#define _key_h#include <reg52.h>#define uchar unsigned char#define uint unsigned intuchar ki=0,flag; //flag是按键标志ki是获得的键盘数/***1ms延时**/void delay(uint k){k=k*125;while(k--);}/***键盘编号程序**/ uchar number(uchar k) {uchar sum;switch(k){case 1:sum=0;break;case 2:sum=1;break;case 4:sum=2;break;case 8:sum=3;break;default:break;}return sum;}/***键盘程序**/key(void){uchar m,n;.P3=0x0f;delay(1);if(P3!=0x0f){P3=0x0f;delay(3);m=P3;if(m!=0x0f){m=m^0x0f;m=number(m);m=4*m;P3=0xf0;delay(1);if(P3!=0xf0){n=P3^0xf0;n=n>>4;n=number(n);ki=m+n; //ki是获得的键盘号flag=1;do.{P3=0x0f;}while(P3!=0x0f); //松开按键才可以继续}}}}#endif。