单片机课程设计电子密码锁.doc
目 录1 系统总体设计方案 3 1.1 设计课题任务31.2 功能要求说明31.3 总体方案介绍及工作原理32 硬件系统的设计 42.1 系统各功能模块介绍42.2 系统电路图52.3 系统元器件清单53 软件系统的设计 63.1 设计使用单片机资源介绍63.2 软件系统各功能模块介绍63.3 软件系统程序流程框图63.4 软件系统的程序84 系统的仿真分析及结论 94.1 系统设计的使用说明94.2 系统设计的仿真结果94.3 系统的误差分析 104.4 设计体会 104.5 教学建议10参考文献11致 谢12附录(1)13附录(2) 15摘 要 围绕电子密码锁系统的设计与开发工作进行研究和实践,详细介绍了电子密码锁系统的整体结构、硬件设计、软件设计,系统方案以及其的开发和具体实现。介绍一种基于在系统可编程技术和C51编译器配有集成开发的新型电子密码锁的设计方法,阐述了其工作原理和软硬件设计。在硬件上,用KEIL公司的C51大规模集成芯片对其外围电路进行集成,用1片8051实现了几十片分离元件才能实现的功能,几乎将整个系统下载于同一芯片中,实现了所谓的片上系统,从而大大简化了系统结构,增强了系统的可靠性和性价比。该密码锁特别适用于宾馆、办公大楼、公寓等场所。关键词 密码锁;单片机;硬件设计;软件设计 1 系统总体设计方案1.1 设计课题任务设计一个具有特定功能的密码锁。该密码锁上电或按键复位后能自动显示系统提示符“P.”, 进入准备工作状态。该密码锁设有系统原始密码888888,用户可以设定并存储用户密码,密码输入时应处于保密显示状态,密码输入正确时应显示密码输入正确提示信息,否则,显示密码输入错误提示信息。1.2 功能要求说明 密码锁主要实现的功能是:在输入的密码正确时蜂鸣器发出3S中的鸣叫,同时开锁,但错误时,蜂鸣器发出警报音,也可通过修改密码开锁,一旦密码遗忘可以将原始密码清零后再设新的密码。在进入密码锁环节后,具有输入原始密码,修改密码,当用户遗忘自己设定的密码后,可以要求厂家给出厂密码,输入出厂密码后,系统原始密码自动清零,这时用户需要输入一个新的密码作为以后使用的密码。当用户三次输入原始密码错误后系统将自动锁定,这时需要输入出厂密码进行新密码的设定方可成功。在输入密码模式下,若用户在120秒的时间内没有完成输入操作,则系统将自动退出密码的输入模式。1.3 总体方案介绍及工作原理电子密码锁的总体功能原理是以AT89S52单片机为主要的控制核心,通过外接4*4矩阵式键盘作为信号源,128*64液晶作为显示器件,蜂鸣器作为提示音器件,单片机实时的去执行相应的功能。在液晶上显示出来,而此时通过蜂鸣器发出不同的提示音来告知用户输入的信息是否正确。CPU控制原理图如图1.1所示。2 硬件系统的设计2.1 系统各功能模块介绍2.1.1 AT89S52控制模块考虑到设计功能需要,控制器的功能用于外部键盘信号的接收和识别、液晶显示与密码辨认相关的信息,我们选择了学习过的AT89S52系列单片机,具有反应速度极快,工作效率特高的特点。AT89S52 主要性能 与MCS-51单片机产品兼容 、8K字节在系统可编程Flash存储器,1000次擦写周期,全静态操作:0Hz33Hz 三级加密程序存储器 32个可编程I/O口线 、三个16位定时器/计数器 八个中断源 、全双工UART串行通道、 低功耗空闲和掉电模式 、掉电后中断可唤醒 、看门狗定时器 、双数据指针 、掉电标识符 。 AT89S52 是一种低功耗、高性能CMOS8位微控制器,具有 8K 在系统可编程Flash 存储器。使用Atmel 公司高密度非 易失性存储器技术制造,与工业80C51 产品指令和引脚完 全兼容。另外,AT89S52 可降至0Hz 静态逻 辑操作,支持2种软件可选择节电模式。空闲模式下,CPU 停止工作,允许RAM、定时器/计数器、串口、中断继续工 作。掉电保护方式下,RAM内容被保存,振荡器被冻结, 单片机一切工作停止,直到下一个中断或硬件复位为止。2.1.2 键盘功能模块根据系统的基本的要求,密码的输入和修改要求具有修改和设定等功能,所以采用4*4矩阵式键盘接在AT89S52单片机的接口非常的方便,同时相对于独立式键盘大大节省了资源,在软件的设计时带来了极大的方便,使程序简介,可读性强。在矩阵式键盘中,每条水平线和垂直线在交叉处不直接连通,而是通过一个按键加以连接。这样,一个端口(如P1口)就可以构成4*4=16个按键,比之直接将端口线用于键盘多出了一倍,而且线数越多,区别越明显,比如再多加一条线就可以构成20键的键盘,而直接用端口线则只能多出一键(9键)。由此可见,在需要的键数比较多时,采用矩阵法来做键盘是合理的。矩阵式键盘的按键识别方法用行扫描法。2.1.3 液晶显示模块 显示模块要具有显示输入密码,修改密码的信息准确性,综合以上的要求我选择128*64液晶作为显示的器件,接线主要是数据口接AT89S52单片机,控制线接在PORTF和PORTG两个口的部分口线上. 128*64是一种具有4位/8位并行、2线或3线串行多种接口方式,内部含有国标一级、二级简体中文字库的点阵图形液晶显示模块;其显示分辨率为128*64,.利用该模块灵活的接口方式和简单、方便的操作指令,可构成全中文人机交互图形界面。其基本特征:(1) 低电源电压(VDD:+3.0-+5.5V)(2) 显示分辨率:128×64点(3) 内置汉字字库,提供8192个16×16点阵汉字(简繁体可选)(4) 内置 128个16×8点阵字符(5) 2MHZ时钟频率2.1.4 信息提示模块电子密码锁的另外一个要求功能是在输入密码正确和错误的时候发出报警,利用蜂鸣器来实现。具有电路结构非常简单,控制极其方便等优点。2.2 系统电路图 2.3 系统的元器件清单 本系统中所用到的元件如表2.1所示。表2.1 系统元器件表器件型号数量器件型号数量单片机AT89S521个按键普通17个晶振8MHZ1 个开关6脚双路1个电容22F,33pF1个,2个 液晶显示 128*641个电阻普通若干下载接口10针接口1个蜂鸣器脉冲式1个单排针普通若干3 软件系统的设计3.2 软件系统各功能模块介绍3.3.1 矩阵式键盘模块矩阵式键盘软件设计通过在主程序中调用子程序Uchar keyscan(void)的返回值去执行键功能子程序Void key(void),单片机P0口发出OXF0,之后延时12ms,读取C口线的数据,达到通过键功能程序的分支执行相应的程序段,完成对应的操作。3.2.2 液晶显示模块液晶显示的程序中,将液晶的系统的设置,初始化的程序段写成子程序,等待50ms,显示开关控制初始化,之后只要调用 Void ini(void)和Void set(void),然后执行display();子程序就可以在液晶上随意显示所需的内容。3.2.3 信息提示模块在软件的设计中信息提示模块是通过驱动蜂鸣器产生不同的声音来告诉密锁的状态,通过调用 Void Fmq1(void)和 Void Fmq2(void)两个子程序执行相应的功能,分别表示输入密码正确和错误。当输入正确时发出持续3S的鸣叫,错误时发出警报声。3.3 软件系统程序流程框图软件系统的总体流程框图如图3.1,键扫和显示程序流程框图分别如图3.2、图3.3所示。3.4 软件系统的程序软件系统的程序如附录(2)。4 系统的仿真分析及结论4.1 系统设计的使用说明在通电以后主要在液晶上显示欢迎光顾,用户可以按转换键进入系统模式。其具体的操作布骤是:按转换键进入密码锁模式,按K键一次就次进入了输入密码开锁模式,再按T键判断输入密码是否正确。按K键两次进入输入出厂密码模式,接着按下E键判断出厂密码是否正确。当用户输入出厂密码正确后,可以按下X键进行新的密码的设置,输入六位数的新密码后,按下E键确认新密码设置成功。当用户已经进入了任何一种密码输入模式但是想返回主界面的时候,可以按下R键返回主界面。4.2 系统设计的仿真结果仿真主要争对是对4*4矩阵式键盘和液晶,在按键盘不同的键值的时,显示正确的输入信息,在按下了键1和键A,仿真的结果如图4.1和4.2所示。 图4.1 按键1的仿真结果 图4.2 按键A的仿真结果4.3 系统的误差分析 系统准备工作结束后,在硬件调试中有时候按下键但却没反应者是最主要的误差,也许这是老话的现象以及硬件的焊接有些地方存在虚焊的原因,但是范围很小,还有在最初几次密码存放有一定的问题,但最后发现应安排在数据和程序存储器里的。4.4 设计体会电子技术的快速发展,使一些新型电子器件和集成芯片应用越来越广泛,电子系统的功能越来越强大,印刷电路板越来越复杂和精密。单片机的应用使得我们对各种电路变得模块化,集成化,电子设计自动化(Electronics Design Automates,即EDA)工具的集成设计环境,电子设计软件Protel 软件等的运用使得电子设计电路更加方便,而我做为电子信息工程专业的学生,应该熟练掌握各种电路编辑软件,在这次的设计中我深刻的体会到电子产品的快乐,当我们看到显示屏上一条条信息出现时,好开心,这意味着我们的设计成功了,几十天的努力方案设计,和实践工作我们从中熟练各种电子的技术和强大,并不断地总结经验。这次课设对我们来说非常重要,也是我们最满意的一次,好的开头是成功的第一步,只有经历过,才会懂得过程的重要性。参考文献1马忠梅 单片机C程序设计M,北京:北京航空航天大学出版社,2007 2李广弟 单片机基础M,北京:北京航空航天大学出版社,2007 3张洪润,兰清华,单片机应用技术教程M,北京:清华大学出版社,19974闵锐,徐勇,孙峥等.电子线路基础西安M,西安电子科技大学出版社,2003附 录(1)#include<reg52.h>#include<xianshi.h>bit bb; /密码比较返回值bit bz0; /判断确认键是否按下标志位 bit bz1; /密码比较是否正确标志位bit cc; /是否进行密码修改标志位 bit dd; /是否模拟插卡bit hh; /密码确定修改标志位bit bb1; /万能密码比较返回值bit u; /万能密码输入标志位bit jp; /万能密码输正确标志位bit jp1; /判断确认键是否按下标志位 sbit gg=P37;uchar j; uchar js,kk,tt; uchar ymm=8,8,8,8,8,8; /原始密码uchar xmm=0,0,0,0,0,0; /新密码uchar code wnmm=8,8,0,6,1,2; /万能密码uchar gy;void delay(uint m) while(m-) for(gy=1000;gy-;gy>0); /* 密码比较子程序*/uchar bjmm(void) uchar j; for(j=0;j<6;j+) if(xmmj=ymmj) bb=1; else bb=0; return (bb);/*显示子程序*/void display1(void) display(3,2,"请您输入密码"); display(4,1,"剩余时间: 120 秒");/*蜂鸣器子程序*/void fmq0(void) gg=0; /蜂鸣器鸣叫 delay(2000); gg=1;void fmq1(void) gg=0; /蜂鸣器鸣叫 delay(500); gg=1; delay(200); gg=0; delay(500); gg=1;/*密码修改子程序*/uchar bjmm1(void) uchar e11; for(e11=0;e11<6;e11+) if(xmme11=wnmme11) bb1=1; else bb1=0; return (bb1); /*在液晶上显示输入密码*/void display2(void) if(kk=7) kk=1; switch(kk) /根据kk的数值显示 case 1:display(3,2,"* "); break; /显示1个"*" case 2:display(3,3,"* "); break; /显示2个"*" case 3:display(3,4,"* "); break; /显示3个"*" case 4:display(3,5,"* "); break; /显示4个"*" case 5:display(3,6,"* "); break; /显示5个"*" case 6:display(3,7,"* "); break; /显示6个"*" uchar keyscan(void)uchar scan,tmp;P1=0xf0; /发全行0扫描码if(P1&0xf0)!=0xf0) /若有键按下delay(50); /延时去抖if(P1&0xf0)!=0xf0) /延时再判键是否还按下scan=0xfe;while(scan&0x10)!=0) /逐行扫描 P1=scan; /输出行扫描码 if(P1&0xf0)!=0xf0) /本行有键按下tmp=(P1&0xf0)|0x0f; return (scan)|(tmp); /还回键值 else scan=(scan<<1)|0x01; /行扫描码左移一位 return (0); /无键按下,还回0 /*键功能处理子程序*/void keyc(void) uchar w; w=keyscan(); /调键扫,取得键值 display2();switch(w) case 0x11: if(cc=1) ymmjs=1; js+; kk+; if(js<6&&dd=1) /1键按下,输入密码1 xmmjs=1; js+; kk+; if(js<6&&u=1) xmmjs=1; js+; kk+; break; case 0x12: if(cc=1) ymmjs=2; js+; kk+; if(js<6&&dd=1) /2键按下,输入密码2 xmmjs=2; js+; kk+; if(js<6&&u=1) xmmjs=2; js+; kk+; break; case 0x14: if(cc=1) ymmjs=3; js+; kk+; if(js<6&&dd=1) /3键按下,输入密码3 xmmjs=3; js+; kk+; if(js<6&&u=1) xmmjs=3; js+; kk+; break; case 0x18: if(cc=1) ymmjs=4; js+; kk+; if(js<6&&dd=1) /4键按下,输入密码4 xmmjs=4; js+; kk+; if(js<6&&u=1) xmmjs=4; js+; kk+; break; case 0x21: if(cc=1) ymmjs=5; js+; kk+; if(js<6&&dd=1) xmmjs=5; js+; kk+; /5键按下,输入密码5 if(js<6&&u=1) xmmjs=5; js+; kk+; break; case 0x22: if(cc=1) ymmjs=6; js+; kk+; if(js<6&&dd=1) /6键按下,输入密码6 xmmjs=6; js+; kk+; if(js<6&&u=1) xmmjs=6; js+; kk+; break; case 0x24: if(cc=1) ymmjs=7; js+; kk+; if(js<6&&dd=1) xmmjs=7; js+; kk+; /7键按下,输入密码7 if(js<6&&u=1) xmmjs=7; js+; kk+; break; case 0x28: if(cc=1) ymmjs=8; js+; kk+; if(js<6&&dd=1) /8键按下,输入密码8 xmmjs=8; js+; kk+; if(js<6&&u=1) xmmjs=8; js+; kk+; break; case 0x41: if(cc=1) ymmjs=9; js+; kk+; if(js<6&&dd=1) /9键按下,输入密码9 xmmjs=9; js+; kk+; if(js<6&&u=1) xmmjs=9; js+; kk+; break; case 0x42: if(cc=1) ymmjs=1; js+; kk+; if(js<6&&dd=1) /0键按下,输入密码9 xmmjs=9; js+; kk+; if(js<6&&u=1) xmmjs=0; js+; kk+; break; case 0x44: bz0=1; if(js=6) /确认键按下 bz1=bjmm(); else bz1=0; delay(10); break; case 0x48: for(j=0;j<6;j+) xmmj=0; clear_lcd(); display1(); dd=1; kk=0; break; /密码清零,返回输入界面case 0x81: for(j=0;j<6;j+) ymmj=0;cc=1; display(3,2,"请输入新密码");kk=0;dd=0;break; /是否需要修改密码 case 0x82: dd=1; display(3,2,"请您输入密码"); /模拟插卡信号 delay(12); kk=0; break; case 0x84: if(cc=1) if(js=6) hh=1; cc=0; js=0; /修改密码确认 if(u=1) if(js=6) jp1=1;jp=bjmm1(); break; /万能密码输入确认 case 0x88: u=1; cc=0; dd=0; display(3,2,"输入原始密码"); break; /万能密码输入 break; void main (void) lcdset();display(1,1," 单片机课程设计"); /封面显示display(2,1,"题目: 液晶密码锁"); display(3,1,"设计学生: 曹 璟"); display(4,1,"指导老师: 王 韧");delay(3000);clear_lcd(); display(1,1," 液晶密码锁"); display(2,2,"系统功能介绍"); display(3,3,"正在连接"); display(4,3,"请等待."); delay(3000);clear_lcd();display(1,1,"1.控制器模块");display(2,1,"采用AT89S52 系列"); display(3,1,"2.外接键盘模块"); display(4,1,"采用4*4 矩阵键盘"); delay(3000);clear_lcd();display(1,1,"3.显示模块");display(2,1,"采用SY128*64液晶");display(3,1,"4.声音提示模块");display(4,1,"采用常见的蜂鸣器");delay(3000);clear_lcd();display(3,2,"请您插入房卡");delay(1000); while(1) keyc(); /按键 delay(50); if(jp1=1) if(jp=1) js=0;u=0; jp=bjmm1(); for(j=0;j<6;j+) xmmj=0; /密码清0 if(jp=1) display(3,2,"密码已经清零"); fmq0(); /蜂鸣器开启 jp=0;kk=0; jp1=0; else display(3,2,"原始密码错误"); kk=0;jp1=0; fmq1(); /蜂鸣器开启 if(hh=1) hh=0; kk=0; display(3,2,"密码修改成功"); fmq0(); /蜂鸣器开启 if(bz0=1) js=0;bz0=0; /密码计数器清0 bz1=bjmm(); for(j=0;j<6;j+) xmmj=0; /密码清0 if(bz1=1) display(3,2,"输入密码正确"); fmq0(); /蜂鸣器开启 kk=0; dd=0; /关插卡标志位表已经取卡 else display(3,2,"输入密码错误"); fmq1(); /蜂鸣器开启 kk=0; #define uint unsigned int#define uchar unsigned charuchar command;sbit rs = P20;sbit rw = P21;sbit en = P22;sbit psb = P23;sbit ret = P25;uchar codeyejingtable14=0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39