1、山东交通学院单片机原理与应用课程设计院(部): 轨道交通学院 班 级: 自动化121 学生姓名: 学 号: 指导教师: 时 间: 2015.6.12015.6.12 课 程 设 计 任 务 书题 目 电子密码锁设计 系 (部) 轨道交通学院 专业班级 自动化121 学生姓名 学 号 06 月 01 日至 06 月 12 日 共 2 周指导教师(签字) 系 主 任(签字) 年 月 日一、设计内容及要求本实验基于51单片机利用矩阵按键、步进电机、lcd1602等模块实现电子密码锁的输入密码、密码比对、步进电机的驱动、修改密码等功能。设计内容包括:1)lcd1602显示;2)矩阵按键的输入;3)24
2、C08的储存于读取;4)步进电机的驱动;5)线路的链接。设计要求:1)能演示;2)能回答答辩过程中提问的问题;3)完成设计报告。 二、设计原始资料单片机原理及接口技术 李全利 2010年 1月单片机原理及应用教程 范立南 2006年 1月单片机原理及应用教程 刘瑞新 2003年07月三、设计完成后提交的文件和图表1计算说明书部分1)方案论证报告打印版或手写版2)程序流程图3)具体程序 2图纸部分:具体电路原理图打印版四、进程安排教学内容 学时 地点资料查阅与学习讨论 2天 406实验室分散设计 4天 406实验室编写报告 2天 406实验室成果验收 2天 406实验室 按分组选择不同的实验台,
3、每组3人,题目可重复选择,但每题目不得超过10人。五、主要参考资料 电子设计自动化技术基础马建国、孟宪元编 清华大学出版 2004年4月 单片机原理及接口技术 张毅刚 人民邮电出版社.2008年 实用电子系统设计基础 姜威 2008年1月 单片机系统的PROTEUS设计与仿真 张靖武 2007年4月指导老师成绩答辩小组成绩总成绩目录 摘要.1 1.设计要求.2 2.功能概述.2 3.总体设计.2 4.硬件设计.3 4.1矩阵按键设计.3 4.2 LCD显示设计.4 4.3步进电机模块设计.5 4.4密码修改设计.5 4.5密码比较模块.6 5.软件设计及流程图.6 6.个人体会.8 7.参考文
4、献.9 附录.1020 / 24摘要设计运用了ATMEL公司的AT89S52芯片系统,将微处理器、总线、蜂鸣器、矩阵键盘、存储器和I/O口等硬件集中一块电路板上,通过读取键盘输入的数据(密码)并储存到ATMEL912 24C08存储器中,然后判断之后键盘输入的数据与已存储的数据是否相同来决定打开密码箱或锁键盘或报警。在keil4软件中编程,系统可实现6位密码的处理,并通过控制步进电机控制密码箱门的电子锁,同时还可以修改改密码。利用单片机系统制作的密码箱安全性能更高,更易操作且体积小。关键词:单片机、密码锁、修改密码1.设计要求本实验将实现六位数的电子密码锁。要求使用4X4 行列式键盘作为输入,
5、并用LCD实时显示。具体要求如下:1. 开机时LCD显示“welcome to use”,初始化密码为“123456”,密码可以更改。 2. 按下“10”,开始则显示“Enter Please:”。3. 随时可以输入数值,并在LCD上实时显示*。当键入数值时,为了保密按从左到右依次显示*,可键入值为09。 4. 按下“13”键,则表示确定键按下,进行密码对比。如相符则在LCD第一行显示“Open the door!”,同时指示灯亮起并且步进电机旋转一定的角度;如不符,则LCD第一行显示“Wrong password!”,并且蜂鸣器同时提示一下。如果密码连续三次错误 则蜂鸣器连续响5下,并且持续
6、5秒不能进行任何操作 5.在开锁状态下按下“12”键,进入修改密码状态,LCD同时提示“Enter new code!”。6.14为删除按键,出入之后可以进行删除。7.15按键为关闭按键,只有在打开状态下才可以关闭,按下之后LCD显示“Close the door!”。2.功能概述此设计分为四个功能模块。第一模块:按键输入模块,用于密码的输入以及其他的密码操作按键。第二模块:LCD模块,是与使用者交流的界面,用于显示各种状态下的内容。第三模块:步进电机模块,用于控制密码锁的打开与关闭。第四模块:24C08模块,用于储存输入的密码并读出来。3. 总体设计 本次设计作品的主要构成部分包括80C51
7、单片机、LCD1602、24C08、矩阵按键、LED等、蜂鸣器。 如图1总体仿真图,图2实物图。图1 总体电路图图2 密码锁实物图4.硬件设计4.1 矩阵按键设计如图3所示矩阵按键由P1口控制,了加强密码的保密性,采用一个44的矩阵式键盘可以任意设置用户密码(1-16位长度),从而提高了密码的保密性,同时也能减少与单片机接口时所占用的I/O口线的数目,节省了单片机的宝贵资源,在按键比较多的时候,通常采用这种方法。每一行与每一列的交叉处不相同,而是通过一个按键来连通,利用这种行列式矩阵结构只需要N根行线与M根列线,即可组成具有N M 个按键的矩阵键盘。在这种行列式矩阵键盘编码的单片机系统中,键盘
8、处理程序首先执行等待按键并确认有无按键按下的程序段。当确认有按键按下后,下一步就是要识别哪一个按键被按下。对键的识别方法通常有两种:一种是通用的组行扫描查询法;另一种是速度较快的线反转法。此系统中,我们采用线反转法。首先辨别键盘中有无按键被按下,在单片机I/O口向键盘送全扫描字,然后读入行线状态来判断。具体方法是:向行线输出全扫描字00H,把全部列线置成低电平,然后将列线的电平状态读入累加器A中。如果有按键被按下,总会有一根行线电瓶被拉至低电平从而使行线不全为1。判断键盘中哪一个按键被按下通常是通过将列线逐列至低电平后,检查行输入状态来实现的。方法是:依次给列线送低电平,然后检查所有行线状态,
9、如果全为1,则所按下的按键不在此列;如果不全为1,则所按下的按键必在此列,而且是在与零电平行线相交的交点上的那个按键。图3 矩阵按键电路4.2 LCD显示设计 显示电路是为了给使用者以提示而设置的,显示部分由液晶显示器LCD1602(如图4所示)取代普通的数码管完成。P0口作为数据传输口P2.0、P2.1、P2.2分别连接RS、RW、E。开锁时,按下键盘上的开锁按键后,利用键盘上的数字键09输入密码,每按下一个数字键后在显示器上显示一个*,输入多少位就显示多少个*。当密码输入完成时,如果输入的密码正确的话, LCD显示“open the dore!”。如果密码不正确,LCD显示屏会显示“Wro
10、ng password!”,同时红灯亮起。通过LCD显示屏,可以清楚地判断出密码锁所处的状态。图4 LCD显示屏4.3步进电机模块设计步进电机是一种将电脉冲转化为角位移的执行机构。通俗一点讲:当步进驱动器接收到一个脉冲信号,它就驱动步进电机按设定的方向转动一个固定的角度步进角。您可以通过控制脉冲个来控制角位移量,从而达到准确定位的目的;同时您可以通过控制脉冲频率来控制电机转动的速度和加速度,从而达到调速的目的。步进电机28BYJ48型四相八拍电机,电压为DC5VDC12V。当对步进电机施加一系列连续不断的控制脉冲时,它可以连续不断地转动。每一个脉冲信号对应步进电机的某一相或两相绕组的通电状态改
11、变一次,也就对应转子转过一定的角度(一个步距角)。当通电状态的改变完成一个循环时,转子转过一个齿距。四相步进电机可以在不同的通电方式下运行,常见的通电方式有单(单相绕组通电)四拍(A-B-C-D-A.),双(双相绕组通电)四拍(AB-BC-CD-DA-AB-.),八拍(A-AB-B-BC-C-CD-D-DA-A.)。如图4所示。由ULN2003来控制,ULN2003的1、2、3、4引脚分别连接P3.0、P3.1、P3.2、P3.3口。 图5 步进电机模块4.4 密码修改设计 AT24C02是美国ATMEL公司的低功耗CMOS串行EEPROM,它是内含2568位存储空间,具有工作电压宽(2.55
12、.5V)、擦写次数多(大于10000次)、写入速度快(小于10ms)等特点。下面是它的电路图。 图5中AT24C02的1、2、3脚是三条地址线,用于确定芯片的硬件地址。在AT89C51试验开发板上它们都接地,第8脚和第4脚分别为正、负电源。第5脚SDA为串行数据输入/输出,数据通过这条双向I2C总线串行传送,在AT89C51试验开发板上和单片机的P3.5连接。第6脚SCL为串行时钟输入线,在AT89C51试验开发板上和单片机的P3.4连接。SDA和SCL都需要和正电源间各接一个5.1K的电阻上拉。第7脚需要接地。通过使用24C02便可以实现对密码的储存于读取进一步实现密码锁的改密码功能。 图6
13、 AT24C024.5密码比较设计 该模块将输入密码字符串与设定密码字符串比较。如果相同,执行开锁动作并将输入错误次数清零;如果不同,累计错误次数,如果是第三次输入错误,系统锁死并发出声光告警;如果小于三次,显示密码错误信息,返回密码输入环节。逻辑框图如图6所示。模块启动验证密码判断错误次数显示错误并且锁定10秒发出报警 系统锁死作出相应 的动作连续错误次数小于三次密码正确密码错误 图7 密码比较流程图 5. 软件设计及流程图系统的软件设计采用汇编语言编码。设计方法是先用文本编辑器编写源码,然后用软件Keil C51编译,如果没有错误,可连接生成.HEX格式的文件。如果有错误则无法连接,但可在
14、生成的.OBJ文件中找到代码错误的地方,便于修改。当然也可以直接在Keil中编码。生成的HEX文件是记录文本行的ASCII文本文件,在HEX文件中,每一行是一个HEX记录,由十六进制数组成的机器码或者数据常量。HEX文件经常被用于将程序或数据传输存储到ROM、EPROM,大多数编程器和模拟器使用HEX文件。图8 单片机控制总体电路图7为单片机控制总体电路,图8软件运行流程图。图9 软件运行流程图6.个人体会通过这次课程设计,让我更加深刻了解课本知识,和以往对知识的疏忽得以补充,在设计过程中遇到一些模糊的操作和专业用语,比如说单片机定时器,以及中断的选择,通过对单片机的操作实现自己设计的功能,
15、在使用手册时,有的数据很难查出,但是这些问题经过这次设计,都一一得以解决,我相信单片机这本书中还有很多我为搞清楚的问题,但是这次的课程设计给我相当的基础知识,为我以后工作打下了严实的基础。虽然这次课程是那么短暂的2周时间,我感觉到这些天我的所学胜过我这一学期所学,这次任务原则上是设计,其实就是一次大的作业,是让我对课本知识的巩固和应用,对程序的设计,修改以及调试,使我做事的耐心和仔细程度得以提高。课程设计是培训学生运用本专业所学的理论知识和专业知识来分析解决实际问题的重要教学环节,是对三年所学知识的复习和巩固。同样,也促使了同学们的相互探讨,相互学习。 因 此 , 我 们 必 须 认 真 、谨
16、 慎 、踏 实、一步一步 的 完 成 设 计。如 果 时 间 可 以 重来,我可能会认真的去学习和研究,也可能会自己独立的完成一个项目,我相信无论是谁看到自己做出的成果时心里一定会很兴奋。此次设计让我明白了一个很深刻的道理:团队精神固然很重要,但人往往还是要靠自己的努力,自己亲身去经历,这样自己的心里才会踏实,学到的东西才会更多。参考文献 1 马建国、孟宪元.电子设计自动化技术基础.机械工业出版社.2004. 2 姜威.实用电子系统设计基础.北京理工大学出版社.2008. 3 张靖武.单片机系统的PROTEUS设计与仿真.电子工业出版社.2007. 4 孙福成.KEIL C项目教程.西安电子科
17、技大学出版社.2012. 5 张毅刚.单片机原理及接口技术.人民邮电出版社.2008.8.附录:源程序#include#include #defineOP_READ0xa1/ 器件地址以及读取操作,0xa1即为1010 0001B#defineOP_WRITE 0xa0/ 器件地址以及写入操作,0xa1即为1010 0000B#define uint unsigned int#define uchar unsigned char#define KEY P1#define No_key 20#define lcddata P0sbit SDA=P35; /将串行数据总线SDA位定义在为P3.5引
18、脚sbit SCL=P34; /将串行时钟总线SDA位定义在为P3.4引脚sbit lcden=P22;sbit lcdrs=P20;sbit lcdrw=P21;sbit light=P23;sbit light1=P24;sbit deng=P37;sbit BEEP= P36;uchar j,z,y,j1,j2; /h使用修改后的密码开锁标志位uchar n=0,h=0; /中间标志位 用于传递信息 保证密码修改过后 按复位按键 密码修改标志位不改变uchar aa;uchar code FFW8=0xf1,0xf3,0xf2,0xf6,0xf4,0xfc,0xf8,0xf9;uchar
19、 code REV8=0xf9,0xf8,0xfc,0xf4,0xf6,0xf2,0xf3,0xf1; /反转编码uchar code table =Welcome to use!;uchar code table1=Open the door! ;uchar code table2=Enter Please: ; uchar code table3=Close the door!;uchar code table4=Wrong password!; uchar code table5=Enter new code!;uchar code table6=New code finish;ucha
20、r code key_table16=1,2,3,10, 4,5,6,11, 7,8,9,12, 0,13,14,15;uchar Password=1,2,3,4,5,6; /设置的初始密码uchar save15;uchar mima15;uchar conflag; /确认标志uchar lockflag; /键盘锁定标志uchar startflag; /开始标志uchar open; /门打开标志位uchar begain;/开始标志void delay1(uint t);void delay(uint z);void wright_com(uchar com); /写命令函数voi
21、d wright_data(uchar date); /写数据函数void init(); /初始化函数void display_open(); /显示open the doorvoid display_close();/显示close the doorvoid display_wrong();void display_newcode(); /显示输入新密码void display_codefinish(); / 显示新密码成功void delete(); /删除输入的最后一个数uchar keyscan(); /带返回值的键盘扫描程序void enter_code(uchar t); /vo
22、id enter_code1(uchar t);void enter_code2(uchar t);void confirm(); /确认密码对不对,把输入的数据与密码逐一对比void confirm1();void succeed_an(); /密码正确时的响应void fail_an(); /密码失败时的响应void alarm(); /发出警报声void reset(); /复位函数void reset_save();void display_enter(); /显示输入void motor_ffw();void motor_rev();/*函数功能:延时1ms(3j+2)*i=(333
23、+2)10=1010(微秒),可以认为是1毫秒*/void delay1ms() uchar i,n; for(i=0;i10;i+) for(n=0;n33;n+) ; /*函数功能:延时若干毫秒入口参数:n*/ void delaynms(uint n) uchar i;for(i=0;in;i+) delay1ms(); void start() / 开始位SDA = 1; /SDA初始化为高电平“1” SCL = 1; /开始数据传送时,要求SCL为高电平“1”_nop_(); /等待一个机器周期_nop_(); /等待一个机器周期_nop_(); /等待一个机器周期_nop_();
24、/等待一个机器周期SDA = 0; /SDA的下降沿被认为是开始信号_nop_(); /等待一个机器周期_nop_(); /等待一个机器周期_nop_(); /等待一个机器周期_nop_(); /等待一个机器周期SCL = 0; /SCL为低电平时,SDA上数据才允许变化(即允许以后的数据传递) void stop() / 停止位SDA = 0; /SDA初始化为低电平“0”_nSCL = 1; /结束数据传送时,要求SCL为高电平“1”_nop_(); /等待一个机器周期_nop_(); /等待一个机器周期_nop_(); /等待一个机器周期_nop_(); /等待一个机器周期SDA = 1
25、; /SDA的上升沿被认为是结束信号_nop_(); /等待一个机器周期_nop_(); /等待一个机器周期_nop_(); /等待一个机器周期_nop_(); /等待一个机器周期SDA=0;SCL=0;/*从AT24Cxx读取数据*unsigned char ReadData()/ 从AT24Cxx移入数据到MCUunsigned char i;unsigned char x; /储存从AT24Cxx中读出的数据for(i = 0; i 8; i+)SCL = 1; /SCL置为高电平x=1; /将x中的各二进位向左移一位x|=(unsigned char)SDA; /将SDA上的数据通过按
26、位“或“运算存入x中SCL = 0; /在SCL的下降沿读出数据return(x); /将读取的数据返回/*函数功能:向AT24Cxx的当前地址写入数据*/在调用此数据写入函数前需首先调用开始函数start(),所以SCL=0bit WriteCurrent(unsigned char y)unsigned char i;bit ack_bit; /储存应答位for(i = 0; i 8; i+)/ 循环移入8个位 SDA = (bit)(y&0x80); /通过按位“与”运算将最高位数据送到S /因为传送时高位在前,低位在后 _nop_(); /等待一个机器周期 SCL = 1; /在SCL
27、的上升沿将数据写入AT24Cxx _nop_(); /等待一个机器周期 _nop_(); /等待一个机器周期 SCL = 0; /将SCL重新置为低电平,以在SC线形成传送数据所需的个脉冲y = 1; /将y中的各二进位向左移一位SDA = 1; / 发送设备(主机)应在时钟脉冲的高电平期间(SCL=1)释放SDA线, /以让SDA线转由接收设备(AT24Cxx)控制_nop_(); /等待一个机器周期 _nop_(); /等待一个机器周期 SCL = 1; /根据上述规定,SCL应为高电平_nop_(); /等待一个机器周期 _nop_(); /等待一个机器周期 _nop_(); /等待一个
28、机器周期 _nop_(); /等待一个机器周期 ack_bit = SDA; /接受设备(AT24Cxx)向SDA送低电平,表示已经接收到一个字节 /若送高电平,表示没有接收到,传送异常SCL = 0; /SCL为低电平时,SDA上数据才允许变化(即允许以后的数据传递)return ack_bit;/ 返回AT24Cxx应答位/*向AT24Cxx中的指定地址写入数据*)void WriteSet(unsigned char add, unsigned char dat)/ 在指定地址addr处写入数据WriteCurrentstart(); /开始数据传递WriteCurrent(OP_WRI
29、TE); /选择要操作的AT24Cxx芯片,并告知要对其写入数据WriteCurrent(add); /写入指定地址WriteCurrent(dat); /向当前地址(上面指定的地址)写入数据stop(); /停止数据传递delaynms(4); /1个字节的写入周期为1ms, 最好延时1ms以上unsigned char ReadCurrent() /从AT24Cxx中的当前地址读取数据unsigned char x;start(); /开始数据传递WriteCurrent(OP_READ); /选择要操作的AT24Cxx芯片,并告知要读其数据x=ReadData(); /将读取的数据存入x
30、stop(); /停止数据传递return x; /返回读取的数据unsigned char ReadSet(unsigned char set_addr) /从AT24Cxx中的指定地址读取数据start(); /开始数据传递WriteCurrent(OP_WRITE); /选择要操作的AT24Cxx芯片,并告知要对其写入数据WriteCurrent(set_addr); /写入指定地址return(ReadCurrent(); /从指定地址读出数据并返回void gaimima() /*改密码程序*uchar temp,i;SDA=1;SCL=1;if(z=1)while(1)temp=k
31、eyscan();enter_code(temp);if(temp=13)for(i=0;i6;i+) WriteSet(i,savei); delaynms(10); for(i=0;i6;i+) mimai=ReadSet(i); delaynms(10);display_codefinish();reset_save();break;if(temp=14)delete(); void main(void)uchar temp;y=0;open=1; /open门开关标志位 1为关闭 0为打开while(1)init();if(h=1)deng=0;while(1)begain=0;if(
32、lockflag)temp=keyscan(); /按键期间也要进行键盘扫描if(temp!=No_key) /重新计时三秒aa=0; /重新在定时器中计数elsetemp=keyscan(); /反复扫描输入,等待随时输入if(temp!=No_key) /有按键按下才能进行下一步if(temp=10&open=1)reset();startflag=1; /开始标志位if(startflag)if(h=0)/更改密码前的密码确认enter_code(temp); /每扫描一次键盘就要进行一次处理 保存输入的数值if(temp=13&open=1) /按下确认键进行密码确认confirm()
33、;/进行确认判断if(conflag)succeed_an(); /密码正确作出相应的反应open=0;z=1;reset_save();elsefail_an(); /密码错误作出相应的反应else /更改密码后的密码确认enter_code(temp); /每扫描一次键盘就要进行一次处理 保存输入的数值if(temp=13&open=1) /按下确认键进行密码确认confirm1();/进行确认判断if(conflag)succeed_an(); /密码正确作出相应的反应open=0;z=1;elsefail_an(); /密码错误作出相应的反应if(temp=14)delete();if
34、(temp=12&z=1)reset();display_newcode();gaimima();h=1;/ 改密码成功标志位 用于以后选择密码对比if(temp=15&z=1)uchar r;open=1;display_close();for(r=0;r18;r+) motor_rev(); /电机反转if(temp=11&begain=0&open=1)begain=1;break;void motor_rev() /电机反转函数uchar i;uint j;z=0;for (j=0; j8; j+) /转1n圈for (i=0; i8; i+) /一个周期转45度 P3 = REVi; /取数据 delay1(2); /调节转速void motor_ffw() /电机转动函数 uchar i; uint j; for (j=0; j8; j+) /转1*n圈 for (i=0; i8; i+) /一个周期转45度 P3 = FFWi; /取数据 delay1(2); /调节转速 void display_enter()/显示enteruchar num;wright_com(0x80);for(num=0;num15;num+)wright_data(table2num); void display