1602pcb及电子密码锁课程设计报告附图 代码.docx
《1602pcb及电子密码锁课程设计报告附图 代码.docx》由会员分享,可在线阅读,更多相关《1602pcb及电子密码锁课程设计报告附图 代码.docx(27页珍藏版)》请在冰豆网上搜索。
1602pcb及电子密码锁课程设计报告附图代码
西安邮电大学
专业课程设计报告书
系部名称
:
光电子技术系
学生姓名
:
张娟娟()
专业名称
:
光电信息工程
班级
:
光电1103班
实习时间
:
2013年12月16日至2013年12月27日
专业课程设计报告
内容1:
驱动电路设计
【一】实验目的
利用Protel99SE软件为主题,介绍其基础知识、设计流程、设计方法及电子设计的基本技能等问题,并要求掌握电子产品开发的基本技术问题。
通过实习可以独立实现电路原理图和电路板的设计,为今后的学习和工作中的实际应用打下较为坚实的基础。
用Protel99SE软件绘制一个电路图,图有自己决定。
先绘制出电路原理图,然后进行电气规则检验,没有错误后,生成网络表,然后根据网络表生成印制电路板图,最后自动布局,手工调整,自动布线,手工调整布线,保存。
【二】实验原理
1:
原理图设计
最基本的要求是正确性,其次是布局合理,最后是在正确性和布局合理的前提下力求完美。
(1)启动原理图设计界面,进入Protel99SE,创建一个数据库,执行菜单File/New命令,从框中选择原理图服务器(SchematicDocument)图标,双击该图标,建立原理设计文档。
双击文档图标,进入原理设计服务器界面;
(2)设置原理图设计环境,执行菜单Design/Option和Tool/Preferences,设置图纸大小,捕捉栅格,电器栅格等;
(3)创建自己的元件库,先进入Protel99SE的原理图编辑器,新建一个元件,绘制SCH元件以及放入元件的管脚,给新建的元件改名,绘制制元件的外形以及放入说明文字并保存好,画原理图的时候,就可以调用这些元件了;
(4)装入所需的元件库,在设计管理器中选择Browse区域中的下拉框中选择Library,然后单击ADD/Remove按钮,在弹出的窗口中寻找Protel99SE子目录,在该目录中选择Library\SCH路径,在元件库列表中选择所需的元件库,单击ADD按钮,即可把元件库增加到元件库管理器中;
(5)放置元件,根据实际电路的需要,到元件库中找出所需的元件,然后用元件管理器的Place按钮将原件放置在工作平面上,再根据与按键之间的走线把元件调整好;
(6)原理图布线,利用Protel99SE所提供的各种工具,指令进行布线,将工作平面上的器件用具有点其意义的导线,符号连接起来,构成一个完整的电路原理图;
(7)编辑和调整,利用Protel99SE所提供的各种强大的功能对原理图进一步调整和修改,以保证原理图的美观和正确。
同时对元件的编号,封装进行定义和设定等;
(8)检查原理图,使用Protel99SE的电器规则,及执行菜单命令Tool/ERC对画好的电路原理图进行电气规则检查,若有错误,根据错误情况进行改正。
(9)生成网络表,网络表是电路原理图设计和印刷电路板设计之间的桥梁,执行菜单命令Design/CreateNetlist可以生成具有元件名,元件封装,参数及元件之间连接关系的网络表;
2:
PCB设计
电路设计的最终目的是为了设计出电子产品,而电子产品的物理结构是通过印刷电路板来实现的。
Protel99SE位设计者提供了一个完整电路板设计环境,是电路设计更加方便有效。
应用Protel99SE设计印刷电路板过程如下:
(1)启动印刷电路板设计服务器,执行菜单File/New命令,从框中选择PCB设计服务器(PCBDocument)图标,双击该图标,建立PCB设计文档。
双击文档图标,进入设计服务器界面;
(2)规划电路板,根据要设计的电路确定电路板的尺寸。
选取KeepOutLayer复选框,执行菜单命令Place/Track,绘制电路板的边框。
执行菜单Design/Options,在“SignalLager”中选择BottomLager,把电路板定义为单面板;
(3)设置参数,参数设置是电路板设计的非常重要的步骤,执行菜单命令Design/Rules,左键单击Routing按钮,根据设计要求,在规则类(RulesClasses)中设置参数;
(4)装入元件封装库,执行菜单命令Design/Add/RemoveLibrary,在“添加、删除元件库“对话框中所选取所有元件所对应的元件封装库;
(5)装入网络表,执行菜单Design/LoadNets命令,然后在弹出的窗口中单击Browse按钮,再在弹出的窗口中选择地电路原理图生成的网络表文件(扩展名为Net),如果没有错误,单击Execute。
若出现错误提示,必须更改错误;
(6)Protel99SE既可以进行自动布局也可以进行手工布局,执行菜单命令Tools/AutoPlacement/AutoPlacer可以自动布局。
布局是布线关键性的一步,为了式布局更加合理,最好采用手工布局的方式;
(7)自动布线,Protel99SE采用世界最先静的无网络,基于形式的对角线自动布线技术。
执行菜单命令AutoRouting/All,并在弹出的窗口中单击Routeall按钮,程序即对印刷电路板进行自动布线。
只要设置有关参数,元件布局合理,自动布线的成功率几乎为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电路原理图
图2PCB版图
电子密码锁C程序:
#include
#defineuintunsignedint
#defineucharunsignedchar
#defineKEYP1//键盘输入端口
#defineNo_key20//无按键时的返回值
#definelcddataP0//1602的数据输入端口
sbitlcden=P2^6;
sbitlcdrs=P2^4;
sbitlcdrw=P2^5;
sbitlight=P2^1;
sbitlight1=P2^2;
ucharj;//用来统计输入个数的全局变量
ucharaa;//用来在定时器中计数的全局变量
ucharcodetable[]="Hello!
";
ucharcodetable1[]="OK!
right!
";
ucharcodetable2[]="Enterplease!
";
ucharcodetable3[]="Twotimesleft";
ucharcodetable4[]="onetimesleft";
ucharcodetable5[]="nonetimesleft";
ucharcodekey_table[16]=
{
1,2,3,10,
4,5,6,11,
7,8,9,12,
0,13,14,15
};
ucharpassword[]={1,2,3,4,5};//设定初始密码
ucharsave[6];//保存输入的数据
ucharconflag;//确认标志
ucharlockflag;//锁键盘标志
ucharstartflag;//开始标志
sbitbeep=P2^7;
voiddelay(uintz);//延时子函数
voidwright_com(ucharcom);//写指令函数
voidwright_data(uchardate);//写数据函数
voidinit();//初始化
voiddisplay_OK();
voiddisplay_wrong1();
voiddisplay_wrong2();
voiddisplay_wrong3();//显示OK
voiddelete();//删除输入的最后一个数
ucharkeyscan();//带返回值的键盘扫描程序
voidenter_code(uchart);//输入密码函数,把输入的数据存入数组中并在屏幕上显示相应的东西,
voidconfirm();//确认密码对不对,把输入的数据与密码逐一对比,完全一样刚正确,
voidsucceed_an();//输入密码成功时的响应,
voidfail_an();//输入密码失败时响应
voidlockkey();//锁键盘三秒
voidalarm();//发出警报声
voidreset();//复位函数
voiddisplay_enter();//显示输入
voidmain(void)
{uchari=0;
uchartemp;
init();
while
(1)
{
uchari;
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********/
voiddisplay_enter()
{
ucharnum;
wright_com(0x80);
for(num=0;num<16;num++)
{
wright_data(table2[num]);
}
}
/******显示wrong********/
voiddisplay_wrong1()
{
ucharnum;
wright_com(0x80);
for(num=0;num<16;num++)
{
wright_data(table3[num]);
}
}
voiddisplay_wrong2()
{
ucharnum;
wright_com(0x80);
for(num=0;num<16;num++)
{
wright_data(table4[num]);
}
}
voiddisplay_wrong3()
{
ucharnum;
wright_com(0x80);
for(num=0;num<16;num++)
{
wright_data(table5[num]);
}
}
/******显示OK********/
voiddisplay_OK()
{
ucharnum;
wright_com(0x80);
for(num=0;num<13;num++)
{
wright_data(table1[num]);
}
}
/******删除最后一个********/
voiddelete()
{
wright_com(0x80+0x40+j);//确定删除对象
wright_data('');//显示空格即为删除
save[--j]=0;//删除后数据清零
wright_com(0x80+0x40+j);//为下次输入数据时写好位置,必须是在最后一个后面
}
/******对各种变量进行复位********/
voidreset()
{
ucharnum;
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;
}
/******输入密码正确进行响应********/
voidsucceed_an()
{
light=0;//灯亮
display_OK();//显示成功
delay(1000);
light=1;//灯灭
}
/******输入密码错误进行响应********/
voidfail_an()
{
lockkey();
alarm();
}
/******发出警报声**********/
voidalarm()//这个以后再扩展它
{
unsignedintk;
for(k=0;k<50000;k++)
{
beep=1;
}
beep=0;
}
/******锁键盘三秒************/
voidlockkey()
{
lockflag=1;
}
/******输入密码并在屏幕上显示星号******/
voidenter_code(uchart)
{
if(t>=0&&t<10)
{
if(j==0)
{
wright_com(0x80+0x40);//第一输入时要先写入地址指令,否则无法显示
wright_data('*');
}
else
{
wright_data('*');//不是第一个输入则不用再写地址
}
save[j++]=t;//保存输入的数据
}
}
/******校对密码以确定是不是正确的**********/
voidconfirm()
{
uchark;
for(k=0;k<6;k++)
{
if(password[k]!
=save[k])//对数组中的内容进行逐一比较,一旦有数据不对马上退出循环
{
break;
}
}
if(k==6)//要是条件退出的话说明六个数全对密码
{
conflag=1;//进行标志密码正确
}
}
/******中断服务程序**********/
voidtimer0()interrupt1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;//重装初值
if(lockflag)
{
aa++;
light1=0;
if(aa>=60)//三秒到了
{
aa=0;//清零可以方便下次再使用
light1=1;//关闭警报
lockflag=0;//标志清零解除键锁,方便下次使用
}
}
}
/******初始化***********/
voidinit()
{
ucharnum;
/*****定时器初始化****/
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写入指令************/
voidwright_com(ucharcom)
{
lcdrs=0;
lcddata=com;
delay
(1);
lcden=1;
delay
(1);
lcden=0;
}
/******1602写入数据***********/
voidwright_data(uchardate)
{
lcdrs=1;
lcddata=date;
delay
(1);
lcden=1;
delay
(1);
lcden=0;
}
/******延时函数************/
voiddelay(uintz)
{
uintx,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
/*********