嵌入式系统课程设计报告数字密码锁课程设计报告_第1页
嵌入式系统课程设计报告数字密码锁课程设计报告_第2页
嵌入式系统课程设计报告数字密码锁课程设计报告_第3页
嵌入式系统课程设计报告数字密码锁课程设计报告_第4页
嵌入式系统课程设计报告数字密码锁课程设计报告_第5页
已阅读5页,还剩25页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、 嵌入式系统课程设计报告数字密码锁 摘 要电子数字密码锁是一种通过密码输入来控制电路或是芯片工作,从而控制机械开关的闭合,我们采取的是单片机,它具有超大规模集成电路技术,有极强的数据处理功能,I/O口多。以它为核心设计的密码锁,结构小,功能强,现在很多单位甚至家里的各个家用电器,还有保险箱都需要它。目 录1设计内容及要求 32系统的设计3 2.1系统设计结构图3 2.2系统的工作原理说明43系统硬件设计43.1使用到的元器件列表5 3.2系统各模块简介54电路程序设计64.1软件总设计流程图64.2各模块具体实现7附录1设计总体电路图12附录2数字密码锁源程序131设计内容及要求1、任务设计一

2、多位电子密码锁2、要求1)设计一多位电子密码锁,输入密码用“F”表示,输入密码正确,绿灯亮(或显示其他标志、蜂鸣器替代),输入密码错误,红灯亮(或显示其他标志、蜂鸣器替代)2)具有确定键和取消键,在未确定之前可以取消,重新输入3)连续输入三次错误密码,红灯闪烁,报警电路动作,键盘锁定4)具有密码重置功能5)具有等待操作时间限制功能,超过限定时间报警6)显示北京时间2系统的设计2.1系统设计结构图如下图所示,本设计的真题原理框图如下所示:ADuc848驱动电路报警电路振荡电路LCD1602显示4×4键盘输入复位电路时钟模块图1 硬件系统的总体结构图2.2系统的工作原理说明本系统采用AD

3、uc848单片机为核心的系统,加以4×4矩阵键盘、LED、蜂鸣器等。矩阵键盘分别为0、1、2、3、4、5、6、7、8、9、Enter、Change、Conform、delete。系统开始显示北京时间,按Enter后提示输入密码lcd显示“Enterplease”;输入密码过程中每输入一个密码屏幕上显示一个“*”,当密码输入完毕按下“confirm”键时,若输入密码与设定的密码相同,即密码正确,液晶屏显示为“OK!”提示锁打开,同时蜂鸣器响;若密码不正确,LED显示电路显示提示“wrong”,蜂鸣器响,若连续3次输入不正确,则发出警报声同时锁定键盘。若在输入过程中发现输入错误的数字,可

4、以通过“delete”键删除输入的数字后重新输入。若需要修改预先设定的密码,可以先输入一次正确的密码,然后按下“change”键Lcd显示“change number”,输入完新密码后,按确认键,密码修改完成。为了防止恶意尝试,若连续输入3次密码输入错误则键盘被锁定不能再进行输入操作并发出报警声。3系统硬件设计如图1所示,本系统的硬件部分主要由单片机ADuc848、4×4矩阵键盘、LCD1602、报警电路和驱动电路组成;其中报警电路使用蜂鸣器。总的来说,数字密码锁主要由微处理器模块、键盘模块、声光提示模块和显示模块构成。3.1 使用到的元器件列表元器件 规格/型号 数量单片机 ADu

5、c848 1三极管 8550 1稳压管 7805 1液晶显示器 LCD1602 1晶振 12M 1电阻 10K/1K/100 4/6/1排阻 10K 1电容 104/30Pf4.7uF 3/2/1蜂鸣器 1时钟芯片 1表1 元器件列表3.2 系统各模块简介1.微处理器模块,也就是ADuc848单片机,因为本系统要实现密码检测、密码设定、声光提示等功能,要求微处理器必须能提供很多I/O口,而且由于系统体积限制,很难扩展I/O口和使用外部程序存储器,所以选用ADuc848单片机。2.声光提示模块,由发光二极管LED和蜂鸣器组成,由单片机控制。发光二极管LED有绿色和红色两种,绿色LED亮表示密码输

6、入正确,驱动开锁电路;相反,红色LED亮就表示输入密码错误。蜂鸣器采用5V驱动蜂鸣器,作为报警电路。当输入密码错误次数超 过3次后就发出声音警报。3.显示模块,考虑到友好的人机界面,采用LCD1602液晶显示。显示模块的作用主要是显示提示信息和输入的密码,以方便用户使用。4.键盘模块,键盘模块的作用是让用户输入密码和修改密码。考虑到本系统需要用到大量的按键,键盘模块采用4×4的16矩阵键盘模式。4软件程序设计4.1软件总设计流程图 软件总设计流程图如图12所示。开始LCD初始化时钟显示检测命令键S2S3设置时间S4密码锁界面检测命令键Return键输入密码N密码正确Y开锁N红色LED

7、亮N+1N>3报警YN修改密码修改密码键图12 软件设计流程图4.2 具体功能软件实现4.2.1 4×4矩阵键盘扫描程序当键盘中按键数量较多时,为了减少对I/O口的占用,通常将按键排列成矩阵形式,也称为行列键盘,这是一种常见的连接方式。矩阵式键盘接口见图13所示,它由行线和列线组成,按键位于行、列的交叉点上。当键被按下时,其交点的行线和列线接通,相应的行线或列线上的电平发生变化,MCU通过检测行或列线上的电平变化可以确定哪个按键被按下。图13 4×4矩阵键盘图13为一个4×4行列结构,可以构成16个键的键盘。很明显,在按键数量多的场合,矩阵键盘与独立式按键键

8、盘相比可以节省很多的I/O口线。矩阵键盘不仅在连接上比单独式按键复杂,它的按键识别方法也比单独式按键复杂。在矩阵键盘的软件接口程序中,常使用的按键识别方法有行扫描法和线反转法。这两种方法的基本思路是采用循环查循的方法,反复查询按键的状态,因此会大量占用MCU的时间,所以较好的方式是采用状态机的方法来设计,尽量减少键盘查询过程对MCU的占用时间。图13中,lie0、lie1、lie2、lie3、为4根列线工作于输入方式hang0、hang1、hang2、hang3为4根行线,工作于输出方式,由MCU(扫描)控制其输出的电平值。 行扫描法也称为逐行扫描查询法,其按键识别的过程如下:(1)将全部行线

9、lie0lie3置低电平输出,然后读hang0hang3四根输入列线中有无低电平出现。只要有低电平出现,则说明有键按下(实际编程时,还要考虑按键的消抖)。如读到的都是高电平,则表示无键按下。(2)在确认有键按下后,需要进入确定具体哪一个键闭合的过程。其思路是:依次将行线置为低电平,并检测列线的输入(扫描),进而确认具体的按键位置。如当hang0输出低电平时,测到lie2的输入为低电平,则可确认按键S3处于闭合状态。通过以上分析可以看出,MCU对矩阵键盘的按键识别,是采用扫描方式控制行线的输出和检测列线输入的信号相配合实现的。(3)矩阵按键的识别仅仅是确认和定位了行和列的交叉点上的按键,接下来还

10、要考虑键盘的编码,即对各个按键进行编号。在软件中常通过计算的方法或查表的方法对按键进行具体的定义和编号4x4矩阵键盘扫描函数见附件源程序4.2.2 显示程序本系统使用LCD1602实现显示,只要参照LCD1602的使用手册进行初始化和程序编写就可以显示,即在程序编写中添加LCD1602的驱动程序。这里的驱动程序主要包括:初始化函数、设置显示坐标、写字符函数及写字符串函数。在时钟界面时显示时间的运行,在密码锁界面时主要显示提示信息和输入的密码,当然,当输入密码数字时,输出不是显示数字,而是用“*”显示代替。LCD1602的部分读写控制时序程序如下所示:4.2.3 时钟运行子程序 当系统开始后,L

11、CD1602初始化,然后显示时钟界面,程序在T0中断,进入时钟运行子程序,其流程图如图14所示。T0中断入口 显示时钟数据秒计数加1=500?秒计数0SECOND加1=60?NYSECOND=0,并MINITE加1=60?NYMINITE=0,并HOUR加1=24?NYHOUR=0显示数据处理中断返回图14 时钟运行流程图4.2.4密码比较子程序当输入密码后,调用AT24C02中的密码进行比较,若密码一致,就驱动开锁电路,即绿色发光二极管LED亮,若不一致,红色发光二极管LED亮,如果超过3次输入的密码不正确,此时报警电路就会响应,蜂鸣器响,以及锁住系统。其程序流程图如图18所示。输入密码密码

12、正确N+1N>3报警 开锁YYNN图18 密码比较流程图4.2.5 密码修改子程序修改密码时,先输入旧密码,如果输入的密码正确,再输入新密码,否则返回;输入新密码后要求再次输入新密码,当两次输入的新密码一致时,然后存储到AT24C02中,否则重新输入新密码。修改密码时,如果连续三次输入的旧密码都不正确,报警电路响应。其程序流程图如图19所示。输入旧密码密码正确N+1N>3报警 YYNN存储密码输入新密码再次输入新密码新密码是否一致NY 图19 密码修改流程图附录1 设计总体电路图附录2数字密码锁源程序#include<aduc848.h>#include<time

13、.h>#define uint unsigned int#define uchar unsigned char#define No_key 20 /无按键时的返回值#define lcddata P0 /lcd1602的数据输入端口sbit lcden= P33;sbit lcdrs= P36;sbit lcdrw= P35;sbit light= P30;sbit light1= P32;uchar i;/用来统计输入密码错误次数uchar j ; /用来统计输入 个数的全局变量uchar k;/用来统计改密码时输入的个数uchar aa; /用来在定时器中计数的全局变量 uchar

14、code table1=" OK!" ;uchar code table2="Enter please:" ;uchar code table3="wrong!"uchar code table4="Newpassword:"uchar code key_table16 = 0,1,2,3, 4,5,6,7, 8,9,10,11, 12,13,14,15 ;uchar password=1,2,3,4,5,6 ; /设定初始密码uchar CurrentTime7=40,40,21,6,23,4,11;/初始时间u

15、char save6; /保存输入的数据uchar conflag ; /确认标志uchar lockflag; /锁键盘标志uchar startflag; /开始标志uchar changeflag;/改键标志位uchar timeflag;/时钟标志void delay(uint z); /延时子函数void wright_com(uchar com); /写指令函数void wright_data(uchar date) ; /写数据函数void init(); /初始化void display_OK(); / 显示OKvoid delete(); /删除输入的最后一个数void di

16、splay_wrong();/显示wrong;uchar keyscan() ; /带返回值的键盘扫描程序void enter_code(uchar t); /输入密码函数,把输入的数据存入数组中并在屏幕上显示相应的东西void change_code(uchar t); / 改变密码的函数 ,把输入的数据存到password中void confirm(); /确认密码对不对,把输入的数据与密码逐一对比,完全一样刚正确void succeed_an(); /输入密码成功时的响应void fail_an(); /输入密码失败时的响应 void lockkey(); /锁键盘三秒void rese

17、t(); /复位函数void display_enter(); /显示输入void alarm() ;/密码成功声音void xianshi();/显示时间void xiemaohao();/显示时间中的斜杠void main(void) uchar temp; init(); PLLCON&=0xf8;/设置频率为12.58MHzI2CCON=0xE8;/配置IIC为软件主发送模式 必须SetTime(CurrentTime);SwitchRTC(1); while(1) if(lockflag) temp=keyscan(); / 锁键期间也要进行键盘扫描 if(temp!=No_

18、key) /重新记时三秒 aa=0; /重新在定时器中计数 else temp=keyscan(); /反复扫描输入,等待随时输入 if(temp!=No_key) /有按键按下才进行下面的操作 if(changeflag&&k<6) change_code(temp); else if(temp=10) wright_com(0x01); startflag=startflag; /开始标志置位 if(startflag) reset(); if(startflag) enter_code(temp); /每扫描一次键盘就要进行一次处理,保存输入的数值 if(temp=

19、13) /按下确认键盘就要进行密码确认 confirm(); /进行确认判断 if(conflag) /密码确认为正确 succeed_an(); /密码正确,作出相应的反应 else fail_an(); /密码错误,作相应反应 if(temp=12&&conflag=1) alarm(); changeflag=1;k=0; if(temp=14) delete(); /作删除操作 else /wright_com(0x01) ; ReadTime(CurrentTime); xianshi();xiemaohao(); /写冒号 /* 显示enter*/void disp

20、lay_enter() uchar num;/wright_com(0x01);wright_com(0x80+0x40);for(num=0;num<16;num+)wright_data(' '); wright_com(0x80);for(num=0;num<13;num+) wright_data(table2num); /* 显示OK*/void display_OK() uchar num; wright_com(0x01);wright_com(0x80);for(num=0;num<16;num+)wright_data(' '

21、); /wright_com(0x80+0x40);/for(num=0;num<16;num+)/wright_data(' ');/wright_com(0x80);wright_com(0x80);for(num=0;num<4;num+) wright_data(table1num); /* 显示wrong*/ void display_wrong() uchar num;wright_com(0x01);wright_com(0x80+0x40);for(num=0;num<15;num+)wright_data(' '); wrig

22、ht_com(0x80);for(num=0;num<6;num+) wright_data(table3num); wright_com(0x80+15); wright_data(i+49);/* 删除最后一个*/void delete() wright_com(0x80+0x40+j-1); /确定删除对象wright_data(' '); /显示空格即为删除save-j=0; /删除后数据清零wright_com(0x80+0x40+j); /为下次输入数据时写好位置,必须是在最后一个后面/* 对各种变量进行复位*/void reset()uchar num;di

23、splay_enter();wright_com(0x80+0x40); /擦除屏幕上的显示for(num=0;num<6;num+) savenum=0; /对输入的数值进行清零 wright_data(' '); /显示的是空格 wright_com(0x80+0x40); /下次再输入时可以又从起始位置输入conflag=0;j=0;/* 输入密码正确进行响应*/void succeed_an()display_OK(); /显示成功alarm();/* 输入密码错误进行响应*/void fail_an()if(i>=2) lockkey(); display

24、_wrong(); alarm(); else wright_com(0x80+15); wright_data(i+48); display_wrong(); alarm(); i+ ; /*锁键盘三秒*/void lockkey() lockflag=1; /*改变密码并在屏幕上显示出来*/ void change_code(uchar t) uchar num;if(t>=0&&t<10) passwordk=t; /保存输入的数据 if(k=0) for(num=0;num<12;num+) wright_com(0x80+num); wright_d

25、ata(table4num); wright_com(0x80+0x40) ; /第一输入时要先写入地址指令,否则无法显示 wright_data(passwordk+48) ; else wright_data(passwordk+48);/不是第一个输入则不用再写地址 k+; /*输入密码并在屏幕上显示星号*/void enter_code(uchar t) if(t>=0&&t<10) if(j=0) wright_com(0x80+0x40) ; /第一输入时要先写入地址指令,否则无法显示 wright_data('*') ; else wr

26、ight_data('*') ;/不是第一个输入则不用再写地址 savej+=t; /保存输入的数据 /*校对密码以确定是不是正确的*/void confirm()uchar k;for(k=0;k<6;k+) if(passwordk!=savek) /对数组中的内容进行逐一比较,一旦有数据不对马上退出循环 break; if(k=6) /要是条件退出的话说明六个数全对密码 conflag=1; / 进行标志密码正确 /*中断服务程序*/void timer0(void) interrupt 1 TR0=0; TH0=(65536-50000)/256; TL0=(65

27、536-50000)%256; /重装初值 if(lockflag) aa+; if(aa>=100) /三秒到了 aa=0; /清零可以方便下次再使用 lockflag=0; /标志清零解除键锁,方便下次使用 TR0=1;/*初始化*/void init() /*定时器初始化*/TMOD=1;TH0=(65536-50000)/256;TL0=(65536-50000)%256;ET0=1;EA=1; /开启总中断TR0=1;/把定时器关闭/*1602初始化*/lcdrw=0; /这个必须要置 零,否则无法正常显示 lcden=0;wright_com(0x38) ; /初始化 wri

28、ght_com(0x0c) ; /打开光标 0x0c不显示光标 0x0e光标不闪,0x0f光标闪wright_com(0x01) ; /清显示wright_com(0x80) ;/*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(uin

29、t z) uint x,y; for(x=z;x>0;x-) for(y=110;y>0;y-) ;/*4x4矩阵键盘扫描函数*/uchar keyscan()static bit keyflag=0; /keyflag定义为静态变量 这样的话main中的每个while循环就不会让keyflag重新赋0.unsigned char temp,jianzhi=0xff;P1&=0xf0;P2&=0xf0; temp=P1&0x0f;if(keyflag=0) if(temp!=0x0f) delay(10); if(temp=(P1&0x0f) P2|

30、=0x0e; switch(P1&0x0f) case 0x0e:jianzhi=3;break; case 0x0d:jianzhi=7;break; case 0x0b:jianzhi=11;break; case 0x07:jianzhi=15;break; case 0x0f:break; default:jianzhi= 0x20;break; P2&=0xf0; P2|=0x0d; switch(P1&0x0f) case 0x0e:jianzhi= 2;break; case 0x0d:jianzhi= 6;break; case 0x0b:jianzhi

31、= 10;break; case 0x07:jianzhi= 14;break; case 0x0f:break; default:jianzhi= 0x20;break; P2&=0xf0; P2|=0x0b; switch(P1&0x0f) case 0x0e:jianzhi= 1;break; case 0x0d:jianzhi= 5;break; case 0x0b:jianzhi= 9;break; case 0x07:jianzhi= 13;break; case 0x0f:break; default:jianzhi= 0x20;break; P2&=0x

32、f0; P2|=0x07; switch(P1&0x0f) case 0x0e:jianzhi= 0;break; case 0x0d:jianzhi= 4;break; case 0x0b:jianzhi= 8;break; case 0x07:jianzhi= 12;break; case 0x0f:break; default:jianzhi= 0x20;break; keyflag=1; if(keyflag=1) if(temp=0x0f) /只有在按键松开的时间足够长的时候才会从新开始读键值,即让keyflag为0。 delay(1000);if(temp=0x0f)key

33、flag=0;return jianzhi;/*密码正确的声音*/void alarm() unsigned int b;PWM0H=33;PWM1L=66;PWMCON=0x21; /配置pwm模块工作在方式2,选择频率为32.768khzfor(b=0;b<=30000;b+) ; /响声延时 PWM0H=12;PWM1L=70;PWMCON=0x21; /配置pwm模块工作在方式2,选择频率为32.768khzfor(b=0;b<=30000;b+) ;PWMCON=0x01; /关响声 /*写冒号*/ void xiemaohao() /写冒号wright_com(0x82

34、);/冒号wright_data(0x3a);wright_com(0x85);/冒号wright_data(0x3a); wright_com(0xc4);/写/线wright_data(0x2f); wright_com(0xc7);/写/线wright_data(0x2f); wright_com(0xca);/写,线wright_data(0x2f); /*显示时间*/ void xianshi() wright_com(0x80);/写时wright_data(CurrentTime2/10+48);wright_data(CurrentTime2%10+48); wright_co

35、m(0x83);/写分wright_data(CurrentTime1/10+48);wright_data(CurrentTime1%10+48);wright_com(0x86);/写秒wright_data(CurrentTime0/10+48);wright_data(CurrentTime0%10+48);wright_com(0xc0);/写年高wright_data(0x32); wright_data(0x30);wright_data(CurrentTime6/10+48);wright_data(CurrentTime6%10+48);wright_com(0xc5); /

36、写月wright_data(CurrentTime5/10+48);wright_data(CurrentTime5%10+48);wright_com(0xc8); /写日wright_data(CurrentTime4/10+48);wright_data(CurrentTime4%10+48);wright_com(0xcb); /周几wright_data(CurrentTime3%10+48); 时钟函数程序void iic_start(void);void iic_stop(void);void iic_ack(void);bit read_ack(void);void iic_n

37、ack();unsigned char get_byte(void);void out_byte(unsigned char dd);void IIC_Delay_us(unsigned int times);void ReadTime(unsigned char TIME7); /读时间值void SetTime(unsigned char TIME7); /设置时间初值void SwitchRTC(unsigned char SWITCH); /时间开始走动void ReadTime(unsigned char TIME7) /返回的是十进制的数值时间 bit EATemp; unsign

38、ed char temp; EATemp=EA; iic_start(); /开总线 out_byte(0xd0); /发地址 read_ack(); out_byte(0x00); /发秒地址 read_ack(); iic_stop(); /停总线 IIC_Delay_us(1); iic_start(); out_byte(0xd1); read_ack(); TIME0=get_byte(); iic_ack(); TIME1=get_byte(); iic_ack(); TIME2=get_byte(); iic_ack(); TIME3=get_byte(); iic_ack();

39、 TIME4=get_byte(); iic_ack(); TIME5=get_byte(); iic_ack(); TIME6=get_byte(); iic_nack(); iic_stop(); IIC_Delay_us(1); TIME0=(TIME0&0x7f)>>4)*10+(TIME0&0x0f); /second TIME1=(TIME1&0x7f)>>4)*10+(TIME1&0x0f); /minute /* if(TIME2&0x40) /12小时还是24小时制,d6=1表示12小时制 if(TIME2&am

40、p;0x20)temp=0x80;else temp=0x40; /12小时制 TIME2=(TIME2&0x1f)>>4)*10+(TIME2&0x0f); /hour TIME2|=temp; else TIME2=(TIME2&0x3f)>>4)*10+(TIME2&0x0f); /24小时制 /* TIME3=TIME3&0x07; /week TIME4=(TIME4&0x3f)>>4)*10+(TIME4&0x0f); /date TIME5=(TIME5&0x1f)>>

41、4)*10+(TIME5&0x0f); /month TIME6=(TIME6>>4)*10+(TIME6&0x0f); /year EA=EATemp;/*放置时间初值void SetTime(unsigned char TIME7) bit EATemp; unsigned char temp=0; unsigned char TimeTemp7; EATemp=EA; for(temp=0;temp<7;temp+)TimeTemptemp=TIMEtemp; temp=0; TimeTemp6=(TimeTemp6/10)<<4)+(Tim

42、eTemp6%10); TimeTemp5=(TimeTemp5/10)<<4)+(TimeTemp5%10); TimeTemp4=(TimeTemp4/10)<<4)+(TimeTemp4%10); TimeTemp3=(TimeTemp3/10)<<4)+(TimeTemp3%10); if(TimeTemp2&0xc0)=0x00) TimeTemp2=(TimeTemp2/10)<<4)+(TimeTemp2%10); else if(TimeTemp2&0xc0)=0x01)temp=0x40;else temp=0x60; TimeTemp2&=0x3f; TimeTemp2=(TimeTemp2/10)<<4)+(TimeTemp2%10); TimeTemp2|=temp; TimeTemp1=(TimeTemp1/10)<<4)+(TimeTemp1%10); TimeTemp0=(TimeTemp0/10)<<4)+(TimeTemp0%10); Time

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论