《基于单片机的密码锁设计课程设计报告.doc》由会员分享,可在线阅读,更多相关《基于单片机的密码锁设计课程设计报告.doc(38页珍藏版)》请在三一办公上搜索。
1、物理与电气工程学院课程设计报告基于单片机的密码锁设计 作者 专业 年级 指导教师 成 绩 日期 2013.10.6 基于单片机的密码锁设计(安阳师范学院 物电学院, 河南 安阳 455000)摘要:电子密码锁是一种通过密码输入来控制电路或是芯片工作,从而控制机械开关的闭合,完成开锁、闭锁任务的电子产品。它的种类很多,有简易的电路产品,也有基于芯片的性价比较高的产品。现在应用较广的电子密码锁是以芯片为核心,通过编程来实现的。本文以AT89C52单片机为核心器件,结合按键电路、LCD数码管显示电路、报警指示电路和开锁机构,利用单片机灵活的编程设计和丰富的I/O端口,及其控制的准确性通过软件程序来控
2、制整个系统实现电子密码锁的基本功能,其主要具有如下功能:密码通过键盘输入,若密码正确,则将锁打开密码输入错误,蜂鸣器将报警提示用户可以自由设定密码与万年历相结合本密码锁具有设计方法合理,简单易行成本低,安全实用等特点,具有一定的推广价值。关键词:单片机 液晶显示器 键盘 万年历1引言:随着人们生活水平的提高, 日常生活和工作中的住宅与部门的安全防范、单位的文件档案、财务报表以及一些个人资料的保存等一系列安全防盗问题变的尤其突出。传统的机械锁由于其构造的简单,被撬的事件屡见不鲜,且人们常需携带多把钥匙, 使用极不方便, 一旦钥匙丢失安全性即大打折扣。随着科学技术的不断发展,人们对日常生活中的安全
3、保险器件的要求越来越高。为满足人们对锁的使用要求,增加其安全性,用密码代替钥匙的密码锁应运而生。密码锁因具有安全性高、成本低、功耗低、易操作等优点,受到了广大用户的青睐。据有关资料介绍,电子密码锁的研究从20世纪30年代就开始了,在一些特殊场所早就有所应用。但当时多半是配合机械锁一起作用且存在着诸如体积较大,成本较高,可靠性较低等缺点一时难以普及。20世纪80年代后,随着信息技术、集成电路、半导体技术的发展,电子密码锁的设计也取得了快速的进步。目前,在西方发达国家,电子密码锁技术相对先进,种类齐全,电子密码锁已被广泛应用于安全处所,而我国在此点上这稍有落后。2方案论证: (1)现今常见的密码锁
4、设计方案一种是中规模集成电路控制的方案,对于采用集成电路控制的方案,其中的编码电子锁电路分为编码电路、控制电路、复位电路、解码电路、防盗报警电路、门铃电路,而电子锁主要由输入元件、电路(包括电源)以及锁体三部分组成。显然此种方案的物理实现结构较为复杂且重新设置密码、输入密码的操作过程也会给用户带来一定的不方便;(2)另一种是单片机控制的方案,由于单片机灵活的编程设计和丰富的I/O端口,及其控制的准确性,不但能实现基本的密码锁功能,还能添加掉电存储、声光提示甚至添加遥控控制功能,但其也有一定的局限性,就在于其控制原理的复杂以及要求设计人员具有更加良好的程序设计能力,调试较为繁琐,否则程序一旦跑飞
5、将造成意想不到的损失。通过对这两种方案的优缺点比较,再考虑到本人自己对单片机设计具有一定的基础,所以此次选择利用单片机来进行密码锁的设计。3 结果与讨论3.1.1 AT89C52介绍 单片机主控电路的主要元件是AT89c52,其外型如图 AT89C52是51系列单片机的一个型号,它是ATMEL公司生产的。是一个低电压,高性能CMOS 8位单片机,片内含8k bytes的可反复擦写的Flash只读程序存储器和256 bytes的随机存取数据存储器(RAM),器件采用ATMEL公司的高密度、非易失性存储技术生产,兼容标准MCS-51指令系统,片内置通用8位中央处理器和Flash存储单元,功能强大的
6、AT89C52单片机可为您提供许多较复杂系统控制应用场合。 AT89C52有40个引脚,32个外部双向输入/输出(I/O)端口,同时内含2个外中断口,3个16位可编程定时计数器,2个全双工串行通信口,2个读写口线,AT89C52可以按照常规方法进行编程,但不可以在线编程(S系列的才支持在线编程)。其将通用的微处理器和Flash存储器结合在一起,特别是可反复擦写的Flash存储器可有效地降低开发成本。 3.1.2 AT24C02简介AT24C02是美国Atmel公司的低功耗CMOS型E2PROM,内含256*8位存储空间,具有工作电压宽(2.5V5.5V),擦写次数多(大于10000次),写入速
7、度快(小于10ms),抗干扰能力强,数据不易丢失,体积小等特点。并且它是采用I2C总线式进行数据读写的串行操作,只占用很少的资源和I/O线。AT24C02有一个16字节页写缓冲器,该器件通过I2C总线接口进行操作,还有一个专门的写保护功能。AT24C02的引脚如图3-9,各引脚功能如下:SCL:串行时钟输入管脚,用于产生器件所有数据发送或接收的时钟。SDA:双向串行数据/地址管脚,用于器件所有数据的发送或接收。A0、A1、A2:器件地址输入端。这些输入脚用于多个器件级联时设置器件地址,当这些脚悬空时默认值为0。使用AT24C02最大可级联8个器件,如果只有一个24C02被总线寻址,这三个地址输
8、入脚A0、A1、A2可悬空或连接到VSS。图3-9 AT24C02引脚图WP:写保护。如果WP管脚连接到Vcc,所有的内容都被写保护,只能读。当WP管脚连接到Vss或悬空,允许器件进行正常的读/写操作。VSS:电源地(GND)。VCC:电源电压(5V)。3.1.3时钟芯片DS1302 DS1302 是DALLAS 公司推出的涓流充电时钟芯片,内含有一个实时时钟/日历和31 字节静态RAM,通过简单的串行接口与单片机进行通信实时时钟/日历电路.提供秒分时日日期.月年的信息,每月的天数和闰年的天数可自动调整时钟操作可通过AM/PM 指示决定采用24 或12 小时格式.DS1302 与单片机之间能简
9、单地采用同步串行的方式进行通信,仅需用到三个口线:1 RES 复位,2 I/O 数据线,3 SCLK串行时钟.时钟/RAM 的读/写数据以一个字节或多达31 个字节的字符组方式通信. DS1302 的引脚功能排列及描述如下所示. 管脚描述:X1 X2 32.768KHz 晶振管脚GND 地RST 复位脚I/O 数据输入/输出引脚SCLK 串行时钟Vcc1,Vcc2 电源供电管脚3.1.4 LCD12864液晶 带中文字库的128X64 是一种具有4 位/8 位并行、2 线或3 线串行多种接口方式,内部含有国标一级、二级简体 中文字库的点阵图形液晶显示模块;其显示分辨率为12864, 内置819
10、2 个16*16 点汉字,和128 个16*8 点ASCII 字符 集.利用该模块灵活的接口方式和简单、方便的操作指令,可构成全中文人机交互图形界面。可以显示84 行1616 点 阵的汉字. 也可完成图形显示.低电压低功耗是其又一显著特点。由该模块构成的液晶显示方案与同类型的图形点阵液晶 显示模块相比,不论硬件电路结构或显示程序都要简洁得多,且该模块的价格也略低于相同点阵的图形液晶模块。基本特性(1) 低电源电压(VDD:+3.0-+5.5V)(2)显示分辨率:12864 点(3)内置汉字字库,提供8192 个1616 点阵汉字(简繁体可选)(4)内置128 个168 点阵字符(5)2MHZ
11、时钟频率(6)显示方式:STN、半透、正显(7)驱动方式:1/32DUTY,1/5BIAS(8)视角方向:6 点(9)背光方式:侧部高亮白色LED,功耗仅为普通LED 的1/51/10(10)通讯方式:串行、并口可选(11)内置DC-DC 转换电路,无需外加负压(12)无需片选信号,简化软件设计(13)工作温度: 0 - +55 ,存储温度: -20 - +60 LCD12864实物图3.2原理设计 整体电路设计方案: 本次课程设计准备实现的功能有分两个模块,一是万年历显示功能,二是密码锁功能,让两个模块在12864液晶上可以实时的分屏显示。首先是选择功能,选择万年历或者密码锁功能。当选入密码
12、锁功能时,提示“请输入密码”当连续三次输入错误时,则警报器会响,并且密码锁会自动回到初始界面。密码输入正确后则提示开锁成功,此时又两个按键可以选择:一是改密键,二则是返回主界面键。当按下改密键后则首先提示输入旧密码,旧密码输入完成后再提示输入两遍新密码,两遍新密码输入完成后则提示修改成功,并返回主界面。当修改密码时旧密码输入错误或两遍新密码输入不相同时都会提示改密不成功,并且蜂鸣器响起。3.2.1硬件电路设计 AT89C52显示模块报警电路时钟模块密码存储模块复位电路键盘输入模块 1.矩阵键盘模块按键模块为的4*4矩阵键盘,8个端连接到单片机的P1口,实现时间调整和各功能的选择。硬件电路图如图
13、所示上电后,下按键B,则进入了万年历模式,若按下按键A,则进入了密码锁模式,屏幕上会显示提醒用户输入密码的字样,此时按下按键0到9,可输入密码,密码设定为六位数,若输入正确,则屏幕上显示密码输入正确,此时指示灯被点亮,否则会显示密码输入错误,输错三次,蜂鸣器会报警。按键F用于清除一个字符。按键E为确认键,输入密码的过程中,当输入的数够六位以后,按下该键确认即可。按键C为改密键。2. 时钟ds1302模块 X1和X2是振荡源,外接32.768kHz晶振。RST是复位/片选,通过把RST输入驱动置高电平来启动所有的数据传送,VCC1接5V纽扣电池,VCC2则外接电源VCC。3.AT24C02密码存
14、储模块 4.蜂鸣器电路 本次设计用9012型号三极管来驱动蜂鸣器。3.3软件设计: 本次设计因考虑到需要实物实现的功能较多,所需要的模块较多,程序比较复杂,所以运用模块化编程的方式来编写程序。 软件设计流程图如下:开锁有按键按下LCD初始化Y 有键按下? N 按开锁键? YY 万年历输入密码 Y 确认程序N输入密码正确?错误次数三次? N Y报警程序 开锁成功Y Y按下改密键? N返回初始化Y输入旧密码 输入密码正确?输入两遍新密码 Y改密不成功两遍密码相同? 改密成功 返回3.4调试结果分析: 3.4.1.硬件调试 1.当电路板焊好通上电时发现12864液晶屏正常亮了。但当将程序烧到芯片时,
15、发现液晶屏不能显示字符,当旋转下LCD调节背光的螺丝后,屏幕能正常显示了。 2.开始时按键不管用,经用万用表检测后,发现任一按键当按下时,连接行的四个端口均全部置0. 不能读出相应键值。最后发现有链接短路的现象。当把短路的线划断后,按键恢复正常了。 3.4.2软件调试 开始时写程序时是分两大块内容进行的,万年历与密码锁。两个调试时都是分别独立调试的。而密码锁则是每个模块逐个调试,调试好了再连在一起总调。 4.设计总结做这次的课程设计对我们这个小组来说是一个不小的挑战,但我们一直在努力,有问题就去克服,有不会的就去做,最后我们成功了,在规定的前六周内完成了课程设计。说实话这次的做课程设计的成功对
16、我们是一个很大的鼓励。只要去做,只要去学,只要肯下功夫学,没有完不成的事!别人做的我们一样能做。在做课程设计的过程也让我们学到了很多东西,对于我自身来说 ,第一是知道了模块化编程的形式及使用方法。第二,通过这几周的努力与学习,让自己的编程水平也有了很大提升。第三,做硬件时不仅要合理的布局原件,而且要考虑到链接外接电路的端口问题。这都是很重要收获。在这过程中遇到了很多问题,所以在这里也要真诚的感谢老师和同学们的帮助。 参考文献 1 华成英,童诗白.模拟电子技术基础M 北京:高等教育出版社,20062 杨路明. C语言程序设计教程M 北京:北京邮电大学出版社,20053 胡骅, 陈明.Protel
17、 99 SE 原理图与PCB设计M 北京:机械工业出版社,2005 5 胡汉才.单片机原理及其接口技术M. 北京:清华大学出版社,2006,3 附图1 原理图附图2 PCB图 4. 元器件清单元器件规格/型号数量单片机AT89C521存储芯片AT24C021发光二极管1三极管PNP1蜂鸣器1电阻2202电阻1K2电阻10k2排阻10k1电解电容22uf 1 瓷片电容30pf 2 晶振 2 液晶12864 按键开关 16 时钟芯片Ds1302 1源程序附页main.c主程序 #includereg52.h#include24c02.h#includekey.h#include12864.h#in
18、cludereact.h#include1302.hvoid main()lcd_init();init();while(1)system_start();24c02.c 存储芯片子程#includereg52.h#includeintrins.h#include24c02.h#define uint unsigned int#define uchar unsigned charsbit SDA=P24;sbit SCL=P25;bit flag;uchar read_password6;void delayms(unsigned int xms);void delaynp()_nop_();
19、_nop_();_nop_();_nop_();void init() /24C02初始化SDA=1;delaynp();SCL=1;delaynp();void start() /起始信号SCL=1;SDA=1;delaynp();SDA=0;delaynp();SCL=0;void stop()/终止信号SCL=0;SDA=0;delaynp();SCL=1;delaynp();SDA=1;void check() /应答检查SDA=1;SCL=1;flag=0;CY=SDA;if(CY=1)flag=1;/应答标志位,非应答else if(CY=0)SCL=0;void writebyt
20、e(uchar temp) /写一个字节uchar count=8;while(count-)SCL=0;delaynp();if(temp&0x80)=0x80)SDA=1; else SDA=0;delaynp();SCL=1;delaynp();temp=1; SCL=0;uchar readbyte() /读一个字节uchar count=8;uchar byte,rebyte;SCL=0;while(count-)delaynp();SDA=1;SCL=1;delaynp();if(SDA)byte=byte|0x01;elsebyte=byte&0xfe;SCL=0;rebyte=
21、byte;byte=1;return(rebyte);void wrtorom(uchar addr,uchar temp) /向地址addr中写入一个字节start();writebyte(0xa0);check();while(flag);writebyte(addr);check();while(flag);writebyte(temp);check();while(flag);stop();delayms(50);uchar refrrom(uchar addr)/从地址addr中读出数据uchar i;start();writebyte(0xa0); /伪写check();while
22、(flag);writebyte(addr);check();while(flag);start();writebyte(0xa1);check();while(flag);i=readbyte();check();while(!flag);stop();delayms(50);return(i);void writepage(uchar addr,uchar temp,uchar n) /写入若干字节uchar i;uchar *p;p=temp;for(i=0;in;i+)wrtorom(addr+i,*(p+i);void readpage(uchar addr,uchar temp,u
23、char n) /读出若干字节uchar i;uchar *p;p=temp;for(i=0;i0;i-)for(j=110;j0;j-);void writecmd(uchar cmd) /写命令RS=0;RW=0;EN=0;P0=cmd;delayms(5);EN=1;delayms(5);EN=0;void writedat(uchar dat) /写数据RS=1;RW=0;EN=0;P0=dat;delayms(5);EN=1;delayms(5);EN=0;void lcd_pos(uchar X,uchar Y)uchar pos;if(X=0)X=0x80;else if(X=1
24、)X=0x90;else if(X=2)X=0x88;else if(X=3)X=0x98;pos=X+Y;writecmd(pos);void lcd_dis(uchar X,uchar Y,uchar *p)lcd_pos(X,Y);while(*p)writedat(*p);p+; void lcd_init()/dula=0;/wela=0;delayms(10);writecmd(0x30);delayms(5);writecmd(0x0c);delayms(5);writecmd(0x01);delayms(5);key.c按键扫描子程序#includereg52.h#includ
25、ekey.h#define uint unsigned int#define uchar unsigned charuchar key;void delayms(unsigned int xms);uchar keyscan()uchar temp;P1=0xfe;temp=P1;temp=temp&0xf0;if(temp!=0xf0) /行扫描delayms(10); /延时消抖动if(temp!=0xf0)/稳定以后再扫描temp=P1;switch(temp)case 0xee:key=0;break;case 0xde:key=1;break;case 0xbe:key=2;brea
26、k;case 0x7e:key=3;break; while(temp!=0xf0) /等待按键释放 temp=P1; temp=temp&0xf0; return(key);P1=0xfd;temp=P1;temp=temp&0xf0;if(temp!=0xf0)delayms(10);if(temp!=0xf0)temp=P1;switch(temp)case 0xed:key=4;break;case 0xdd:key=5;break;case 0xbd:key=6;break;case 0x7d:key=7;break;while(temp!=0xf0) temp=P1; temp=t
27、emp&0xf0; return(key);P1=0xfb;temp=P1;temp=temp&0xf0;if(temp!=0xf0)delayms(10);if(temp!=0xf0)temp=P1;switch(temp)case 0xeb:key=8;break;case 0xdb:key=9;break;case 0xbb:key=10;break;case 0x7b:key=11;break;while(temp!=0xf0) temp=P1; temp=temp&0xf0; return(key);P1=0xf7;temp=P1;temp=temp&0xf0;if(temp!=0x
28、f0)delayms(10);if(temp!=0xf0)temp=P1;switch(temp)case 0xe7:key=12;break;case 0xd7:key=13;break;case 0xb7:key=14;break;case 0x77:key=15;break;while(temp!=0xf0) temp=P1; temp=temp&0xf0; return(key);void keydown()uchar temp; P1=0x0f; temp=P1;if(temp&0x0f)!=0x0f)key=keyscan(); 1302. c日历子程序# include reg5
29、1.h# include intrins.h#include 1302.h#includekey.h#include12864.h#includereact.h# define uchar unsigned char#define uint unsigned int uchar table1=课程设计:;uchar table2=I2C 密码锁;uchar table3=年月日时分秒周;uchar table8=一二叁四五六日;sbit rs=P35; /s=P20;sbit rw=P36; / rw=P21;sbit e=P34; / e=P22;/sbit psb=P27; unsigne
30、d char code digit10=0123456789;sbit SCLK=P20;/ SCLK=P10;sbit DATA=P21; /DATA=P11;sbit RST =P22; / RST =P12;/ sbit deng=P27;/ sbit fenming=P37; /* 函数功能: 延时若干微秒 入口参数 n*/ void delaynus(uint n) uint i; for(i=0;in;i+); /* 延时若干毫秒* void delayms(uint n) uint i,j; for(i=0;i0;j-); *函数功能:向DS1302写一个字节数据入口参数:x/*
31、/ void write1302(uchar dat) uchar i; SCLK=0; delaynus(2); for(i=0;i=1; /* 函数功能: 向DS1302在写入命令的情况下写入一个字节数据 入口参数:命令:cmd 数据:dat*/ void writeset1302(uchar cmd ,uchar dat) RST=0; SCLK=0; RST=1; delaynus(2); write1302(cmd); write1302(dat); SCLK=1 ; RST=0; /*8 函数功能:从DS1302中读取一个字节数据/*/ uchar read1302(void) u
32、char i,dat; / SCLK=1; /此处不能加这一句 delaynus(2); for(i=0;i=1; if(DATA=1) dat=dat|0x80; SCLK=1; delaynus(2); SCLK=0; delaynus(2); return dat;/* 函数功能:在写入命令字的情况下从1302中读取一个字节的数据 入口参数:命令子:cmd*/ uchar readset1302(uchar cmd ) uchar dat; RST=0; SCLK=0; RST=1; write1302(cmd); dat=read1302(); SCLK=1; RST=0; return dat; /* 函数功能: 对1302初始化设置/*/void init_ds1302() unsigned char flag; flag= readset1302(0x81);if(flag&0x80) /判断时钟芯片是否关闭 writeset1302(0x8E,0x00); /根据写状态寄存器命令字,写入不保护指令 writeset1302(0x80,(0/10)4|(0%10); /根据写秒寄存器命令字,写入秒的初始值writeset1302(0x82,(35/10)4|(35