单片机课设计Word文件下载.docx
《单片机课设计Word文件下载.docx》由会员分享,可在线阅读,更多相关《单片机课设计Word文件下载.docx(40页珍藏版)》请在冰豆网上搜索。
附录一总电路原理图............................................11
附录二用lochmaster绘制的电子密码锁图像.....................................12
附录三电子密码锁的实物图.....................................12
附录四元器件清单.............................................13
附录五源程序清单..............................................15
1、课题设计目标
1、设计任务:
本设计采用单片机为主控芯片,结合外围电路,组成电子密码锁,用户想要打开锁,必先通过提供的键盘输入正确的密码才能将锁打开,密码输入错误将不能打开锁。
2、方案总体设计
2.1设计思路
该电路是一种采用以AT89S52为核心的单片机控制方案。
利用单片机灵活的编程设计和丰富的IO端口,及其控制的准确性,不但能实现基本的密码锁功能,还能根据实际需要添加调电存储、声光提示功能。
2.2方案确立
(1)为了实现密码的保密性,采用一个4×
4的矩阵式键盘可以任意设置用户密码,从而提高了密码的保密性。
(2)采用LCD显示单元,提高了可读性,提供良好的人机界面。
3、硬件电路方框图
电路由两大部分组成:
AT89S51单片机及其外围电路和密码锁电路。
密码锁电路包含,矩阵键盘输入、LCD指示电路、报警控制电路、AT24C02掉电存储电路。
其原理方框图如图3.1所示。
3.1单片机及其最小系统
3.1.1复位电路的设计
复位是单片机的初始化操作。
单片机启运运行时,都需要先复位,其作用是使CPU和系统中其他部件处于一个确定的初始状态,并从这个状态开始工作。
因而复位是一个很重要的操作方式。
但单片机本身是不能自动进行复位的,必须配合相应的外部电路才能实现。
该复位电路采用按键电平复位式复位电路。
当单片机已在运行当中时,按下复位键S后松开,在复位引脚RET(9脚)脚持续出现24个振荡器脉冲周期(即2个机器周期)的高电平信号将使单片机复位。
也能使RST为一段时间的高电平,从而实现上电或开关复位的操作。
如图3.2所示。
图3.2复位电路
3.1.2时钟电路的设计
冲的驱动下的进行的,如果单片机的时钟电路停止工作,晶振停振,那么单片机也就停止运行了。
当采用内部时钟时钟电路为单片机产生时序脉冲,单片机所有运算与控制过程都是在统一的时序脉时,连接方法如下图所示,在晶振引脚XTAL1(19脚)和XTAL2(18)脚,引脚之间接入一个11.0592MHZ晶振,两个引脚对地分别再接入一个电容即可产生所需的时钟信号,电容的容量一般在几十皮法,如20PF。
如图3.3所示。
图3.3时钟电路
3.2密码锁电路
3.2.1按键电路的设计
为了加强密码的保密性,采用一个4×
4的矩阵式键盘可以任意设置用户密码,1-16位长度,从而提高了密码的保密性,同时也能减少与单片机接口时所占用的I/O口线的数目节省了单片机的宝贵资源,在按键比较多的时候,通常采用这种方法。
其原理图如图3.4所示。
图3.4矩阵键盘电路
每一行与每一列的交叉处不相同,而是通过一个按键来连通,利用这种行列式矩阵结构只需要N根行线与M根列线,即可组成具有N×
M个按键的矩阵键盘。
在这种行列式矩阵键盘编码的单片机系统中,键盘处理程序首先执行等待按键并确认有无按键按下的程序段。
当确认有按键按下后,下一步就是要识别哪一个按键被按下。
对键的识别方法通常有两种,一种是通用的组行扫描查询法,另一种是速度较快的线反转法。
此系统中,我们采用线反转法。
首先辨别键盘中有无按键被按下,在单片机I/O口向键盘送全扫描字然后读入行线状态来判断。
具体方法是,向行线输出全扫描字00H,把全部列线置成低电平,然后将列线的电平状态读入累加器A中。
如果有按键被按下,总会有一根行线电瓶被拉至低电平从而使行线不全为1。
判断键盘中哪一个按键被按下通常是通过将列线逐列至低电平后,检查行输入状态来实现的。
方法是,依次给列线送低电平然后检查所有行线状态,如果全为1,则所按下的按键不在此列,如果不全为1,则所按下的按键必在此列,而且是在与零电平行线相交的交点上的那个按键。
10个数字键用来输入密码,另外2个功能键分别是:
确认、取消。
其中退格键的功能是当输入密码错误的时候,清除前面已经输入的数据,重新输入。
确认键的功能是确认输入的密码。
按键功能表
按键
键名
功能说明
0—9键
数字键
输入密码
E键
确认
确认密码
F键
退格
退出
3.2.2LCD显示电路
本系统设计的显示电路是为了给使用者以提示而设置的。
因为系统具有账户管理系统使用LCD可以为用户提供更友好的人机界面,故选用LCD1602作为显示器件。
开锁时,按下键盘上的开锁按键后,利用键盘上的数字键0-9输入密码,每按下一个数字键后在显示器上显示一个*,输入多少位就显示多少个*。
当密码输入完成时,按下确认键,如果输入的密码正确的话,LCD显示“OK”,单片机其中P3.0引脚会输出低电平,使三极管T2导通电磁铁吸合,继电器开关跳转,电子密码锁被打开,如果密码不正确,LCD显示屏会显示“Enterplease”,P3.0输出的是高电平,电子密码锁不能打开。
通过LCD显示屏,可以清楚地判断出密码锁所处的状态。
图3.5显示器电路
显示器主要用于显示以下几个字符指示如图3.6所示。
图3.6(a)开机状态
图3.6(b)等待输入状态
图3.6(c)密码输入正确状态
4、程序设计
4.1模块介绍
本设计将密码锁软件分为以下几个模块(程序见附录程序清单)
(1)主程序模块
主程序主要完成系统及外围电路的初始化,控制LCD根据按键操作进行各个
状态的转化,实现密码锁的人机交互界面。
(2)键盘驱动及键盘输入程序
主要包括键盘扫描的程序,根据按键的布局进行符合操作习惯的键值映射
键盘操作到数据的转换。
(3)LCD1602驱动
包括液晶屏的初始化程序和字符显示,字符串显示等基本函数,供主程序调用。
(4)AT24C02存取程序
包括I2C总线的读写时序模拟控制及读写程序。
主程序流程图如图4.1所示:
图4.1主程序流程图
5、课程设计总结
在做本次课程设计的过程中,我感触最深的当属查阅大量的设计资料了。
为了让自己的设计更加完善,查阅这方面的设计资料是十分必要的,同时也是必不可少的。
我们是在做片机课程设计,但我们不是艺术家,他们可以抛开实际尽情在幻想的世界里翱翔,而我们一切都要有据可依,有理可寻,不切实际的构想,永远只能是构想,永远无法升级为设计。
其次,在这次课程设计中,我们运用到了以前所学的专业课知识,如Proteus制图,C语言等。
虽然过去从未独立应用过它们,但在学习的过程中带着问题去学我发现效率很高,这是我做这次课程设计的又一收获。
最后,要做好一个课程设计,就必须做到,在设计程序之前,对所用单片机的内部结构有一个系统的了解知道该单片机内有哪些资源,要有一个清晰的思路和
一个完整的的软件流程图,在设计程序时,不能妄想一次就将整个程序设计好,反复修改、不断改进是程序设计的必经之路,要养成注释程序的好习惯,一个程序的完美与否不仅仅是
实现功能,而应该让人一看就能明白你的思路,这样也为资料的保存和交流提供了方便,在设计课程过程中遇到问题是很正常德,但我们应该将每次遇到的问题记录下来,并分析清楚,以免下次再碰到同样的问题。
另外,这次课程设计让我感到了团队合作的重要性。
在团队中我们互帮互助,对整个课程设计来说,这是至关重要的,缺少每一个人都会对我们的设计产
生影响。
还有要感谢指导老师在我们遇到困难时,给予我们的建议与鼓励。
一周多的课程设计结束了,但是从中学到的知识会让我受益终身。
发现、提出、分析、解决问题和实践能力的提高都会受益于我在以后的学习、工作和生活中。
6、参考文献
参考文献:
[1]张天凡.完全手册--51单片机C语言开发详解[M].电子工业出版社2008
[2]李群芳.单片微型计算机与接口技术[M].北京电子工业出版社2008
[3]赵景波.ProtelDXP实用教程[M].人民邮电出版社2009
[4]丁明亮唐前辉.51单片机应用设计与仿真--基于KeilC与Proteus[M].北京航空航天大学出版社2009
[5]Atmel.AT89S51DataSheet
[6]ShareWave.LCD1602器件手册
[7]Atmel.AT24C02DataSheet
7、附录:
附录一:
总电路原理图
附录二:
用lochmaster绘制的电子密码锁图像
附录三:
电子密码锁的实物图
附录四:
元器件清单
名称
型号
数量
备注
单片机
AT89C51
1
电阻
6
2
排阻
液晶显示器
瓷片电容
电解电容
16
晶振
单排插针
4
发光二级管
USB接口
垫片及底座
排母
附录五:
源程序清单
#include<
reg52.h>
#defineuintunsignedint
#defineucharunsignedchar
#defineKEYP1//键盘输入端口
#defineNo_key20//无按键时的返回值
#definelcddataP0//1602的数据输入端口
sbitlcden=P2^2;
sbitlcdrs=P2^0;
sbitlcdrw=P2^1;
sbitlight=P3^0;
sbitlight1=P3^1;
ucharj;
//用来统计输入个数的全局变量
ucharaa;
//用来在定时器中计数的全局变量
ucharcodetable[]="
Hello!
"
;
ucharcodetable1[]="
OK!
"
;
ucharcodetable2[]="
Enterplease:
ucharcodekey_table[16]=
{1,2,3,10,4,5,6,11,
7,8,9,12,0,13,14,15};
ucharpassword[]={2,0,1,0,9,3};
//设定初始密码
ucharsave[6];
//保存输入的数据
ucharconflag;
//确认标志
ucharlockflag;
//锁键盘标志
ucharstartflag;
//开始标志
voiddelay(uintz);
//延时子函数
voidwright_com(ucharcom);
//写指令函数
voidwright_data(uchardate);
//写数据函数
voidinit();
//初始化
voiddisplay_OK();
//显示OK
voiddelete();
//删除输入的最后一个数
ucharkeyscan();
//带返回值的键盘扫描程序
voidenter_code(uchart);
//输入密码函数把输入的数据存入数组中
并在屏幕上显示相应的东西,
voidconfirm();
//确认密码对不对把输入的数据与密码逐一对比
完全一样刚正确
voidsucceed_an();
//输入密码成功时的响应,
voidfail_an();
//输入密码失败时响应
voidlockkey();
//锁键盘三秒
voidreset();
//复位函数
voiddisplay_enter();
//显示输入
voidmain(void)
{uchartemp;
init();
while
(1)
{
if(lockflag)
temp=keyscan();
//锁键期间也要进行键盘扫描
if(temp!
=No_key)//重新记时三秒
{
aa=0;
//重新在定时器中计数}
}
else
temp=keyscan();
//反复扫描输入等待随时输入
=No_key)//有按键按下才进行下面的操作
if(temp==10)
reset();
startflag=1;
//开始标志置位
if(startflag)
enter_code(temp);
//每扫描一次键盘就要进行一次处理
保存输入的数值
if(temp==13)//按下确认键盘就要进行密码确认
confirm();
//进行确认判断
if(conflag)//密码确认为正确
succeed_an();
//密码正确作出相应的反应
fail_an();
//密码错误作相应反应
}
if(temp==14)
delete();
//作删除操作}
/******显示enter********/
voiddisplay_enter()
ucharnum;
wright_com(0x80);
for(num=0;
num<
13;
num++)
wright_data(table2[num]);
/******显示OK********/
voiddisplay_OK()
wright_data(table1[num]);
/******删除最后一个********/
voiddelete()
wright_com(0x80+0x40+j);
//确定删除对象
wright_data('
'
);
//显示空格即为删除
save[--j]=0;
//删除后数据清零
//为下次输入数据时写好位置必须是在最后
一个后面
/******对各种变量进行复位********/
voidreset()
ucharnum;
display_enter();
wright_com(0x80+0x40);
//擦除屏幕上的显示
6;
save[num]=0;
//对输入的数值进行清零
//显示的是空格
//下次再输入时可以又从起始位置输入
lockflag=0;
//各种变量要清零回起始状态
conflag=0;
j=0;
/******输入密码正确进行响应********/
voidsucceed_an()
light=0;
//灯亮
display_OK();
//显示成功
delay(1000);
light=1;
//灯灭
/******输入密码错误进行响应********/
voidfail_an()
lockkey();
/******锁键盘三秒************/
voidlockkey()
lockflag=1;
/******输入密码并在屏幕上显示星号******/
voidenter_code(uchart)
if(t>
=0&
&
t<
10)
if(j==0)
wright_com(0x80+0x40);
//第一输入时要先写入地址指令否则无法显示
*'
);
wright_data('
//不是第一个输入则不用再写地址
save[j++]=t;
/******校对密码以确定是不是正确的**********/
voidconfirm()
uchark;
for(k=0;
k<
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)//三秒到了
//清零可以方便下次再使用
light1=1;
//关闭警报
lockflag=0;
//标志清零解除键锁方便下次使用
/******初始化***********/
voidinit()
/*****定时器初始化****/
TMOD=1;
ET0=1;
EA=1;
//开启总中断
TR0=1;
//把定时器关闭
/****1602初始化******/
lcdrw=0;
//这个必须要置零否则无法正常显示
lcden=0;
wright_com(0x38);
wrig