基于51单片机的电子锁设计
学院名称: 电气信息工程学院
专 业: 电子信息工程
班 级:
姓 名:
学 号:
指导教师:
摘要:随着电子产品向智能化和微型化的不断发展,单片机已成为电子产品研制和开发中首选的控制器。随着人们生活水平的提高,如何实现家庭防盗这一问题也变的尤其的突出,传统的机械锁由于其构造的简单,安全性能低,无法满足人们的需要。本设计采用单片机为主控芯片,结合外围电路,组成电子密码锁,用户想要打开锁,必先通过提供的键盘输入正确的密码才能将锁打开,密码输入错误有提示,为了提高安全性,当密码输入错误三次将报警。经实验证明,该密码锁具有设计方法合理,简单易行,成本低,安全实用等特点,符合住宅、办公室用锁要求,具有推广价值。
关键词:电子密码锁,89C51,键盘接口,LCD1602显示
Controller system design of digital lock
Abstract:With the continuous development of electronic products to intelligent and miniaturization, microcontroller has become electronic product development and the development of the preferred controller. As people living standard rise, how to realize the family anti-theft this problem is particularly prominent, the traditional mechanical lock because of its simple structure, safety performance is low, cannot satisfy the needs of the people. This design USES the single chip microcomputer as main control chip, combining with the peripheral circuit, composed of electronic trick lock, the user wants to play the lock, must first by providing keyboard input the correct password to open the lock, password input error, in order to improve the security, when the password input error three times will report to the police. Proved by the experiment, the design method of the combination lock is reasonable, simple, low cost, safe and practical characteristics, conform to the requirements of the residential, office use, locks, has promotion value.
Keywords:electronic code lock, 89C51, keyboard interface, LCD1602 display
目 录
前言 1
第1章 绪论 2
1.1 课题的意义和目的 2
1.2 课题的研究内容 2
1.3 课题的任务要求 2
第2章 系统方案设计 4
2.1系统方案设计 4
2.2 方案的选择与论证 5
2.2.1 方案的比较与论证 5
2.2.2 系统结构实现框图设计 5
第3章 系统各模块的硬件设计 7
3.1 电源模块设计 7
3.2 掉电存储模块设计 7
3.2.1 AT24C02介绍 8
3.2.2掉电存储电路设计 9
3.3 单片机控制模块设计 9
3.3.1 单片机时钟电路设计 10
3.3.2 单片机复位电路设计 11
3.4 按键模块设计 11
3.5 显示模块设计 12
3.6 蜂鸣器模块设计 14
第4章 系统软件设计 15
4.1 系统软件设计总体思路 15
4.2 系统软件主程序流程图设计 15
4.3 系统软件子程序设计 16
4.3.1按键功能程序设计 16
4.3.2 密码设置程序设计 16
4.3.3 开锁程序设计 17
第5章 系统调试与数据分析 19
5.1 硬件电路的制作和调试 19
5.1.1 硬件电路的制作 19
5.1.2 硬件电路的调试 19
5.1.3 故障方析 20
5.2 软硬件功能分析 20
5.3 测试结果分析 20
第6章 总结与展望 22
参考文献 23
致谢 24
附录1 电路原理图 25
附录2 程序 26
附录3 实物图 42
附录4 元器件清单 43
《综合工程实践报告》
前言
目前,最常用的锁是20世纪50年代意大利人设计的机械锁,其机构简单、使用方便、价格便宜。但在使用中暴露了很多缺点:一是机械锁是靠金属制成的钥匙上的不同齿形与锁芯的配合来工作的。据统计,每4000把锁中就有两把锁的钥匙齿牙相同或类似,故安全性低。二是钥匙一旦丢失,无论谁捡到都可以将锁打开。三是机械锁的材料大多为黄铜,质地较软,容易损坏。四是机械锁钥匙易于复制,不适于诸如宾馆等公共场所使用。由于人们对锁的安全性,方便性等性能有更高的要求,许多智能锁(如指纹辨别、IC卡识别)也相继问世,但这类产品的特点是针对特定指纹或有效卡,但能适用于保密要求高且仅供个别人使用的箱、柜、房间,其成本一般较高,在一定程度上限制了这类产品的普及和推广。
电子密码锁是一种通过密码输入来控制电路或是芯片工作,控制机械开关的闭合,完成开锁、闭锁任务的电子产品。它的种类很多,有简易的电路产品,也有基于芯片的性价比较高的产品。现在应用较广的电子密码锁是以芯片为核心,通过编程来实现的。其性能和安全性已大大超过了机械锁,特点如下:
1.保密性好,编码量多,远远大于弹子锁。随机开锁成功率几乎为零。
2.密码可变。 用户可以经常更改密码,防止密码被盗,同时也可以避免因人员的更替而使锁的密级下降。
3.误码输入保护。当输入密码多次错误时,报警系统自动启动。
第1章 绪论
1.1 课题的意义和目的
随着人们生活水平的提高,电子密码防盗锁作为防盗卫士的作用日趋重要。电子密码防盗锁用密码代替钥匙,不但省去了佩戴钥匙的烦恼,也从根本上解决了普通门锁保密性差的缺点。根据国外的统计资料显示,装有电子防盗装置的商业区或居民区盗窃犯罪率平均下降30%左右。目前西方发达国家已经大量地应用这种智能门禁系统,但在我国的应用还不广泛,成本还很高。键盘式电子密码在键盘上输入,与打电话差不多,因而易于掌握,其突出优点是“密码”是记在被授权人脑子里的数字和字符,既准确又可靠,不会丢失,难以被窃。
本设计系统主机采用8051单片机,MCS-51单片机的程序存储器和数据存储器的地址空间是相互独立的,而且程序存储器一般为ROM或EPROM,只能读出不能写入。扩展用的程序存储器芯片大多采用EPROM芯片,最大可扩展到64K字节。该设计使用矩阵键盘输入,LCD1602显示输入密码, AT24C01存储器存储密码。密码正确,二极管发光。输入密码错误次数超过三次则系统报警,蜂鸣器发出报警音。
1.2 课题的研究内容
本设计采用单片机为主控芯片,结合外围电路,组成电子密码锁,用户想要打开锁,必先通过提供的键盘输入正确的密码才能将锁打开,密码输入错误有提示,为了提高安全性,当密码输入错误三次将报警。密码可以由用户自己修改设定,锁打开后才能修改密码。修改密码之前必须再次输入密码,在输入新密码时候需要二次确认,以防止误操作。
1.3 课题的任务要求
主要完成以下功能:
1、设置6位密码,密码通过键盘输入,若密码正确,则将锁打开。
2、密码可以由用户自己修改设定(只支持6位密码),锁打开后才能修改密码。修改密码之前必须再次输入密码,在输入新密码时候需要二次确认,以防止误操作。
3、报警、锁定键盘功能。密码输入错误显示器会出现错误提示,若密码输入错误次数超过3次,蜂鸣器报警并且锁定键盘。
4、AT24C02保存密码,支持复位保存,掉电保存功能。
第2章 系统方案设计
2.1系统方案设计
本设计采用STC89C52单片机为主控芯片,结合外围电路矩阵键盘、液晶显示器LCD1602和密码存储AT24C02等部分组成。其中矩阵键盘用于输入数字密码和进行各种功能的实现。由用户通过连接单片机的矩阵键盘输入密码,后经过单片机对用户输入的密码与自己保存的密码进行对比,从而判断密码是否正确,然后控制引脚的高低电平传到开锁电路或者报警电路控制开锁还是报警,有以下几种方案可供选择。
方案一:选用单片机作为系统的核心部件,实现控制与处理的功能。单片机具有资源丰富、速度快、编程容易等优点。该方案的设计框图如图1所示:
图1 方案一设计框图
方案二:采用数字电路控制,用以74LS112双JK触发器构成的数字逻辑电路作为密码锁的核心控制,将密码保存在JK触发器中,与输入密码通过比较器比较,判断结果是否相符合。该方案的设计框图如图2所示。
图2 方案二设计框图
2.2 方案的选择与论证
2.2.1 方案的比较与论证
比较以上两个方案,在同样能达到技术指标要求的前提下。采用数字电路设计的方案好处就是设计简单,但控制的准确性和灵活性差,故不采用。利用单片机内部的随机存储器(RAM)和只读存储器(ROM)及其引脚资源,外接液晶显示(LCD),键盘输入等实现数据的处理传输和显示功能,基本上能实现设计指标。因此综合考虑,本系统采用方案一。
2.2.2 系统结构实现框图设计
设计采用单片机为主控芯片,结合外围电路,组成电子密码控制系统,密码锁共6位密码,每位的取值范围为0~9,用户可以自行设定和修改密码,每个密码按键都有声提示。用户想要打开锁,必先通过提供的键盘输入正确的密码才可以,密码输入错误有提示,为了提高安全性,当密码输入错误三次将报警,期间输入密码无效,以防窃贼多次试探密码。方案具体如下:
(1)矩阵键盘:矩阵键盘的工作过程可分为两步:第一步是CPU首先检测键盘上是否有键按下;第二步是识别哪一个键按下。
(2)复位电路:STC89C51的复位输入引脚RST为单片机提供初始化的手段,可以使程序从指定处开始执行,在STC89C51的时钟电路工作后,只要RST引脚上出现两个机器周期以上的高电平时,即可产生复位操作。只要RST保持高电平,则单片机循环复位。只要当RST有高电平变为低电平以后,单片机才从0000H地址开始执行程序,本系统采用按键复位方式的复位电路,当复位键按下,系统自动切换到初始状态。
(3)时钟电路:STC89C51的时钟可以有两种方式,一种是内部方式,利用芯片内部的振荡电路;另一种为外部方式。采用内部振荡方式。STC89C51内部有一个用于构成振荡器的高增益反相放大器,引脚XTAL1和XTAL2分别是此放大器的输入端和输出端,这个放大器作为反馈元件的片外晶体和陶瓷谐振器一起构成一个自激振动器。
(4)电源模块:由于整个系统采用的电源电压只需+5V,故利用PC机的USB串口直接供电。
(5)系统控制模块:采用单片机控制芯片,它是一种低功耗、高性能的微型控制器,可以接受检测信号,外接口亦能方便的输出控制信号。
(6)LCD显示模块:该模块主要用来显示开锁提示。LCD的数据端通过1K欧姆的上拉电阻接到单片机P0口。
(7)掉电存储模块:采用的是AT24C02,SCL移位脉冲口和SDA数据地址口接到单片机I/O口。
第3章 系统各模块的硬件设计
本设计主要由单片机、矩阵键盘、液晶显示器和密码存储等部分组成。其中矩阵键盘用于输入数字密码和进行各种功能的实现。由用户通过连接单片机的矩阵键盘输入密码,后经过单片机对用户输入的密码与自己保存的密码进行对比,从而判断密码是否正确,然后控制引脚的高低电平传到开锁电路或者报警电路控制开锁还是报警。硬件部分由电源输入部分、键盘输入部分、复位部分、晶振部分、显示部分、报警部分组成。
3.1 电源模块设计
STC单片机USB下载线原理图,也可以用USB口和电脑进行串口通信PL-2303hx的USB转TTL电平串口的电路。如图3-1所示。
- 电脑的原有的串口,叫作RS232接口,这是一种cmos接口,接口电压从-15v到+15v之间,而单片机C51都是TTL电平,电平电压只用0v或是5v两种。用这个电脑做出来的就是单片机上用的TTL电平,所以,不要再接MAX232芯片了。这是它的一大好处。
- 电路可以提取出USB接口的+5v电压,正好用于C51单片机的使用,非常方便。另外PL-2303hx还能对外提供一个+3.3v的电压,这个电压,对于AVR单片机,非常合适。
图3-1 USB-TTL下载器原理图
3.2 掉电存储模块设计
3.2.1 AT24C02介绍
AT24C02是美国Atmel公司的低功耗CMOS型E2PROM,内含256×8位存储空间,具有工作电压宽(2.5~5.5 V)、擦写次数多(大于10000次)、写入速度快(小于10 ms)、抗干扰能力强、数据不易丢失、体积小等特点。而且他是采用了I2C总线式进行数据读写的串行器件,占用很少的资源和I/O线,并且支持在线编程,进行数据实时的存取十分方便。AT24C02中带有的片内地址寄存器。每写入或读出一个数据字节后,该地址寄存器自动加1,以实现对下一个存储单元的读写。所有字节均以单一操作方式读取。为降低总的写入时间,一次操作可写入多达8个字节的数据。I2C总线是一种用于IC器件之间连接的二线制总线。他通过SDA(串行数据线)及SCL(串行时钟线)两根线在连到总线上的器件之间传送信息,并根据地址识别每个器件。AT24C02正是运用了I2C规程,使用主/从机双向通信,主机(通常为单片机)和从机(AT24C02)均可工作于接收器和发送器状态。主机产生串行时钟信号(通过SCL引脚)并发出控制字,控制总线的传送方向,并产生开始和停止的条件。无论是主机还是从机,接收到一个字节后必须发出一个确认信号ACK。AT24C02的控制字由8位二进制数构成,在开始信号发出以后,主机便会发出控制字,以选择从机并控制总线传送的方向。其电路如图3-2-1所示。
SCL 为串行时钟:串行时钟输入管脚用于产生器件所有数据发送或接收的时钟这是一个输入管脚。
SDL 为串行数据/地址:双向串行数据/地址管脚用于器件所有数据的发送或接收SDL,是一个开漏输出管脚可与其它开漏输出或集电极开路输出进行线或。
A0、A1、A2 为器件地址输入端:当使用24C02 时最大可级联8个器件,如果只有一个24C02被总线寻址,这三个地址输入脚A0、A1、A2可悬空或连接到Vss。
WP为写保护: 如果WP 管脚连接到Vcc 所有的内容都被写保护只能读当WP, 管脚连接到Vss 或悬空,允许器件进行正常的读/写操作。
3.2.2掉电存储电路设计
采用AT24C02设计的掉电存储电路如图3-2-2所示。图中R是上拉电阻,其作用是减少AT24C02的静态功耗,由于AT24C02的数据线和地址线是复用的,采用串口的方式传送数据,所以只用两根线SCL(移位脉冲)和SDA(数据/地址)与单片机传送数据。
每当设定一次密码,系统就自动调用存储程序,将信息保存在芯片内;当系统重新上电的时候,自动调用读存储器程序,将存储器内的密码等信息,读到缓存单元中,供主程序使用。
3.3 单片机控制模块设计
单片机是由运算器、控制器、存储器、输入设备以及输出设备共五个基本部分组成的。单片机是把包括运算器、控制器、少量的存储器、最基本的输入输出口电路、串行口电路、中断和定时电路等都集成在一个尺寸有限的芯片上。
通常,单片机由单个集成电路芯片构成,内部包含有计算机的基本功能部件:中央处理器、存储器和I/O接口电路等。因此,单片机只需要和适当的软件及外部设备相结合,便可成为一个单片机控制系统。
在STC89C52中有四个双向I/O端口P0 ~ P3口,每个端口都是由锁存器、输出驱动器、输入缓冲器组成。当CPU控制系统与外部设备交换信息时,都是通过端口锁存器进行的。四个I/O端口都可作输出输入使用,其中P0和P2口通常用于对外部存储器的访问。
接通锁存器时,P0口作为双向I/O使用,如P0口的锁存器的值为1,使输出驱动器中的场效应管截止,引脚空,此时端口可作高阻输入。锁存器的值为0时,下面的场效应管导通,输出为0。P0口作为地址/数据总线口使用时,由“控制”线控制将电子开关接通至“地址/数据”端,分别输出扩展外存的低8位地址A0 ~ A7和数据D0 ~D7。一般情况下,当P0口作输入输出线使用时,都要外接拉高电阻。
在P1、P2、P3端口内,都接有内部上拉电阻,此上拉电阻分为固定部分和附加部分,当端口的状态要从0变为1时,在发生变化的哪个机器周期的S1P1和S1P2接通附加的拉高电路以增加变化的速度,否则这个状态的变化将十分缓慢。附加的拉高电路允许通过的电流比普通的上拉电阻大100倍。
STC89C52有40条引脚,分为端口线、电源线和控制线三类。如图3-3为STC89C52的引脚结构图:
图3-3 89C52引脚图
3.3.1 单片机时钟电路设计
时钟电路由一个晶体振荡器12MHZ和两个22pF的瓷片电容组成,瓷片电容叫晶振的负载电容。时钟电路用于产生单片机工作所需要的时钟信号,而时序所研究的是指令执行中各信号之间的相互关系。单片机本身就如一个复杂的同步时序电路,为了保证同步工作方式的实现,电路应在唯一的时钟信号控制下严格地工作。时钟电路接法是,AT89C52的外接晶体引脚为XTAL1和XTAL2,是利用单片机内部的振荡器产生,只要在XTAL1、XTAL2引脚上外接定时反馈电路,内部振荡器便自激振荡,产生时钟输出到内部的定时控制逻辑。其电路如图3-3-1所示:
图3-3-1 时钟电路图
3.3.2 单片机复位电路设计
单片机在启动时都需要复位,以使CPU及系统各部件处于确定的初始状态,并从初态开始工作。89系列单片机的复位信号是从RST引脚输入到芯片内的施密特触发器中的。当系统处于正常工作状态时,且振荡器稳定后,如果RST引脚上有一个高电平并维持2个机器周期(24个振荡周期)以上,则CPU就可以响应并将系统复位。单片机系统的复位方式有:手动按钮复位和上电复位。
本设计采用手动按钮复位,需要人为在复位输入端RST上加入高电平。一般采用的办法是在RST端和正电源Vcc之间接一个按钮。当人为按下按钮时,则Vcc的+5V电平就会直接加到RST端。手动按钮复位的电路如所示。由于人的动作再快也会使按钮保持接通达数十毫秒,所以,完全能够满足复位的时间要求。根据实际操作的经验,下面给出这种复位电路的电容、电阻参考值。C=10uF,Rl=10K,R2=1K,如图3-3-2所示。
图3-3-2复位电路图
3.4 按键模块设计
本系统需要的按键数量较多,为了减少I/O口的占用,将按键排列成矩阵形式,如图3-4所示。在矩阵式键盘中,每条水平线和垂直线在交叉处不直接连通,而是通过一个按键加以连接。这样,一个端口(如P1口)就可以构成4*4=16个按键,比之直接将端口线用于键盘多出了一倍,而且线数越多,区别越明显,由此可见,在需要的键数比较多时,采用矩阵法来做键盘是合理的。
图3-4 矩阵键盘图
矩阵键盘的工作过程可分为两步:第一步是CPU首先检测键盘上是否有键按下;第二步是识别哪一个键按下。
检测键盘上是否有键按下的处理方法是:将行线送入全扫描字,读入列线的状态来判别。
识别键盘中哪一个键按下的处理方法是:将行线逐列置成低电平,检查列输入状态,称为逐行扫描。
例如:P0.7~P0.0设为11111110,然后与11110000相与,如果结果不等于11110000,则判断有按键按下,即这种情况是有按键按下,而且是P0.0为低电平,可知是第一行有一个按键按下,接下来就通过判断P0口的值来检测是哪个按键,如果值为11101110,即P0.4为低电平,初始值可知P0.0也是低电平,这是就可以判断是第一行第一个按键是按下的;如果为11011110,则是第一行第二个按键是按下的;如果为10111110,则是第一行第三个按键是按下的;如果为01111110,则是第一行第四个按键是按下的。由此类推,便可以判断是哪个按键按下,之后便可以进行接下来的操作。
3.5显示模块设计
液晶显示模块已作为很多电子产品中都可以看到,显示的主要是数字、专用符号和图形。1602型LCD显示模块具有体积小,功耗低,显示内容丰富等特点。1602型LCD可以显示2行16个字符,有8位数产品的通过器件,如在计算器、万用表、电子表及很多家用电子据总线D0-D7和RS,R/W,EN三个控制端口,工作电压为5V,并且具有字符对比度调节和背光功能。引脚功能说明:
LCD1602采用标准的14脚(无背光)或16脚(带背光)接口,各引脚接口说明:
第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脚:背光源负极。
LCD连线图如图3-5所示。
图3-5 LCD1602连线图
只有按下键盘上的开启按键后,显示器才处于开启状态。同理只有按下关闭按键后显示器才处于关闭状态。否则显示器将一直处于初始状态,当需要对密码锁进行开锁时,按下键盘上的开锁按键后利用键盘上的数字键0-9输入密码,每按下一个数字键后在显示器上显示一个*,输入多少位就显示多少个*。当密码输入完成时,按下确认键,如果输入的密码正确的话, LCD子显示“RIGHT”,单片机其中P2.0引角会输出低电平,使三极管T2导通,电磁铁吸合,电子密码锁被打开,如果密码不正确,LCD显示屏会显示“ERROR”,P2.0输出的是高电平,电子密码锁不能被打开。通过LCD显示屏,可以清楚的判断出密码锁所处的状态。
3.6蜂鸣器模块设计
三极管起开关作用,单片机驱动口输出驱动电平并通过三极管放大驱动电流就能使蜂鸣器发出声音。三极管基极低电平时导通,蜂鸣器发声,基极高电平则使三极管关闭,蜂鸣器停止发声。蜂鸣器报警电路如图3-6所示。
图3-6蜂鸣器连线图
第4章 系统软件设计
4.1 系统软件设计总体思路
当用户需要开锁时,先按键盘开锁键之后按键盘的数字键0-9输入密码。密码输完后按下确认键,如果密码输入正确则开锁,不正确显示密码错误重新输入密码,当三次密码错误则发出报警;当用户需要修改密码时,先按下键盘设置键后输入原来的密码,只有当输入的原密码正确后才能设置新密码。
4.2 系统软件主程序流程图设计
如图4-2所示为主程序流程图,开始接上电源,程序进行初始化设置,然后在键盘上输入密码,此系统进行键盘扫描,密码正确,开锁成功,密码错误3次出错报警,选择是否修改密码,若要修改密码,先输入旧密码密码,密码正确后设置新密码,错误时报警,需要两次确认新密码,确认后,密码修改成功,否则结束最终返回。
4.3 系统软件子程序设计
4.3.1按键功能程序设计
如图4-3-1为按键功能流程图,在按键当中,有与输入、开锁、清除、设置、确认的程序相对应的按键,并按顺序与输入的数相比较,当输入正确时,进入密码程序,错误时进行清除,输入两次新密码正确时,可进行重新设置密码,最后确认程序。
图4-3-1 按键功能程序流程图
4.3.2 密码设置程序设计
如图4-3-2为密码设置流程图,开始按下设置键,输入旧密码,如果错误累计三次,进行报警程序。如输入正确,可以修改密码,确认后再次输入新密码,如两次输入一样,则更改成功。如果两次输入的新密码不一样,则修改密码失败,重新返回设置新密码。
图4-3-2密码重置程序流程图
4.3.3 开锁程序设计
如图4-3-3为开锁流程图,开始时按开锁键,输入密码,如果输入正确,则开锁成功。如果输入错误累计达到三次,则执行报警程序。
图4-3-3 开锁程序流程图
第5章 系统调试与数据分析
5.1 硬件电路的制作和调试
5.1.1 硬件电路的制作
本电路由相关元器件在通用板上面焊接而成,在焊接之前,用万用表检查各个元器件是否有损坏,比如电容、发光二极管是否开路,之后设计好各个元器件在电路板上面的布局,做到合理、美观。布局完成之后就可以进行焊接了,元器件之间的连线由带有绝缘皮的导线完成。焊接的过程中不可三心二意,不要造成短路、开路等错误,尽量做到一步到位
5.1.2 硬件电路的调试
本次调试主要采用proteus软件仿真。首先设计电子密码锁的源程序,源程序经过汇编后,生成的目标文件经过仿真调试。依次按下密码后按确定键,二极管亮,表示密码正确开门。
系统调试包括硬件调试和软件调试,硬件调试的任务排除系统的硬件电路.包括设计和工艺故障,软件调试是利用开发工具进行在线住址调试,除发现和解决程序错误之外,也可以发现硬件故障.
(1) 静态调试
第一步为目测,单片机应用系统中大部分电路安装在印制电路板上,因此对每一块加工好的印制电路板要进行仔细的检查。第二步为示波器测试,目测检查后,可进行示波器测试。第三步为加电检查,第四步实际联机检查。但注意示波器必须接在入口而不能接在电压大的端口上。
(2) 动态调试
一般方法是由近及远、由分到合。首先按逻辑功能将用户系统硬件电路分为若干份,先分块调试,当调试某块电路时,与该电路无关的器件全部从用户系统中去掉,这样,可将故障范围限定在某个局部电路上。当各块电路调试无故障后,将各块电路加入系统中,再对个块电路功能及电路间可能存在的相互联系进行试验。经历这样一个调试过程后,大部分硬件故障基本可以排除。
软件调试一般步骤:
先独立后联机:一个子程序一个子程序的进行调试,最后单片机连起来总调。
先分块后组合:逐个芯片逐步调试再和整体芯片一起进行总调。
先单步后连续:先执行一条指令,在每步后,又返回监控调试状态在从程序任意一条地址处启动,最后全速运行。
5.1.3 故障方析
现象一:通电调试硬件的时候,无论单片机P2.0~P2.5与单片机20脚(GND)相连,还是将单片机P3.4~P3.7与单片机20脚(GND)相连,发光二极管和LCD都不亮;
故障方析:可能电路未供上电,或者各个发光二极管阴极和数码管位选端均未与单片机相连;
解决方法:用数字万用表蜂鸣挡两个表笔分别搭到单片机40脚(VCC)和电源排针,不响,可知电源未接通,将其接通,排除故障。
5.2 软硬件功能分析
在软硬件联调时,按基本功能依次调试。当电路通上+5v电源后,程序自动调入初始密码,此时依次输入:000000,然后按确认键,此时锁会打开,可以看到显示open,密码锁打开。首次使用输入:131420,对密码进行初始化,显示出现:initpassword,证明密码初始化完成,此时初始密码即为:000000。按下取消键,此时锁关闭,所有输入清除。在开锁状态下,再次输入正确的密码并按下确认键,此时听到两声提示,输入新的六位密码并按重设键,再重复输入一次新密码并按重设键,会听到两声提示音,重设密码成功,内部保存新密码并存储到AT24C02。如两次输入的新密码不一样,则重设密码失败。报警并锁定键盘:当输入密码错误后,报警并锁定键盘3秒,如3秒内又有按键,3秒再启动。
5.3 测试结果分析
经通电测试检查完毕,本系统可以实现的功能如下:
1、设置6位密码,密码通过键盘输入,若密码正确,则将锁打开。
2、密码可以由用户自己修改设定(只支持6位密码),锁打开后才能修改密码。修改密码之前必须再次输入密码,在输入新密码时候需要二次确认,以防止误操作。
3、报警、锁定键盘功能。密码输入错误显示器会出现错误提示,若密码输入错误次数超过3次,蜂鸣器报警并且锁定键盘。
4、AT24C02保存密码,支持复位保存,掉电保存功能。
第6章 总结与展望
本次设计的电子密码锁是以手动键盘输入密码的,通过这几个星期对电子密码锁的研究学习,发觉这种密码输入方式可以进行改革。在越来越高科技化的今天,遥控控制显的愈发重要,今后的电子密码锁应该具有以红外技术或无线电技术为辅助的密码按键输入远程交互技术,这样就能远程输入密码完成操作。也可以放弃传统的按键输入密码模式,借助传感器技术运用声控来实现密码输入,又或者人脸识别技术,还有一种就是用户指纹输入方式,这些都可以使开锁的时间更短更方便。电子密码锁产业将向静态功耗更低,外围电路更简化,可提供的功能或控制口更多,更人性化高科技化的方向发展。
通过本次毕业设计的锻炼,我学到了很多有关电子密码锁的设计方法与工作原理,巩固了单片机知识。无论从理论到实践都使我学到了很多东西,它不仅可以巩固了以前所学过的知识,而且学到了很多在书本上所没有学到过的知识。同时也明白了理论与实践相结合的重要性,只有理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,从理论中得出结论,才能真正为社会服务,从而提高自己的实际动手能力和独立思考的能力。
参考文献
[1] 叶启明.单片机制作的新型安全密码锁[J].家庭电子.2000,第六期:24-27
[2] 胡乔木. 中国大百科全书.中国大百科全书出版社. 1993
[3]李明喜.新型电子密码锁的设计[J].机电产品开发与创新.2004,第八期:77-79
[4]董继成.一种新型安全的单片机密码锁[J].电子技术.2004,第三期:55-60
[5]王宽仁.可靠安全的智能密码锁[J].电子技术应用.2001年第2期
[6]何立民.MCS-51系列单片机应用系统设计系统配置与接口技术[M].北京:北京航空航天大学出版社,1999
[7]胡汉才.单片机原理及其接口技术(第2版)[M].北京:清华大学出版社,2004
[8]江志红. 51单片机技术与应用系统开发[M]. 清华大学出版社, 2008
[9]童诗白,华成英. 模拟电子技术基础[M] 高等教育出版社,2000
[10]阎石. 数字电子技术基础[第四版][M].高等教育出版社.1998.11
[11]任艳艳. 基于AT89C51单片机多功能密码锁的研究[J]. 重庆职业技术学院学报.2008.5
[12]周功明. 基于AT89C2051单片机的防盗自动报警密码锁系统的设计[J]. 绵阳师范学院学报.2007.5
[13]周鑫,何建新, 刘琥. 基于单片机的电子密码锁控制电路设计[J] 成都信息工程学院学报. 2009,(08)
[14] 郭海英. 基于单片机的电子安全密码锁的设计[J]. 佛山职业技术学院现代电子技术2005 (13)
[15] 王金国.采用单片机的电子密码锁控制电路[J].山东煤炭科技 ,2000 ,(3) :30 - 33.
[16] 宁爱民. 应用AT89C2051 单片机设计电子密码锁[J]. 淮海工学院学报2003 ,6
[17] AT89S51 DATA SHEEP Philips SemiSonduStors [J]. 2009
[18] AT89S51 DATA SHEEP Philips SemiSonduStors [J]. 2009
[19] Texas Instruments InSorporated, AT89S51 Family User’s Guide.
[20] Voice of Electronic Password-lock Design, China Control Net ,2008
[21] Design Serial Infrared PhysiSalL ayer SpeSifiSation, Version 1.3. Ostober 15,
致谢
在这一个月的设计和制作过程中,在老师和同学的帮助下,我顺利的完成了此次实训。通过这次电子综合实训,使我深刻地认识到学好专业知识的重要性,也理解了理论联系实际的含义,并且检验了大学四年的学习成果。虽然在这次设计中对于知识的运用和衔接还不够熟练。但是我将在以后的工作和学习中继续努力、不断完善。这四周的课程设计是对过去所学知识的系统提高和扩充的过程,为今后的发展打下了良好的基础,而且为我们下学期的毕业设计提供了模板。
附录1 电路原理图
附录2 程序
- #include<REG51.h>
- #include<intrins.h>
- #define LCM_Data P0
- #define uchar unsigned char
- #define uint unsigned int
- #define w 8//定义密码位数
- sbit lcd1602_rs=P2^6;
- sbit lcd1602_en=P2^7;
- sbit Scl=P3^4; //24C02串行时钟
- sbit Sda=P3^5; //24C02串行数据
- sbit ALAM = P2^0; //报警
- sbit KEY = P3^7; //开锁
- bit operation=0; //操作标志位
- bit pass=0; //密码正确标志
- bit ReInputEn=0; //重置输入充许标志
- bit s3_keydown=0; //3秒按键标志位
- bit key_disable=0; //锁定键盘标志
- unsigned char countt0,second; //t0中断计数器,秒计数器
- void Delay5Ms(void);
- unsigned char time=0;
- unsigned char code a[]={0xFE,0xFD,0xFB,0xF7}; //控盘扫描控制表
- unsigned char code start_line[]= {"password: "};
- unsigned char code name[]={"===CodedLock==="};//显示名称
- unsigned char code Correct[]= {" correct "};//输入正确
- unsigned char code Error[] ={" error "}; //输入错误
- unsigned char code codepass[]= {" pass "};
- unsigned char code LockOpen[]= {" open "};//OPEN
- unsigned char code SetNew[]= {"SetNewWordEnable"};
- unsigned char code Input[] = {"input: "};//INPUT
- unsigned char code ResetOK[]= {"ResetPasswordOK "};
- unsigned char code initword[]= {"Init password..."};
- unsigned char code Er_try[]= {"error,try again!"};
- unsigned char code again[]= {"input again "};
- unsigned char InputData[6]; //输入密码暂存区
- unsigned char CurrentPassword[6]={1,3,1,4,2,0}; //当前密码值
- unsigned char TempPassword[6];
- unsigned char N=0; //密码输入位数记数
- unsigned char ErrorCont;//错误次数计数
- unsigned char CorrectCont;//正确输入计数
- unsigned char ReInputCont; //重新输入计数
- unsigned char code initpassword[6]={0,0,0,0,0,0};
- void Delay5Ms(void)
- {unsigned int TempCyc = 5552;
- while(TempCyc--);}
- void Delay400Ms(void)
- { unsigned char TempCycA = 5;
- unsigned int TempCycB;
- while(TempCycA--)
- {TempCycB=7269;
- while(TempCycB--); }}
- void mDelay(uint t) //延时
- { uchar i;
- while(t--)
- {for(i=0;i<125;i++)
- {;}}}
- void Nop(void) //空操作
- {_nop_();
- _nop_();
- _nop_();
- _nop_();
- }
- /*起始条件*/
- void Start(void)
- {Sda=1;
- Scl=1; Nop();
- Sda=0;
- Nop();}
- /*停止条件*/
- void Stop(void)
- {Sda=0;
- Scl=1;
- Nop();
- Sda=1;
- Nop();}
- /*应答位*/
- void Ack(void)
- {Sda=0;
- Nop();
- Scl=1;
- Nop();
- Scl=0;}
- /*反向应答位*/
- void NoAck(void)
- { Sda=1;
- Nop();
- Scl=1;
- Nop();
- Scl=0;}
- /*发送数据子程序,Data为要求发送的数据*/
- void Send(uchar Data)
- { uchar BitCounter=8;
- uchar temp;
- do
- {temp=Data;
- Scl=0;
- Nop();
- if((temp&0x80)==0x80)
- Sda=1;
- else
- Sda=0;
- Scl=1;
- temp=Data<<1;
- Data=temp;
- BitCounter--;}
- while(BitCounter);
- Scl=0;}
- /*读一字节的数据,并返回该字节值*/
- uchar Read(void)
- {uchar temp=0;
- uchar temp1=0;
- uchar BitCounter=8;
- Sda=1;
- do{
- Scl=0;
- Nop();
- Scl=1;
- Nop();
- if(Sda)
- temp=temp|0x01;
- else
- temp=temp&0xfe;
- if(BitCounter-1)
- {temp1=temp<<1;
- temp=temp1;}
- BitCounter--;}
- while(BitCounter);
- return(temp);}
- void WrToROM(uchar Data[],uchar Address,uchar Num)
- { uchar i;
- uchar *PData;
- PData=Data;
- for(i=0;i<num;i++)
- {Start();
- Send(0xa0);
- Ack();
- Send(Address+i);
- Ack();
- Send(*(PData+i));
- Ack();
- Stop();
- mDelay(20);}}
- void RdFromROM(uchar Data[],uchar Address,uchar Num)
- {uchar i;
- uchar *PData;
- PData=Data;
- for(i=0;i<num;i++)
- {Start();
- Send(0xa0);
- Ack();
- Send(Address+i);
- Ack();
- Start();
- Send(0xa1);
- Ack();
- *(PData+i)=Read();
- Scl=0;
- NoAck();
- Stop();}}
- void delay(uint xms)//延时函数,有参函数
- {uint x,y;
- for(x=xms;x>0;x--)
- for(y=110;y>0;y--);}
- //--------------------------写指令---------------------------//
- write_1602com(uchar com)//****液晶写入指令函数****
- {lcd1602_rs=0;//命令
- P0=com;
- delay(5);
- lcd1602_en=1;
- delay(5);
- lcd1602_en=0;}
- //-------------------------写数据-----------------------------//
- write_1602dat(uchar dat)//***液晶写入数据函数****
- {lcd1602_rs=1;//数据
- P0=dat;
- delay(5);
- lcd1602_en=1;
- delay(5);
- lcd1602_en=0;}
- //-------------------------初始化-------------------------//
- 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 (0x18): k=1;break;
- case (0x28): k=2;break;
- case (0x48): k=3;break;
- case (0x88): k='A';break;
- case (0x14): k=4;break;
- case (0x24): k=5;break;
- case (0x44): k=6;break;
- case (0x84): k='B';break;
- case (0x12): k=7;break;
- case (0x22): k=8;break;
- case (0x42): k=9;break;
- case (0x82): k='C';break;
- case (0x11): k='*';break;
- case (0x21): k=0;break;
- case (0x41): k='#';break;
- case (0x81): k='D';break;}
- return(k);}
- //=====================按键检测并返回按键值===============================//
- unsigned char keynum(void)
- {unsigned char row,col,i;
- P1=0xf0;
- if((P1&0xf0)!=0xf0)
- {Delay5Ms();
- Delay5Ms();
- if((P1&0xf0)!=0xf0)
- {row=P1^0xf0; //确定行线
- i=0;
- P1=a[i]; //精确定位
- while(i<4)
- {if((P1&0xf0)!=0xf0)
- {col=~(P1&0xff); //确定列线
- break; //已定位后提前退出
- }
- else
- {
- i++;
- P1=a[i];
- }
- }
- }
- else
- {
- return 0;
- }
- while((P1&0xf0)!=0xf0);
- return(row|col); //行线与列线组合后返回
- }
- Else return 0; //无键按下时返回0
- }
- //=======================一声提示音,表示有效输入========================//
- void OneAlam(void)
- {
- ALAM=0;
- Delay5Ms();
- ALAM=1;
- }
- //========================二声提示音,表示操作成功========================
- void TwoAlam(void)
- {
- ALAM=0;
- Delay5Ms();
- ALAM=1;
- Delay5Ms();
- ALAM=0;
- Delay5Ms();
- ALAM=1;
- }
- //========================三声提示音,表示错误========================//
- void ThreeAlam(void)
- {
- ALAM=0;
- Delay5Ms();
- ALAM=1;
- Delay5Ms();
- ALAM=0;
- Delay5Ms();
- ALAM=1;
- Delay5Ms();
- ALAM=0;
- Delay5Ms();
- ALAM=1;
- }
- void FourAlam(void)
- {ALAM=0;
- mDelay(700);
- ALAM=1;
- mDelay(1000);
- ALAM=0;
- mDelay(700);
- ALAM=1;
- mDelay(1000);
- ALAM=0;
- mDelay(700);
- ALAM=1;
- mDelay(1000);
- }
- void DisplayOne(void)
- {
- //DisplayOneChar(9+N,1,'*');
- write_1602com(yi+5+N);
- write_1602dat('*');
- }
- //=======================显示提示输入=========================//
- void DisplayChar(void)
- {
- unsigned char i;
- if(pass==1)
- { //DisplayListChar(0,1,LockOpen);
- write_1602com(er);
- for(i=0;i<16;i++)
- {
- write_1602dat(LockOpen[i]);}
- }
- else
- {
- if(N==0) //DisplayListChar(0,1,Error);
- write_1602com(er);
- for(i=0;i<16;i++)
- {
- write_1602dat(Error[i]);}
- }
- else
- { //DisplayListChar(0,1,start_line);
- write_1602com(er);
- for(i=0;i<16;i++)
- {
- write_1602dat(start_line[i]);
- }
- }
- }
- }
- void DisplayInput(void)
- {
- unsigned char i;
- if(CorrectCont==1)
- {
- //DisplayListChar(0,0,Input);
- write_1602com(er);for(i=0;i<16;i++)
- write_1602dat(Input[i]);
- }
- }
- void ResetPassword(void)
- {
- unsigned char i;
- unsigned char j;
- if(pass==0)
- {
- pass=0;
- DisplayChar();
- ThreeAlam();
- }
- else
- {
- if(ReInputEn==1)
- {
- if(N==6)
- {
- ReInputCont++;
- if(ReInputCont==2)
- {
- for(i=0;i<6;)
- if(TempPassword[i]==InputData[i]) //将两次输入的新密码作对比
- i++;
- else
- {
- //DisplayListChar(0,1,Error);
- write_1602com(er);
- for(j=0;j<16;j++)
- {
- write_1602dat(Error[j]);
- }
- ThreeAlam();
- pass=0;
- ReInputEn=0; //关闭重置功能,
- ReInputCont=0;
- DisplayChar();
- break;
- }
- }
- if(i==6)
- {
- //DisplayListChar(0,1,ResetOK);
- write_1602com(er);
- for(j=0;j<16;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<16;j++)
- {
- write_1602dat(again[j]);
- }
- for(i=0;i<6;i++)
- {
- TempPassword[i]=InputData[i]; //将第一次输入的数据暂存起来
- }
- }
- N=0; //输入数据位数计数器清零
- }
- }
- }
-
- }
- void Alam_KeyUnable(void)
- {
- P1=0x00;
- ALAM=~ALAM;
- Delay5Ms();
- }
- void Clean(void)
- {
- if(N<7)
- { if(N<1)N=1;
- N--;
- write_1602com(er+6+N);
- write_1602dat(' ');
- }
- OneAlam();
- }
- void Cancel(void)
- {
- unsigned char i;
- unsigned char j;
- //DisplayListChar(0, 1, start_line);
- write_1602com(er);
- for(j=0;j<16;j++)
- {
- write_1602dat(start_line[j]);
- }
- TwoAlam();//提示音
- for(i=0;i<6;i++)
- {
- InputData[i]=0;
- }
- KEY=1; //关闭锁
- ALAM=1; //报警关
- operation=0//操作标志位清零
- pass=0;//密码正确标志清零
- ReInputEn=0;//重置输入充许标志清零
- ErrorCont=0;//密码错误输入次数清零
- CorrectCont=0;//密码正确输入次数清零
- ReInputCont=0;//重置密码输入次数清零
- //open_led=1;
- s3_keydown=0;
- key_disable=0;
- N=0;
- }
- //=======确认键,并通过相应标志位执行相应功能=============//
- void Ensure(void)
- {unsigned char i,j;
- RdFromROM(CurrentPassword,0,6); //从24C02里读出存储密码
- if(N==6)
- {
- if(ReInputEn==0) //重置密码功能未开启
- {
- for(i=0;i<6;)
- {if(CurrentPassword[i]==InputData[i])
- {
- i++;
- }
- else
- {ErrorCont++;
- if(ErrorCont==3) //错误输入计数达三次时,报警并锁定键盘
- {
- write_1602com(er);
- for(i=0;i<16;i++)
- {
- write_1602dat(Error[i]);
- }
- Alam_KeyUnable();
- Delay400Ms();
- Delay400Ms();
- Delay400Ms();
- Delay400Ms();
- Delay400Ms();
- Delay400Ms();
- Delay400Ms();
- Delay400Ms();
- Delay400Ms();
- Delay400Ms();
- Delay400Ms();
- Delay400Ms();
- Delay400Ms();
- Delay400Ms();
- Delay400Ms();
- Delay400Ms();
- Delay400Ms();
- Delay400Ms();
- Delay400Ms();
- Delay400Ms();
- Delay400Ms();
- Delay400Ms();
- }
- else
- {TR0=1; //开启定时
- key_disable=1; //锁定键盘
- pass=0;
- break;
- }
- }
- }
- if(i==6)
- {
- CorrectCont++;
- if(CorrectCont==1) //正确输入计数,当只有一次正确输入时,开锁,
- {
- //DisplayListChar(0,1,LockOpen);
- write_1602com(er);
- for(j=0;j<16;j++)
- {
- write_1602dat(LockOpen[j]);
- }
- TwoAlam();//操作成功提示音
- KEY=0; //开锁
- pass=1; //置正确标志位
- TR0=1; //开启定时
- //open_led=0; //开锁指示灯亮
- for(j=0;j<6;j++)//将输入清除
- {
- InputData[i]=0;
- }
- }
- else//当两次正确输入时,开启重置密码功能
- {
- //DisplayListChar(0,1,SetNew);
- write_1602com(er);
- for(j=0;j<16;j++)
- {
- write_1602dat(SetNew[j]);
- }
- TwoAlam(); //操作成功提示
- //允许重置密码输入
- CorrectCont=0; //正确计数器清零
- }
- }
- else
- {
- if((InputData[0]==1)&&(InputData[1]==3)&&(InputData[2]==1)&&(InputData[3]==4)&&(InputData[4]==2)&&(InputData[5]==0)){
- WrToROM(initpassword,0,6); //强制将初始密码写入24C02存储
- //DisplayListChar(0,1,initword); //显示初始化密码
- write_1602com(er);
- for(j=0;j<16;j++)
- {
- write_1602dat(initword[j]);
- }
- TwoAlam();
- Delay400Ms();
- TwoAlam();
- N=0;
- }
- else
- {
- //DisplayListChar(0,1,Error);
- write_1602com(er);
- for(j=0;j<16;j++)
- {
- write_1602dat(Error[j]);
- }
- ThreeAlam();//错误提示音
- pass=0;
- }
- }
- }
- else//当已经开启重置密码功能时,而按下开锁键,
- {
- //DisplayListChar(0,1,Er_try);
- write_1602com(er);
- for(j=0;j<16;j++)
- {
- write_1602dat(Er_try[j]);
- }
- ThreeAlam();
- }
- }
- else
- {
- //DisplayListChar(0,1,Error);
- write_1602com(er);
- for(j=0;j<16;j++)
- {
- write_1602dat(Error[j]);
- }
- ThreeAlam();//错误提示音
- pass=0;
- }
- N=0; //将输入数据计数器清零,为下一次输入作准备
-
- operation=1;
- }
- void main(void)
- {
- unsigned char KEY,NUM;
- unsigned char i,j;
- P1=0xFF;
- MOD=0x11;
- TL0=0xB0;
- TH0=0x3C;
- EA=1;
- ET0=1;
- TR0=0;
- Delay400Ms();//启动等待,等LCM讲入工作状态
- lcd_init();//LCD初始化
- write_1602com(yi);//日历显示固定符号从第一行第0个位置之后开始显示
- for(i=0;i<16;i++)
- {
- write_1602dat(name[i]);//向液晶屏写日历显示的固定符号部分
- }
- write_1602com(er);//时间显示固定符号写入位置,从第2个位置后开始显示
- for(i=0;i<16;i++)
- {
- write_1602dat(start_line[i]);//写显示时间固定符号,两个冒号
- }
- write_1602com(er+9); //设置光标位置
- //write_1602com(0x0f); //设置光标为闪烁
- Delay5Ms(); //延时片刻(可不要)
- N=0; //初始化数据输入位数
- while(1)
- {
- if(key_disable==1)
- Alam_KeyUnable();
- else
- ALAM=1; //关报警
- KEY=keynum();
- if(KEY!=0)
- {
- f(key_disable==1)
- {
- econd=0;
- }
- else
- {
- NUM=coding(KEY);
- {
- switch(NUM)
- {
- case ('A'): FourAlam() ; break;
- case ('B'):
- case('C'):Clean();break;
- ase('D'): ResetPassword();break; //重新设置密码
- case('*'):Cancel();break; //取消当前输入
- case('#'):Ensure();break; //确认键,
- default:
- {
- //DisplayListChar(0,1,Input);
- write_1602com(er);
- for(i=0;i<16;i++)
- {
- write_1602dat(Input[i]);
- }
- operation=0;
- if(N<6) //当输入的密码少于6位时,接受输入并保存,大于6位时则无效。
- {
- OneAlam();//按键提示音
- //DisplayOneChar(6+N,1,'*');
- for(j=0;j<=N;j++)
- {
- write_1602com(er+6+j);
- write_1602dat('*');
- }
- InputData[N]=NUM;
- N++;
- }
- else//输入数据位数大于6后,忽略输入
- {
- N=6;
- break; }}}}}} }}
复制代码
附录4 元器件清单