电子密码锁
一、引言
随着人们生活水平的提高,人们对自己的生活有了越来越高的要求,贵重物品也越来越多,而传统的机械安全锁由于其构造的简单,被撬被盗事件在我们身边经常发生,使我们的财产以及人身安全存在很大的安全隐患,这致使我们寻求更好的安全措施。电子锁由于其保密性高,使用灵活性好,安全系数高,受到了广大用户的喜爱。而且密码锁的形式多样,有声控密码锁,电子密码锁等,社会上大多使用电子按键密码锁。本文的电子密码锁利用数字逻辑电路,实现对门的电子控制,并且有各种附加电路保证电路能够安全工作,具有较高的安全系数。要求电子器件设计制作密码锁的控制电路,使之在规定的时间内输入正确的密码时,输出信号以开启密码锁,否则报警电路报警。本设计用红、绿LED指示关锁、开锁状态和报警状态。
二、设计任务
1、密码锁控制器中存储一个4位代码,当锁按钮开关设置8位(其中只有4位有效)的输入代码等于存储代码时启动开锁控制电路,并且用绿灯亮表示开锁状态。
2、从第一个按钮触动后的15秒内若未能将锁打开,则报警电路发报警信号,同时用绿灯灭表示关锁状态。
3、要求性能可靠、操作简便。
4、密码锁控制器中存储的4位密码可以修改。
5、分析部件见工作原理,绘制电路图,进行仿真 制作实物并撰写设
计报告。
三、设计方案
方案一:
用开关控制可控硅整端口的电压变化即导通,按依次按下四个开关,其功能相当于给可控硅一个高电平触发,四个可控硅整流器依次导通,整条回路导通,发光二极管亮,而发光二极管亮即表示输入的密码为正确密码,电路达到密码锁开锁功能。设计8位按键只有4位是正确的,如果按下4位伪码的其中一位即按下的其中一个或几个,控制报警电路可控硅导通。此时开锁部分悬空,报警报警
方案二;
采用STC89C52单片机为芯片主体,采用AT24C08为掉电存储器的芯片,用单片机的P1口作为接4 ×4 键盘按键的检测按键,P0口实现数码管的按键显示,以及错误信息,单片可以进行位操作,P2口组成报警电路,密码修改电路和AT24C08的掉电保护等其他相关功能。
系统框图如下:
方案三:
采用NE555制作成单稳态触发器,JK触发器检测密码输入,74HC163计数器记录输入次数,共设了8个用户输入键,其中只有4个是有效的密码按键,其它的都是干扰按键,只有在规定的时间内按正确的顺序输入密码密码锁才能开启。如果用户输入密码的时间超过15秒,电路将报警,若电路连续报警3次,电路将锁定键盘1分钟,防止他人的非法操作。
系统框图如下:
方案选择:
本次课程设计为电子线路课程设计,方案一,电路实现简单,元器件少,成本较低。但密码不能修改,密码锁的安全性较低。方案二,以STC89C52为核心的单片机控制方案利用单片机灵活的编程设计和丰富的I/O端口,及其控制的准确性,不但能实现基本的密码锁功能,还能添加调电存储,编程相对复杂 再考虑到本次课程设计为电子线路课程设计,顾采用第三种方案 ,采用数字逻辑器件组成电子密码锁,电路简单,功能基本本上满足了任务要求,易于分析仿真调试再考虑到本次课程设计为电子线路课程设计,顾采用第三种方案。
四、原理分析
本次设计的电子密码锁电路包含:键盘输入、密码修改、密码检测、开锁电路、报警电路、键盘输入次数锁定电路。
1、键盘输入、密码修改、密码检测电路
如图所示:
1)、 密码检测电路:由两块74LS112(双JK触发器)组成密码检测电路。由左向右第一个JK触发器处于计数状态,当用户按下第一个正确的密码后,CLK端出现了一个负的下降沿,触发器计数,1处输出为高电平,用户依次按下有效的密码,2、3、4处也依次输出高电平,1、2、3、4送入SI四输入与门74LS21,报警电路没有报警和密码锁没有锁定74LS00将会输出一个负的下降沿。
2)、密码修改电路,由单刀双掷开关SW1,SW2,SW3,SW4组成,由单刀双掷开关的左右来改变输入密码。如设置密码1468,SW1向左,SW2,SW3,SW4向右。本电路也构成了密码的检测。本电路共有16组密码可供用户选择。
3)、开关,R17,R5,Q1组成清零信号,对JK处罚器清零,以保证
电路的正常稳定工作。
2、报警电路:
其电路如图所示:
本电路由两个NE555组成单稳态触发器和一个JK触发器组成,Q3,Q5,Q6处于开关状态。左边的555设定开锁时间,在规定的时间内没有打开锁,报警电路报警,主人经常使用密码,对密码比较熟悉,输入速度比较快,顾密码输入时间设定在15秒。平时左边555的2脚为高电平,3脚为低电平,Q3截止,D2不亮表示未开始开锁,当有人触摸键盘给2脚一个低电平,触发器触发,3脚为呈现一段时间的高电平,Q3导通,D2亮,锁正确打开将给Q6清零信号,Q6导通,Q5截止报警电路解除报警。若在规定时间内密码没有输入正确,当设定时间到3脚会呈现一个下降沿,给JK触发器脉冲信号,5脚输出高电平,Q4导通,右边555的二脚呈现低电平,单稳态触发器触发,3脚出现高电平,Q5导通,Q6截止,D3发光表示报警电路报警。锁不能正常打开。
若连续三次密码没有输入正确,密码锁将锁定1分钟,具体电路如下所示:
本电路使用74HC163同步清零计数器,和555组成的单稳态触发器,每次输入都给163的2脚一个脉冲信号,计数器计数,当连续输入三次错误时,12脚呈现高电平,经过74LS00给计数器一个清零信号,同时触发单稳态触发器,3脚呈现高电平,Q7导通。给74LS21的12脚低电平,密码锁不能打开,密码锁锁定一分钟。
五 电路调试
调试中应用的仪器有:万用表、直流电压源
1、报警电路的调试
接通电路前仔细检查每个芯片的电源引脚有没有接错,确认无误后接通5V电源。按下开锁开关,不输入任何键,在规定的时间内看报警器有没有报警。在15秒内没有输入任何键,指示报警器的二极管发光,报警电路正常。按下清零开关,按上述方法重复三次,三次
后看指示三次输入错误的锁定密码锁锁定的发光二极管是否发光。发光表示电路正常,在输入三次错误后密码锁锁定一分钟,看一分钟后二极管是否灭。结果三次输入错误发光二极管发光,一分钟后二极管灭。表示电路正常,满足设计要求。
2、开锁功能电路调试
在以上电路检测正确的基础上检测电路的开锁功能。按下开锁键,在规定的时间内输入正确的密码,看指示开锁的发光二级管是否发光。发光二极管亮表示密码正确,密码锁打开,不发光表示密码锁不打开。调试结果,输入正确密码后密码锁打开指示二极管发光,表示锁打开。输入错误的密码,密码锁指示二极管不发光表示密码锁没有打开,报警电路报警。多试几次结果一样,表示密码锁正常工作。
3、密码修改电路检测。
在开锁功能正常工作后检测密码修改电路。拨动单刀双掷开关,SW1,SW2,SW3,SW4设定的密码。按下开锁键输入修改后的密码,发光二极管正常发光,密码锁打开,输入错误密码密码锁没有打开,报警电路报警。
经过认真的调试,分析出错原因锁设计的密码锁完全满足了设计的要求,工作稳定。
六 调试中遇到的问题及解决方法
1、按下清零开关后,发现报警电路不能正常报警,并闻到有元器件烧毁的味道。先检测555单稳态触发器是否正常工作,结果555单稳态触发器正常工作,未触发3脚输出低电平,触发后3脚出现一段时
间的高电平。认真分析电路,发现起清零功能的9013三极管烧毁,是触发器3脚没有接限流电阻,基极与发射结直接与5V电压相连,电流过大,更换9013并接上限流电阻,故障排除,报警电路正常报警。
2、三次输错密码,密码锁锁定的指示二极管始终亮,密码锁不能打开。按下开锁开关,检测74HC163的11脚,12脚,13脚和14脚的电压。每按一次记录这四个脚的电平,发现计数器正常工作。检查555单稳态触发器,检测2脚电压为高电平,3脚电压为高电平,问题出在555单稳态触发器,仔细检查发现2脚与3脚焊接在一起。用烙铁将两脚分开,电路恢复正常。
七、心得体会
上就是我为课程设计所做的电子密码锁电路的设计方案、原理图以及调试部分,它经过多次修改和整理,还是一个比较不错的设计,运用发光二极管来显示信号的输入以及密码的正确输入,一目了然,便于观察。可以满足人们的基本要求,但因为水平有限,此电路中也存在一定的问题。用开关作74LS112的CLK脉冲,不是很稳定,可以调换其它高速开关或计数脉冲,还有,其密码只有16位,不能任意设定密码,密码一旦忘记,密码锁将很难打开,并且没有设计显示器,但可以通过增加数字电路来实现这一功能,另外设计方案是在始终通电的前提下设计的,若是遇到断电问题则密码锁也很难打开,可以通过增加备用电源来实现,同样因为条件有限,只能做到这一步。使我们更加懂得一个设计完成的不易,需要经过多次的修改才能完善电路
的功能。电路仿真是在理想的情况,实际运用中可能出现问题,如这在此次课程设计的过程中9013的烧毁使我印象深刻,我觉得既锻炼了我们的实际动手能力,也再一次复习了上学期学习的数电模电知识,对逻辑门逻辑电路,各种基本集成芯片都有了进一步的理解。。特别的是使用proteus软件的进行电路仿真使我对它们的功能有了进一步了解的,也使我们进一步学会了使用该软件,在仿真的过程中出现问题及时的想办法解决。Proteus仿真时的电平变化很清晰,帮助理解整个电路工作的过程。通过这次课程设计,我觉得学习不仅要掌握书本上的基本内容,还要灵活思考,多动脑筋往里面钻,遇到困难想办法解决,找到出错的原因,自己也思考了许多实现功能的其他方法。自己所学知识是有限,有些想法限于自己的水平没有实现,自己的各个方面都需要再加强。在这次设计中,也要感谢同组同学崔福华的帮助,相互讨论中也使我学习了他的思考方式,训练了我的团队合作能力,使深刻体会了团体合作是很重要性。
致谢
在此,我很感谢我的指导老师张晓东教授,在做课程设计的过程中得到他的悉心指导,教我们要多寻找方案,开拓我们的视角,不仅仅局限于眼前的方案。教了我很多,在学习上要有一股钻劲,遇到困难的时候不要放弃。告诉我们现在的电路趋势是小而精,而我们的电路虽然完成了密码锁的基本功能但用的元器件过多,相对来说还是比较复杂还有更好的方案需要我们去探索。
我还要感谢在一起愉快的度过课程设计的搭档崔福华同学,正是由于你的帮助和支持,我们才能克服一个一个的困难和疑惑,直至顺利完成本次设计。
最后,再次对关心、帮助我的老师和同学表示衷心地感谢,感谢我的家人和那些永远也不能忘记的朋友。
参考文献
【1】清华大学教研组编,阎石主编:《数字电子技术基础》(第四版),北京, 高等教育出版社 ,20xx年
【2】华中科技大学电子技术课程组编,康华光主编:《电子技术基础》数字 高等教育出版社 2005 年
附:
1、元器件清单
2、系统电路图
第二篇:1602pcb及电子密码锁课程设计报告(附图 代码)
西安邮电大学
专业课程设计报告书
专业课程设计报告
内容1:驱动电路设计
【一】实验目的
利用Protel 99SE软件为主题,介绍其基础知识、设计流程、设计方法及电子设计的基本技能等问题,并要求掌握电子产品开发的基本技术问题。通过实习可以独立实现电路原理图和电路板的设计,为今后的学习和工作中的实际应用打下较为坚实的基础。用Protel 99 SE软件绘制一个电路图,图有自己决定。先绘制出电路原理图,然后进行电气规则检验,没有错误后,生成网络表,然后根据网络表生成印制电路板图,最后自动布局,手工调整,自动布线,手工调整布线,保存。
【二】实验原理
1:原理图设计
最基本的要求是正确性,其次是布局合理,最后是在正确性和布局合理的前提下力求完美。
(1)启动原理图设计界面,进入Protel99 SE,创建一个数据库,执行菜单File/New命令,从框中选择原理图服务器(Schematic Document)图标,双击该图标,建立原理设计文档。双击文档图标,进入原理设计服务器界面;
(2)设置原理图设计环境,执行菜单Design/Option和Tool/Preferences,设置图纸大小,捕捉栅格,电器栅格等;
(3)创建自己的元件库,先进入Protel 99 SE的原理图编辑器,新建一个元件,绘制SCH元件以及放入元件的管脚,给新建的元件改名,绘制制元件的外形以及放入说明文字并保存好,画原理图的时候,就可以调用这些元件了;
(4)装入所需的元件库,在设计管理器中选择Browse区域中的下拉框中选择Library,然后单击ADD/Remove按钮,在弹出的窗口中寻找Protel99 SE子目录,在该目录中选择Library\SCH路径,在元件库列表中选择所需的元件库,单击ADD按钮,即可把元件库增加到元件库管理器中;
(5)放置元件,根据实际电路的需要,到元件库中找出所需的元件,然后用元件管理器的Place按钮将原件放置在工作平面上,再根据与按键之间的走线把元件调整好;
(6)原理图布线,利用Protel99 SE所提供的各种工具,指令进行布线,将工作平面上的器件用具有点其意义的导线,符号连接起来,构成一个完整的电路原理图;
(7)编辑和调整,利用Protel99 SE所提供的各种强大的功能对原理图进一步调整和修改,以保证原理图的美观和正确。同时对元件的编号,封装进行定义和设定等;
(8)检查原理图,使用Protel99 SE的电器规则,及执行菜单命令Tool/ERC对画好的电路原理图进行电气规则检查,若有错误,根据错误情况进行改正。
(9)生成网络表,网络表是电路原理图设计和印刷电路板设计之间的桥梁,执行菜单命令Design/Create Netlist 可以生成具有元件名,元件封装,参数及元件之间连接关系的网络表;
2 :PCB设计
电路设计的最终目的是为了设计出电子产品,而电子产品的物理结构是通过印刷电路板来实现的。Protel99 SE位设计者提供了一个完整电路板设计环境,是电路设计更加方便有效。应用Protel99 SE设计印刷电路板过程如下:
(1)启动印刷电路板设计服务器,执行菜单File/New命令,从框中选择PCB设计服务器(PCB Document)图标,双击该图标,建立PCB设计文档。双击文档图标,进入设计服务器界面;
(2)规划电路板,根据要设计的电路确定电路板的尺寸。选取Keep Out Layer复选框,执行菜单命令Place/Track,绘制电路板的边框。执行菜单Design/Options,在“ Signal Lager”中选择Bottom Lager,把电路板定义为单面板;
(3)设置参数,参数设置是电路板设计的非常重要的步骤,执行菜单命令Design/Rules,左键单击Routing按钮,根据设计要求,在规则类(Rules Classes)中设置参数;
(4)装入元件封装库,执行菜单命令Design/Add/Remove Library,在“添加、删除元件库“对话框中所选取所有元件所对应的元件封装库;
(5)装入网络表,执行菜单Design/Load Nets命令,然后在弹出的窗口中单击Browse按钮,再在弹出的窗口中选择地电路原理图生成的网络表文件(扩展名为Net),如果没有错误,单击Execute。若出现错误提示,必须更改错误;
(6)Protel99 SE既可以进行自动布局也可以进行手工布局,执行菜单命令Tools/Auto Placement/Auto Placer可以自动布局。布局是布线关键性的一步,为了式布局更加合理,最好采用手工布局的方式;
(7)自动布线,Protel99 SE采用世界最先静的无网络,基于形式的对角线自动布线技术。执行菜单命令Auto Routing/All,并在弹出的窗口中单击Route all按钮,程序即对印刷电路板进行自动布线。只要设置有关参数,元件布局合理,自动布线的成功率几乎为100%;
(8)手工数调整自动布线结束后,可能存在一些令人不满意的地方,手工调整,把电路板设计得尽善尽美。
【三】实验结果
原理图编译结果:
【四】设计中遇到的问题及解决方法
1产生问题原因
(1)连线超过元件器件的断点;
(2)连线的两部分有重复;
(3)原理图中未定义元件的封装形式;
(4)印刷电路板封装的名称不存在,致使在封装库中找不到;
(5)封装可以找到,单元件的管脚名称与印刷电路库中封装的管脚名称不一致。
2解决方法
(1)在元件端点处连线;
(2)元器件连线尽量一线连通;
(3) 到网络表文档中查找未定义封装的元件,补上元件封装;
(4) 确认印刷电路板元件封装库是否已调入,同时检查原理图中元件封装名称是否印刷电路板元件封装库中的名称一致;
(5) 将印刷电路板元件封装中的修改成与原理图中定义一致。
内容2驱动程序开发
【一】项目需求分析
题目1: 4×4键盘及1602LCD显示构成的电子密码锁
需求分析:电子密码锁是一种通过密码输入来控制电路或是芯片工作,从而控制机械开关的闭合,完成开锁、闭锁任务的电子产品。它的种类很多,有简易的电路产品,也有基于芯片的性价比较高的产品。现在应用较广的电子密码锁是以芯片为核心,通过编程来实现的。其性能和安全性已大大超过了机械锁。其特点如下:
1) 保密性好,编码量多,远远大于弹子锁。随机开锁成功率几乎为零。
2) 误码输入保护,当输入密码多次错误时,报警系统自动启动。
4) 无活动零件,不会磨损,寿命长。
5) 使用灵活性好,不像机械锁必须佩带钥匙才能开锁。
【二】实施方案及本人承担的工作
采用以单片机为核心的控制方案
由于单片机种类繁多,各种型号都有其一定的应用环境,因此在选用时要多加比较,合理选择,以期获得最佳的性价比。一般来说在选取单片机时从下面几个方面考虑:性能、存储器、运行速度、I/O口、定时/计数器、串行接口、模拟电路功能、工作电压、功耗、封装形式、抗干扰性、保密性,除了以上的一些的还有一些最基本的比如:中断源的数量和优先级、工作温度范围、有没有低电压检测功能、单片机内有无时钟振荡器、有无上电复位功能等。在开发过程中单片机还受到:开发工具、编程器、开发成本、开发人员的适应性、技术支持和服务等等因素。基于以上因素本设计选用单片机90c52作为本设计的核心元件,利用单片机灵活的编程设计和丰富的I/O端口,及其控制的准确性,实现基本的密码锁功能。在单片机的外围电路外接输入键盘用于密码的输入和一些功能的控制,EEPROM芯片用于密码的存储,外接LCD1602显示器用于显示作用。当用户需要开锁时,先按键盘开锁键之后按键盘的数字键0-9输入密码。密码输完后按下确认键,如果密码输入正确则开锁,不正确显示密码错误重新输入密码,当三次密码错误则发出报警,蜂鸣器蜂鸣,LED灯亮,并锁定屏幕三秒钟,三秒过后可再次输入。
本人承担链接外围电路及写代码的全过程,与搭档一起检查代码的运行效果,根据搭档的意见对代码进行修改,使功能更加完善,更人性化更贴近实际生活。
【三】程序框图
1.总体设计
【四】实验结果
打开单片机开关后,液晶屏幕显示欢迎语句,按复位键后可输入密码,并实现密码的验证,密码正确时开锁显示相关提示,错误时提示所剩输入机会,并在连续输入三次错误时锁屏,三秒后可再次输入。
【五】设计中遇到的问题及解决方法
问题1:输入错误时同时提示错误正确。
问题2:前一次操作产生的相应提示占据了后一次显示提示的空余位置,让人看不清到底是什么。
解决1:检查发现程序逻辑错误少了大括号。
解决2:检查发现分配的字符显示长度不相同,设置为相同并将空余为作空格处理后显示结果很理想。
【六】专业课程设计的心得体会
1.PCB设计体会 此次课程设计不仅加深巩固所学内容,同时对所学内容进行扩展,有一定的深度和广度,我不仅学会了如何使用Protel,并且画出电路的原理图和设计PCB板,而且还在实习中更加深刻的体会了如何与同学配合,互帮互助的精神。在实习中碰到了一些比较难的问题,自己不怕困难,学会如何独立思考并解决问题。最后解决不了的上网搜集资料,请教老师,大家互帮帮助,体现了良好的团队意识。为将来进入社会前锻炼自己的合作精神,更好的为将来工作打好基础。
2.电子密码锁设计体会Keil软件使用的不熟练造成了一定的阻碍,经过一段时间的使用和练习克服了该困难。其次,对于模块结构程序.要一个个子程序分别调试。调试时,一定要符合入口条件和出口条件,调试可用单步运行和断点运行方式,通过检查用者系统的CPU现场情况、RAM的内容和I/O口的状态,检测程序执行结果是否符合设计要求,有无循环错误、有无机器码错误以及转移地址的错误,该问题的解决消耗了相当长的时间。同时,还可以发现系统中存在的硬件设计错误和软件算法错误。各程序模块通过后,则可以把相关功能块连在一起进行总调。这个阶段若有故障,可以考虑各子程序运行时是否破坏了现场,缓冲单元、工作寄存器是否发生冲突,标志位的建立和清除是否有误,堆栈区是否有溢出,输入设备的状态是否正常等等,若用者系统是在开发机的监控程序下运行时,还要考虑用者缓冲单元是否和监控程序的工作单元发生冲突。
单步和断点调试后,还应进行连续调试,用以确定定时精度、当全部调试和修改完成后,将程序固化到90C52中。进行整机调试。各功能实现则调试完成。
附录:主要源程序以及电路原理图或PCB版图
图1 电路原理图
图2 PCB版图
电子密码锁C程序:
#include <reg52.h>
#define uint unsigned int
#define uchar unsigned char
#define KEY P1 //键盘输入端口
#define No_key 20 //无按键时的返回值
#define lcddata P0 //1602的数据输入端口
sbit lcden= P2^6;
sbit lcdrs= P2^4;
sbit lcdrw= P2^5;
sbit light= P2^1;
sbit light1= P2^2;
uchar j ; //用来统计输入 个数的全局变量
uchar aa; //用来在定时器中计数的 全局变量
uchar code table[]= " Hello! ";
uchar code table1[]=" OK! right! " ;
uchar code table2[]="Enter please! ";
uchar code table3[]=" Two times left ";
uchar code table4[]=" one times left ";
uchar code table5[]=" none times left";
uchar code key_table[16] =
{
1,2,3,10,
4,5,6,11,
7,8,9,12,
0,13,14,15
};
uchar password[]={1,2,3,4,5} ; //设定初始密码
uchar save[6]; //保存输入的数据
uchar conflag ; //确认标志
uchar lockflag; //锁键盘标志
uchar startflag; //开始标志
sbit beep=P2^7;
void delay(uint z); //延时子函数
void wright_com(uchar com); //写指令函数
void wright_data(uchar date) ; //写数据函数
void init(); //初始化
void display_OK();
void display_wrong1();
void display_wrong2();
void display_wrong3();// 显示OK
void delete(); //删除输入的最后一个数
uchar keyscan() ; //带返回值的键盘扫描程序
void enter_code(uchar t); //输入密码函数,把输入的数据存入数组中并在屏幕上显示相应的东西,
void confirm(); //确认密码对不对,把输入的数据与密码逐一对比,完全一样刚正确,
void succeed_an(); //输入密码成功时的 响应,
void fail_an(); //输入密码 失败时 响应
void lockkey(); //锁键盘三秒
void alarm(); //发出警报声
void reset(); //复位函数
void display_enter(); //显示输入
void main(void)
{ uchar i=0;
uchar temp;
init();
while(1)
{
uchar i;
if(lockflag)
{
alarm();
// lockflag=0;
temp=keyscan(); // 锁键期间也要进行键盘扫描
if(temp!=No_key) //重新记时三秒
{
aa=0; //重新在定时器中计数
}
}
else
{
temp=keyscan(); //反复扫描输入,等待随时输入
if(temp!=No_key) //有按键按下才进行下面的操作
{
if(temp==10)
{
reset();
startflag=1; //开始标志置位
}
if(startflag)
{
enter_code(temp); //每扫描一次键盘就要进行一次处理,保存输入的数值
if(temp==13) //按下确认键盘就要进行密码确认
{
confirm(); //进行确认判断
if(conflag) //密码确认为正确
{
display_ok(); //密码正确,作出相应的反应
i=0;
}
else
{
i=i+1;
if(i==1)
display_wrong1();
delay(1000);
reset();
if(i==2)
display_wrong2();
delay(1000);
reset();
if(i==3)
{ display_wrong3();
delay(1000);
fail_an(); //密码错误,作相应反应
}
}
}
if(temp==14)
{
delete(); //作删除操作
}
}
}
}
}
}
/****** 显示enter********/
void display_enter()
{
uchar num;
wright_com(0x80);
for(num=0;num<16;num++)
{
wright_data(table2[num]);
}
}
/****** 显示wrong********/
void display_wrong1()
{
uchar num;
wright_com(0x80);
for(num=0;num<16;num++)
{
wright_data(table3[num]);
}
}
void display_wrong2()
{
uchar num;
wright_com(0x80);
for(num=0;num<16;num++)
{
wright_data(table4[num]);
}
}
void display_wrong3()
{
uchar num;
wright_com(0x80);
for(num=0;num<16;num++)
{
wright_data(table5[num]);
}
}
/****** 显示OK********/
void display_OK()
{
uchar num;
wright_com(0x80);
for(num=0;num<13;num++)
{
wright_data(table1[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=0;num<6;num++)
{
save[num]=0; //对输入的数值进行清零
wright_data(' '); //显示的是空格
}
wright_com(0x80+0x40); //下次再输入时可以又从起始位置输入
lockflag=0; //各种变量要清零回起始状态
conflag=0;
j=0;
}
/****** 输入密码正确进行响应********/
void succeed_an()
{
light=0; //灯亮
display_OK(); //显示成功
delay(1000);
light=1; //灯灭
}
/****** 输入密码错误进行响应********/
void fail_an()
{
lockkey();
alarm();
}
/****** 发出警报声**********/
void alarm() //这个以后再扩展它
{
unsigned int k;
for(k=0;k<50000;k++)
{
beep=1;
}
beep=0;
}
/******锁键盘三秒************/
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++;
light1=0;
if(aa>=60) //三秒到了
{
aa=0; //清零可以方便下次再使用
light1=1; //关闭警报
lockflag=0; //标志清零解除键锁,方便下次使用
}
}
}
/******初始化***********/
void init()
{
uchar num;
/*****定时器初始化****/
TMOD=1;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
ET0=1;
EA=1; //开启总中断
TR0=1;//把定时器关闭
/****1602初始化******/
lcdrw=0; //这个必须要置 零,否则无法正常显示
lcden=0;
wright_com(0x38) ; //初始化
wright_com(0x0c) ; //打开光标 0x0c不显示光标 0x0e光标不闪,0x0f光标闪
wright_com(0x01) ; //清显示
wright_com(0x80) ;
for(num=0;num<9;num++)
{
wright_data(table[num]);
delay(1);
}
}
/******1602写入指令************/
void wright_com(uchar com)
{
lcdrs=0;
lcddata=com;
delay(1);
lcden=1;
delay(1);
lcden=0;
}
/******1602写入数据***********/
void wright_data(uchar date)
{
lcdrs=1;
lcddata=date;
delay(1);
lcden=1;
delay(1);
lcden=0;
}
/******延时函数************/
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--) ;
}
/**********4x4矩阵键盘扫描函数*********/
uchar keyscan()
{
uchar temp,num=No_key; //num的初值要为无键盘按下时的返回值
/*********扫描第一行****************/
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;
}
西安邮电大学光电子技术系专业课程设计过程考核成绩表