北邮密码锁小学期报告Word文件下载.docx
《北邮密码锁小学期报告Word文件下载.docx》由会员分享,可在线阅读,更多相关《北邮密码锁小学期报告Word文件下载.docx(44页珍藏版)》请在冰点文库上搜索。
1、密码键盘的输入:
包括0-9数字输入、A-F为功能键。
键盘默认如下:
1234
5678
90AB
CDEF
其中A代表reset(复位),B代表*,C代表关锁,D代表clear(删除),E代表change(修改),F代表#。
2、液晶显示:
主要用于液晶显示屏将具体输入数字用*号代替,便于用户看到自己是否输入六位。
最开始显示“Welcome”字样,然后显示操作指南“A=reset,B=*,C=close,D=del,E=change,F=#,”密码输入正确显示“right”,密码输入错误显示“wrong”。
(2)处理技术:
1、密码正误信息输出:
“确认”输入后,扫描键盘,与EEPROM中的内置密码相比较,若相同,进入“密码重置”功能;
否则,在三次提示输入错误后蜂鸣器鸣响报警。
2、密码重置:
密码正确后,提示是否修改密码,修改按“g”。
两次输入一致后修改内置密码并液晶屏文字提示。
否则进入“开锁功能”。
(3)扩展功能:
倒计时功能:
密码三次输入错误后需间隔1分钟(或更久)后才能再次输入,需两位数码管进入倒计时。
液晶显示变幻:
可实现闪烁,无限滚动等效果(利用C语言编程实现)。
基本原理:
二.硬件设计
1.系统硬件设计思路
系统以Atmega16单片机为控制核心,4*4键盘作为输入模块,1602液晶显示屏作为显示模块实现密码锁的各项功能。
(1)系统硬件方框图如下:
(2)系统工作的流程图如下
判断密码正误
正确
错误
判断是否修改密码
重新输入
判断三次内是否输入正确
否
是
LED灯亮(代表开启)
修改密码
及确认
2.电路连接原理
(1)键盘电路:
4*4键盘采用行列式键盘,使用单片机的8个I/O端口就可以控制16个按键。
键盘的8个引脚分别接在PORTB的8个端口。
对键盘进行扫描时,可以采用查询扫描的方法:
先对一行进行扫描,再对列进行扫描,直至将每行每列都扫描一次,通过单片机端口电平的变化,判断哪个按键被按下。
(2)LCD液晶显示电路:
1602液晶主要用于与用户交互,提示密码输入状态和显示结果。
其中LCD的7~14号引脚分别连结单片机的PORTA各端口,用于数据的并行传输。
4~6号引脚与PC0,PC1,PC7相连,分别控制RS(数据/指令寄存器选择)、RW(读写选择引脚)、E(读写使能引脚)。
相关功能,我们参照1602的数据手册。
(3)蜂鸣器电路:
蜂鸣器电路用于报警。
当密码输入错误时,单片机的PD1端口便会输出高电平,蜂鸣器即发出报警声。
(4)开锁电路:
在此,用指示灯模拟继电器。
当密码输入正确时,单片机的PD0端口便会输出高电平,此时发光二极管发光。
如果二极管亮,说明锁已开;
如果不亮,则锁未打开。
3.电路原理图
1.程序设计思想
(1)键盘扫描:
键盘扫描程序的流程图如下图所示。
对键盘进行查询扫描,确定有键按下后,读取键值,进行延时去抖,再次读取键值,若两次键值相等则返回键值。
一般情况下,我们运用软件进行延时去抖,通常用delay_ms(10),在此期间CPU不能进行其它工作。
(2)LCD显示程序:
根据1602的数据手册,我们可以针对其各引脚的定义和内部结构,定义显示字符函数、显示字符串函数、清屏函数和初始化函数,在后续程序中调用即可。
(3)整体流程:
此程序通过设置多个全局变量把各部分的程序统一成为整体。
其中input_sign用于标记是否有键按下,当其为1时代表有键按下;
state用于标记功能,state=0代表输入密码,state=1代表密码输入成功,state=2代表改密码,state=3代表修改键盘,state=4代表功能选择;
数组password[]用于存储密码;
数组key[][]用于存储键值。
运用if语句即可实现各种功能。
实验器材
4*4键盘
1个
1602液晶显示
蜂鸣器
发光二极管
1.实验历程
(1)9月22日确定设计方案
(2)9月23日-25日上午第一实验周期
9月23日,上午进行视频学习,下午完成电路的一些基本的连接。
9月24日上午,检查硬件和管脚。
观看关于键盘和液晶显示的所有视频。
有一个初步的想法。
完成所有电路的连线和布局。
9月24日下午,确定原设计方案下管脚不够。
更改设计方案:
取消数码管,准备将倒计时功能模块置于液晶屏上显示。
此时出现芯片无法写入的情况。
9月25日上午,和同组同学经过多方排除故障原因,最终更换芯片解决问题。
编写扫描键盘和在液晶显示屏上两个大函数。
(3)9月25日中午-9月27日上午第二实验周期
9月25日中午,完成线路重新设计及布局。
进入单步功能实现及测试。
9月25日下午,按照设计思想编写代码,主要是写键盘控制状态的那个功能函数,主要解决键盘控制不了显示屏的问题
9月26日上午,解决了键盘的控制问题。
然后检测并实现了前边写的LED双行显示功能。
9月26日下午,编好了显示屏和键盘的所有函数,并调试成功。
(3)9月26日晚至9月27日上午
26日晚调试基本功能成功。
并经过十几次的测试,解决了好多细小的问题。
和同伴编写了倒计时的代码。
27日上午,在其基础上添加显示指南代码,进行整体功能调试。
并请老师验收了实验。
2.系统测试过程和结果(截图)
(1)欢迎界面
(2)操作指南无限循环
(3)当任意按一个键,进入键盘解锁界面(4)进入输入密码界面
(5)输入六位密码(6)判断正误(左边正确,右边错误)
(7)如果正确,进入判断是否修改密码界面(8)修改密码,输入两次确认
(9)如果输入错误达到三次,进入倒计时(10)倒计时结束,恢复到初始状态
(1)分工:
李向前:
在第一次实验周期中解决电路连接中管脚不够,芯片无法写入的问题,确定解决方案。
负责LED显示屏代码的编写和原理研究,编程实现双行滚动显示的功能段代码,并在最后实验调试中发挥了较大作用。
闫圆圆:
负责两次实验周期中的布线工作。
认真研究键盘原理,实现键盘模块功能,编写了键盘的扫描函数和键盘相应状态控制函数,当然也完成了其它一些小函数的编写。
在最后实验调试中提出了很多宝贵意见。
(2)合作:
倒计时部分代码由双方讨论决定。
两人一起完善出了最终的代码。
在遇到没有预期的功能时,两个人总是携手一起解决。
(1)实验总结
①概括这次实验
4键盘和LCD液晶显示,实现了密码锁的相应功能。
我们的出发点是设计出既安全又成本低的密码锁。
我们的密码锁有如下功能:
密码验证、修改密码、输入错误后鸣笛等基本功能,当然也有复位后启动倒计时功能、显示操作指南等两个创新功能。
我们收获了很多基础知识,比如说:
对键盘进行扫描时,可以采用查询扫描的方法,即先对一行进行扫描,再对列进行扫描,直至将每行每列都扫描一次,通过单片机端口电平的变化,判断哪个按键被按下。
当然,我们也掌握了液晶显示屏的各个管脚的左右,也掌握了ATmega16的各个管脚的作用。
自然,我们不仅收获了上面所说的知识,也锻炼了自己的动手能力和解决问题的能力。
最重要的是也培养了我们团结协作的能力。
②实验中遇到的问题以及解决方案
有一句话说的好“Manerrssolongashestrives”,意思也就是说,人只要奋斗就会犯错误。
这次实验真的出现了好多错误,但是最终我们都克服了它们。
1.本身是打算用数码管显示倒计时的,发现它如预期的一样,PC2-PC5管脚不能用,尝试改变它的熔丝位试一试,结果以失败告终。
2.可能是由于上面修改熔丝位,或者连电路的时候出了一些小问题,我们的液晶显示屏就是不能用。
之后拆了原来辛辛苦苦连的电路,只是往单片机里写一些控制二极管发光的代码,也写不进去了。
最后判断是单片机锁死了,我们换了一个ATmega16芯片后,终于解决了问题。
3.当然,我的主要工作是键盘模块。
我认真的看了视频,但是,当写入代码的时候发现,不能控制键盘,而且按#键的时候会发生复位问题,当时觉得很奇怪。
后来经过不断地探索,发现是判断按键的那段代码的思路错了,最终可以了,但是奇怪的是,最右边的那一排,一按就复位了。
后来发现是导线错连了一位,有一根导线,连到了reset引脚。
最终解决了这个问题。
4.紧接着就是显示屏的代码问题,会遇到一些字符显示太快,或者是没有达到预期的结果,但是都通过不断地修改断码来解决问题。
距离说一下,就是我要实现的功能是按了*键之后,显示”press#”,但是每次都显示“press*”,后来发现是函数里有一个case少了一个break。
5.最后呢是显示倒计时,刚开始显示乱码。
最后写了这样一个函数LCD_show(m,n);
利用for循环,把数组里的0,1,2等换成‘0’,‘1’,‘2’才解决了问题。
(2)心得体会
一分耕耘一分收获,这次实验,把这句话展现的淋漓尽致。
我想在实验成功的那一刹那,就是对我们这历时两周的忙碌最好的报答。
这次实验还算顺利,在规定日期前就完成了任务。
时间呢,可能大部分花费在解决一些不可预知的问题上了,无论是连电路,还是写代码,虽然也会出现问题,整体来说还算顺利。
很喜欢这样的小学期,它不仅可以增长我们的知识,还可以锻炼我们的动手能力,还可以增进同学之间团结互助的感情。
这样的小学期,充满了乐趣,探索和收获。
有时候一整天都待在实验室,虽然说累,但是感觉整个人都充满了能力。
怀揣着一份新奇,不断尝试,感觉那样的日子很充实,很快乐。
再来说说这次实验,真的是很用心的看视频,然后动手做流水灯,刚开始拿着ATmega16和面包板,真的感觉很新奇,在这之前都没有接触过呢。
看着视频,当看到流水灯工作的时候,觉得那是我见过最美的灯了。
接着呢,就是用2个数码管做一个秒表计时器,实现按下按键后能中断的功能。
感觉中断真的是较难的一个知识了,视频都看了好多编,最后才搞清楚。
中间放假三天,然后我们开始着手设计方案,找自己感兴趣的课题,当然也有想过,做一个更复杂的,更好玩的。
有想过去做一个游戏机,类似快乐大本营的那个拼音游戏,把它做到一个板子上,玩着更方便。
但是后来觉得无法突破判断是否正确的那个环节,所以就结束了那个想法。
后来又考虑做一个智能垃圾箱,可以用手的感应去控制垃圾箱的开关,觉得模拟起来对于材料要求较高,所以最终做一个密码锁,即使用,又在我们的能力范围内。
总之,这次实验真的收获了很多,虽然遇到的问题很多,但是解决问题的过程真的是受益匪浅。
参考资料:
1、《基于AVR的单片嵌入式系统原理与实践应用》华东师范大学电子科学技术系马潮
2、《avr单片机原理及测控工程应用》
代码
#include<
avr/io.h>
string.h>
#defineucharunsignedchar
#defineuintunsignedint
unsignedcharkey_stime_ok;
unsignedcharkey_temp=0;
unsignedcharerror=0,number=0;
unsignedcharkey_stime_counter;
unsignedcharanimation_state=0;
unsignedcharcode_number[6],temp1[6],temp2[6];
intpassword[6]={6,6,6,6,6,6};
uchartime_show[]={'
0'
'
1'
2'
3'
4'
5'
6'
7'
8'
9'
:
'
};
ucharinstr[]="
A=reset,B=*,C=close,D=del,E=change,F=#,"
;
voidxianshi(uchara[]);
#defineNo_key255
#defineK1_11
#defineK1_22
#defineK1_33
#defineK1_44
#defineK2_15
#defineK2_26
#defineK2_37
#defineK2_48
#defineK3_19
#defineK3_20
#defineK3_3'
r'
#defineK3_4'
*'
#defineK4_1'
s'
#defineK4_2'
c'
#defineK4_3'
g'
#defineK4_4'
#'
#defineKey_mask0b00001111
voiddelay(uintms)//延时函数
{
uinti,j;
for(i=0;
i<
ms;
i++)
{
for(j=0;
j<
1141;
j++);
}
}
voidwrite_com(ucharcom)//写指令
{
PORTC&
=~0x01;
=~0x02;
PORTA=com;
PORTC|=0x80;
delay
(1);
=~0x80;
voidwrite_dat(uchardat)//写数据
PORTC|=0x01;
PORTA=dat;
voidLCD_show(intx,inty)//显示倒计时
write_com(0x80+3);
delay(5);
write_dat(time_show[x]);
write_com(0x80+4);
write_dat(time_show[y]);
//delay(35);
voidshow(ucharj)//显示屏
uchari;
write_com(0x0c);
write_com(0x06);
write_com(0x80+0);
switch(j)
case0:
{
write_com(0x01);
delay(5);
write_com(0x80+9);
uchartable[]="
Welcome!
"
//显示welcome
for(i=0;
8;
{
write_dat(table[i]);
delay
(1);
}
delay(10);
9;
i++)//移动9次
write_com(0x18);
delay(10);
xianshi(instr);
break;
}
case1:
{
uchartable1[]="
*"
1;
{
write_dat(table1[i]);
delay
(1);
}
case2:
uchartable2[]="
press#"
7;
write_dat(table2[i]);
case3:
uchartable3[]="
press*"
write_dat(table3[i]);
case4:
uchartable4[]="
thenpress#"
write_com(0x80+40);
//让字符在第二行显示
12;
write_dat(table4[i]);
case5:
uchartable5[]="
inputthecode"
14;
write_dat(table5[i]);
case6:
//先清屏
uchartable6[]="
right"
5;
write_dat(table6[i]);
case7:
uchartable7[]="
open"
4;
write_dat(table7[i]);
case8:
uchartable8[]="
pressg"
write_dat(table8[i]);
case9:
uchartable9[]="
wrong"
write_dat(table9[i]);
case10:
uchartable10[]="
changecode"
11;
write_dat(table10[i]);
case11:
uchartable11[]="
inputagain"
write_dat(table11[i]);
case12:
write_com(0x01);
uchartable12[]="
ok"
2;
write_dat(table12[i]);
case13:
uchartable13[]="
modifypassword"