密码存储模块
24C02C的1、2、3脚是三条地址线,用于确定芯片的硬件地址。在24C02C试验开发板上它们都接地,第5脚和第6脚分别接P3.0和P3.1。第7脚通过一开关与P3.2相连,当按下开关时密码锁直接开启。24C02C中带有片内地址寄存器。每写入或读出一个数据字节后,该地址寄存器自动加1,以实现对下一个存储单元的读写。所有字节均以单一操作方式读取。它与单片机的连接如下图所示。
复位部分
单片机复位是使CPU和系统中的其他功能部件都处在一个确定的初始状态,并从这个状态开始工作。该电路在简单的复位电路下增加了手动复位按键,在接通电源瞬间,电容C1上的电压很小,复位下拉电阻上的电压接近电源电压,即RST为高电平,在电容充电的过程中RST端电压逐渐下降,当RST端的电压小于某一数值后,CPU脱离复位状态,由于电容C1足够大,可以保证RST高电平有效时间大于24个振荡周期,CPU能够可靠复位。增加手动复位按键是为了避免死机时无法可靠复位。当复位按键按下后电容C1通过R1放电。当电容C1放电结束后,RST端的电位由R1与R2分压比决定。由于R1< 晶振部分 AT89S51引脚XTAL1和XTAL2与晶体振荡器及电容C2、C3按下图所示方式连接。晶振、电容C2/C3及片内与非门(作为反馈、放大元件)构成了电容三点式振荡器,振荡信号频率与晶振频率及电容C2、C3的容量有关,但主要由晶振频率决定,范围在0~33MHz之间,电容C2、C3取值范围在5~30pF之间。根据实际情况,本设计中采用12MHZ作为系统的外部晶振。电容取值为30pF。 显示模块 显示部分由液晶显示器LM016L取代普通的数码管完成。开锁时,按下键盘上的开锁按键后,利用键盘上的数字键0-9输入密码,每按下一个数字键后在显示器上显示一个*,输入多少位就显示多少个*。当密码输入完成时,按下确认键,如果输入的密码正确的话, LCD显示“correct”,电子密码锁被打开,如果密 码不正确,LCD显示屏会显示“error”,电子密码锁不能打开。通过LCD显示屏,可以清楚地判断出密码锁所处的状态。电路图如下图所示。 报警部分 报警部分由陶瓷压电发声装置及外围电路组成,加电后不发声,当有键按下时,“叮”声,每按一下,发声一次,密码正确时,不发声直接开锁,当密码输入错误时,蜂鸣器发出噪声报警。如下图所示。 设计总结 1、在本次课程设计中,我通过查阅网络与图书馆搜集到很多相关资料,结合生活中对密码锁的功能特性要求,初步设计出了这一套电子密码锁系统的主要硬件结构和软件结构,基本完成了课题的要求,并在Proteus软件上进行了仿真。 不过由于了解的专业知识尚浅,对课题的研究经验的不足,使得在技术的解决与运用上显得粗糙了一些,特别是功能按键的设定。所幸该系统能基本上完成一个电子密码锁应有的功能特性:开锁提示,输错报警,密码修改,掉电存储。本系统用的是6位密码输入,有106种密码输入方案,相较于机械锁具,防盗能力已经相当不俗。这个系统软硬件设计简单,易于开发,成本较低,安全可靠,操作方便。 2、通过本次毕业设计的锻炼,我学到了很多有关电子密码锁的设计方法与工作原理,巩固了单片机知识。也锻炼了我实践动手能力。 作为一名电气工程及其自动化专业的大三学生,我觉得做单片机课程设计是十分有意义的,而且是十分必要的。在已度过的大学时间里,我们大多数接触的是专业课。我们在课堂上掌握的仅仅是专业课的理论知识,如何去锻炼我们的实践能力?如何把我们所学的专业基础课理论知识运用到实践中去呢?我想做类似的课程设计就为我们提供了良好的实践平台。 最后,要做好一个课程设计,就必须做到:在设计程序之前,对所用单片机的内部结构有一个系统的了解,知道该单片机内有哪些资源;要有一个清晰的思路和一个完整的的软件流程图;在设计程序时,不能妄想一次就将整个程序设计好,反复修改、不断改进是程序设计的必经之路;要养成注释程序的好习惯,一个程序的完美与否不仅仅是实现功能,而应该让人一看就能明白你的思路,这样也为资料的保存和交流提供了方便;在设计课程过程中遇到问题是很正常德,但我们应该将每次遇到的问题记录下来,并分析清楚,以免下次再碰到同样的问题。 3、这次课程设计让我感到了团队合作的重要性。在团队中,我们互帮互助,对整个课程设计来说,这是至关重要的,缺少每一个人都会对我们的设计产生影响。还有要感谢指导老师在我们遇到困难时,给予我们的建议与鼓励。 4、一个月的课程设计结束了,但是从中学到的知识会让我受益终身。发现、提出、分析、解决问题和实践能力的提高都会受益于我在以后的学习、工作和生活中。 源程序 #include #define uchar unsigned char #define uint unsigned int #define C02_write 0xa0 //c02写地址 #define C02_read 0xa1 //c02读地址 #define no0 0x28//定义键码 #define no1 0x14 #define no2 0x24 #define no3 0x44 #define no4 0x12 #define no5 0x22 #define no6 0x42 #define no7 0x11 #define no8 0x21 #define no9 0x41 #define open 0x81 #define modify 0x82 #define enter 0x88 #define backspace 0x84 #define lcm_write_cmd_add XBYTE[0x80FF]//LM016L 控制地址 #define lcm_write_data_add XBYTE[0x81FF] #define lcm_read_busy_add XBYTE[0x82FF] uchar idata temp5_password[6]={0x00,0x00,0x00,0x00,0x00,0x00}; uchar idata key_code[]={no0,no1,no3,no4,no5,no6,no7,no8,no9}; sbit SCL=P3^0; sbit SDA=P3^1; sbit i=P3^2; sbit led=P3^3; sbit beep=P3^4; bit ack; void delay0(uchar x) // 延时函数 { uchar i; while(x--) { for (i = 0; i<13; i++);}} void delayms(uchar i){uchar j; for(;i>0;i--)for(j=124;j>0;j--);} void longdelay(uchar i) {uint j;for(;i>0;i--)for(j=10000;j>0;j--);} void keysound() //按键声音函数 {uchar i; for (i=0;i<180;i++){delay0(5); beep=!beep; //BEEP取反} }void alarm1()//报警函数 { uchar k; for (k=0; k<10; k++)keysound();} void lcm_wait() {while(lcm_read_busy_add&0x80);//读取 LCM忙标志