单片机万年历设计Word格式文档下载.docx
《单片机万年历设计Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《单片机万年历设计Word格式文档下载.docx(34页珍藏版)》请在冰豆网上搜索。
点亮第几位(从左记)
1
2
3
4
5
6
7
8
相应的16进制编码
0xfe
0xfd
0xfb
0xf7
0xef
0xbf
0x7f
图2.28位数码管开关位编码
相应的2进制数输出转化位7段数码管显示十进制的编码表如下:
显示十进制
9
16进制输出
0x3f
0x06
0x5b
0x4f
0x66
0x6d
0x7d
0x07
0x6f
图2.37段数码管显示编码
根据以上数据和单片机的各端口功能分布,可以大略得出程序的流程图。
程序开始前,可以先进行一些预处理,使编程过程简化。
2.2.1程序预处理
首先,讲头文件中包含的单片机的各对应引脚定义为较容易书写的格式,同时定义十进制到7段数码管显示对应的8位2进制数转化的数组序列。
然后,定义全局变量(同时初始化初值),方便在各函数间调用和改变年月日时分秒的具体数值,避免使用指针带来的语言复杂性。
最后,对要用到的函数进行统一声明(也可以直接先写函数),防止编程时不合理的调用函数。
2.2.2主函数流程
最重要的主函数流程可归纳如下:
先将2输出端置零,使得显示屏清空。
后建立一永久循环H,表示程序一直运行。
循环的开始再建立一设定好次数的循环J,用来做单片机分频用,其中调用键盘扫描程序,看是否有键按下,以此判定下一步动作。
由于日历的要求控制键不多,课程设计的要求为可切换显示,故最少应有2个控制键来切换日期和时间的显示。
若按下的为显示日期/时间,则对日期/时间相关数据进行处理,由其中一个输出端输出,由另一输出端控制显示在8位数码管的哪一位上,后延时实现一段时间。
最后再次执行键盘扫描函数,看指令是否变化。
固定循环J结束,判断是否按下其他操作键,对时间日期的数据进行人为修改;
若无则向下执行,进行时间/日期的溢出判断和正常增加计数。
最后运行至无限循环H底部,再跳至开头进行上述步骤。
3.2.3相关子函数
键盘检测程序:
由于操作键较少,所以不必使用多重键盘,只需使用单片机一个端口就可以有8个按键供使用。
检测哪个端口有电位变化,就可判断按下的是哪个按键。
延时函数:
就一设定好次数的循环,用以消耗指令周期,循环中可以为空语句,或者为检测、显示语句以确定按键、固定示数。
2.2.4程序总流程图
根据上述文字表达,可以得出程序总流程图如下:
图2.4程序总流程图
根据课程设计的要求和设计流程,结合设计出的电路图,可以设计相应的C语言程序,见附录。
2.3protues设计电路图及仿真
根据所编的程序,可以设计出相应的电路图。
显示部分采用8位7段数码管,虽然年月日/时分秒只用带6位左右,但是为了分隔便于观察,所以增加2位空格显示。
其中将P1口做输入端,用来和8个接地按键相连,构成键盘电路。
P2口做输出口,用来输出时间日期的8位2进制数表达。
P0口做控制端,控制P2输出的信号显示在具体哪个数码管上。
此外,需要提供相应的外部时钟输入XLAT1和XLAT2,再对RET和EA端口赋予相应的电位,使得单片机能够正常工作。
综上,利用protues元件库,可以设计出满足上述条件的显示电路,如下所示:
图2.5仿真电路图
由于对于Protues的晶振元件不是很熟悉,无法设定合适的电路使其起振,故在此用一周期脉冲源替代晶振作为外部时钟。
基本电路完成,将编程生成的hex文件导入到仿真单片机中:
图2.6导入hex文件
按下仿真键,即可开始仿真:
图2.7仿真实时图(显示日期)
图2.8仿真实时图(显示时间)
虽然电路比较简陋,但是基本可以实现对年月日和时分秒的分别显示,且具有清零和更改设置时间的功能。
由于没有采用4×
4键盘,只和P1端口直接链接,所以只有8个操作键,实现显示6个时间和2个更新时间的操作。
由于选用的的数码管最多只能找到8位的,所以就没有增加显示星期的功能。
也因为,我觉得星期本身就是在日期上多加一个限制在7内的计数单元,没有太多的必要,所以就没有设计这个功能。
3心得体会
本次单片机课程设计是一个使用Protues设计工具、协同使用Keil编程软件制作小万年历的题目。
本来以为会很简单,因为课本上就有很接近的习题和讲解,所以开始我也没有很在意,以至时间越拖越后,最后只能赶工完成。
解题过程中,我更加感到之前的判断是多么的天真,单片机的的C语言表示法很多语法与之前学过的C语言不同,特别是单片机的存储结构和指令计数方式是从前没有学到的。
不过时间紧迫,只能临时抱佛脚啃啃教材。
在整个过程中,我深刻地感受并理解到C语言的简便性和丰富性。
不管是从实现功能的角度看还是从数据类型、架构上,都可以看出C语言是一个十分优秀的程序开发语言。
虽然汇编有程序段短小的巨大优势,不过对于我这样新手而言,能用C语言完成这个题目已经很不容易了。
这次作业让我了解怎么从不同的角度去分析同一个问题,让我们有更多更广的思路去处理解题时遇到的难点和要点。
从解决问题的过程中也可以熟悉和了解C语言和Protues程序的不同用法和功能,而各种原有的模板使得我可以用高效,简洁的思路、观点来解题。
这样的探索过程也是很愉悦的,特别是看到自己也能编写一个起码有点样子的仿真程序的时候。
虽然我所完成的作业本身就是很简单的一个基本应用,但在这过程中我所学到的东西令我终生受用。
在如此紧的时间内(好吧,由于之前所述的原因,其实作业很早就布置了,只是我个人因素使得真正在做的时间很短)完成这次作业,甚至我还只是对所应用的语言和软件一知半解的情况下,没有同学和老师的帮助,要完成它简直是不可想象的。
在我落后进度那么多的情况下,多谢有我的同学的帮助,特别是我的单片机的教材找不到时,他分享他的学习资料,使得我得到可以完成这次课程设计的客观条件。
在学习相关语言知识和软件应用时,也多谢老师和其他同学给予的教导和提点。
有这么多的帮助,我相信,只要坚持不懈的努力,一定能够战胜重重的困难,完成此门课程最后一次大作业!
最后,我完成了这次作业,望老师指正。
参考文献
[1]李群芳,张士军,黄建《单片微型计算机与接口技术(第二版)》电子工业出版社2007年1月
[2]楼然苗《51系列单片机设计实例》北京航空航天出版社2003年3月
[3]梁翎,李爱齐《C语言程序设计实用技巧与程序实例》上海科普出版社1996年
[4]李广第《单片机基础》第1版北京航空航天大学出版社1999年
[5]高峰《单片微机应用系统设计及实用技术》机械工业出版社2004年
附录
#include<
reg51.h>
absacc.h>
#defineucharunsignedchar
#defineuintunsignedint
Unsignedcharcodediscode[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
unsignedinti=0,j,m=32,f=25,s=10,r=21,y=7,n=05;
sbitP1_0=P1^0;
sbitP1_1=P1^1;
sbitP1_2=P1^2;
sbitP1_3=P1^3;
sbitP1_4=P1^4;
sbitP1_5=P1^5;
sbitP1_6=P1^6;
sbitP1_7=P1^7;
sbitP0_0=P0^0;
sbitP0_1=P0^1;
sbitP0_2=P0^2;
sbitP0_3=P0^3;
sbitP0_4=P0^4;
sbitP0_5=P0^5;
sbitP0_6=P0^6;
voiddelays(void);
ucharkbscan(void);
ucharinkbscan(void);
voiddisplay(void);
/******************************下面是主程序*************************/
voidmain(void)
{P0=0;
P2=0;
while
(1)
{
kbscan();
//键盘扫描程序
delays();
//延时程序
for(j=600;
j>
0;
j--)
{if(j>
290&
&
j<
550)
{if(i==0)//showday
{P0=0xfe;
P2=discode[n/10];
delays();
P0=0xfd;
P2=discode[n%10];
P0=0xf7;
P2=discode[y/10];
P0=0xef;
P2=discode[y%10];
P0=0xbf;
P2=discode[r/10];
P0=0x7f;
P2=discode[r%10];
}
if(i==1)//?
showtime
P2=discode[s/10];
P2=discode[s%10];
P2=discode[f/10];
P2=discode[f%10];
P2=discode[m/10];
P2=discode[m%10];
}
kbscan();
}
if(i==2){n++;
i=0;
}//yearadd1
if(i==3){y++;
}//yuefenadd11
if(i==4){r++;
}//dayadd1
if(i==5){s++;
i=1;
}//houradd1
if(i==6){f++;
}//minadd1
if(i==7){n=0;
y=1;
r=1;
s=0;
f=0;
m=0;
}//allbe0
{m++;
//秒计数进行
if(m>
59)
{f++;
if(f>
{s++;
if(s>
23)
{r++;
if(r>
30)
{y++;
if(y>
12)
{n++;
if(n>
99)
{n=2;
}
voiddelays(void)//延时程序
{
into;
for(o=80;
o>
o--);
ucharkbscan(void)//键盘扫描程序
if((P1&
0xff)!
=0xff)
if((P1&
if(P1_0==0)i=0;
if(P1_1==0)i=1;
if(P1_2==0)i=2;
if(P1_3==0)i=3;
if(P1_4==0)i=4;
if(P1_5==0)i=5;
if(P1_6==0)i=6;
if(P1_7==0)i=7;
display();
//数码管显示程序
return(i);
voiddisplay(void)//数码管显示程序
P2=discode[i];
此程序可以正常进行编译,生成相应的hex,说明基本语法没有错误。
中文摘要
摘要:
在日常的生活和工作中,住宅与部门的安全防范、单位的文件档案、财务报表以及一些个人资料的保存多以加锁的办法来解决。
若使用传统的机械式钥匙开锁,人们常需携带多把钥匙,使用极不方便,且钥匙丢失后安全性即大打折扣。
随着科学技术的不断发展,人们对日常生活中的安全保险器件的要求越来越高。
为满足人们对锁的使用要求,增加其安全性,用密码代替钥匙的密码锁应运而生。
密码锁具有安全性高、成本低、功耗低、易操作等优点。
在安全技术防范领域,具有防盗报警功能的电子密码锁逐渐代替传统的机械式密码锁,克服了机械式密码锁密码量少、安全性能差的缺点,使密码锁无论在技术上还是在性能上都大大提高一步。
随着大规模集成电路技术的发展,特别是单片机的问世,出现了带微处理器的智能密码锁,它除具有电子密码锁的功能外,还引入了智能化管理、专家分析系统等功能,从而使密码锁具有很高的安全性、可靠性,应用日益广泛。
随着人们对安全的重视和科技的发展,许多电子智能锁(指纹识别、IC卡辨认)已在国内外相继面世。
但是这些产品的特点是针对特定的指纹和有效卡,只能适用于保密要求的箱、柜、门等。
而且指纹识识别器若在公共场所使用存在容易机械损坏,IC卡还存在容易丢失、损坏等特点。
加上其成本较高,一定程度上限制了这类产品的普及和推广。
鉴于目前的技术水平与市场的接收程度,电子密码锁是这类电子防盗产品的主流。
基于以上思路,本次设计使用ATMEL公司的AT89C51实现一基于单片机的电子密码锁的设计,其主要具有如下功能:
(1)密码通过键盘输入,若密码正确,则将锁打开。
(2)报警、锁定键盘功能。
密码输入错误数码显示器会出现错误提示,若密码输入错误次数超过3次,蜂鸣器报警并且锁定键盘。
电子密码锁的设计主要由三部分组成:
4×
4矩阵键盘接口电路、密码锁的控制电路、输出八段显示电路。
另外系统还有LED提示灯,报警蜂鸣器等。
密码锁设计的关键问题是实现密码的输入、清除、更改、开锁等功能:
(1)密码输入功能:
按下一个数字键,一个“-”就显示在最右边的数码管上,同时将先前输入的所有“-”向左移动一位。
(2)密码清除功能:
当按下清除键时,清除前面输入的所有值,并清除所有显示。
(3)开锁功能:
当按下开锁键,系统将输入与密码进行检查核对,如果正确锁打开,否则不打开。
主要的设计实施过程:
首先,选用ATMEL公司的单片机AT89C51,以及选购其他电子元器件。
第二步,使用DXP2004设计硬件电路原理图,并设计PCB图完成人工布线(后因PCB板损坏决定采用万能板焊接的方法)。
第三步,使用KeiluVision3软件编写单片机的C语言程序、仿真、软件调试。
第四部,使用PROTEUS软件进行模拟软、硬件调试。
最后,联合软、硬件调试电路板,完成本次毕业设计。
关键词:
4矩阵键盘;
AT89C51;
密码锁;
密码二次确认
第1章概述
随着科技的发展,单片机已不是一个陌生的名词,它的出现是近代计算机技术发展史上的一个重要里程碑,因为单片机的诞生标志着计算机正式形成了通用计算机系统和嵌入式计算机系统两大分支。
单片机单芯片的微小体积和低的成本,可广泛地嵌入到如玩具、家用电器、机器人、仪器仪表、汽车电子系统、工业控制单元、办公自动化设备、金融电子系统、舰船、个人信息终端及通讯产品中,成为现代电子系统中最重要的智能化工具。
本文所涉及的是市场占有率最高的是MCS—51系列,因为世界上很多知名的IC生产厂家都生产51兼容的芯片。
到目前为止,MCS—51单片机已有数百个品种,还在不断推出功能更强的新产品。
本设计是基于单片机的密码锁设计方案,根据要求,给出了该单片机密码锁的硬件电路和软件程序,同时给出了单片机型号的选择、硬件设计、软件流程图、单片机存储单元的分配、汇编语言源程序及详细注释等内容。
第2章系统总体方案设计
方案一:
采用数字电路控制。
其原理方框图如图1-1所示。
图2-1数字密码锁电路方案
采用数字密码锁电路的好处就是设计简单。
用以74LS112双JK触发器构成的数字逻辑电路作为密码锁的核心控制,共设了9个用户输入键,其中只有4个是有效的密码按键,其它的都是干扰按键,若按下干扰键,键盘输入电路自动清零,原先输入的密码无效,需要重新输入;
如果用户输入密码的时间超过40秒(一般情况下,用户不会超过40秒,若用户觉得不便,还可以修改)电路将报警80秒,若电路连续报警三次,电路将锁定键盘5分钟,防止他人的非法操作。
电路由两大部分组成:
密码锁电路和备用电源(UPS),其中设置UPS电源是为了防止因为停电造成的密码锁电路失效,使用户免遭麻烦。
密码锁电路包含:
键盘输入、密码修改、密码检测、开锁电路、执行电路、报警电路、键盘输入次数锁定电路。
方案二:
采用一种是用以AT89S51为核心的单片机控制方案。
利用单片机灵活的编程设计和丰富的IO端口,及其控制的准确性,不但能实现基本的密码锁功能,还能添加调电存储、声光提示甚至添加遥控控制功能。
其原理如图1-2所示。
89S51
单片机
矩阵
键盘
控制
输入错误锁定键盘
延时报警控制电路
AT24C02掉电存储
指示电路
串口显示电路
图2-2单片机控制方案
通过比较以上两种方案,单片机方案有较大的活动空间,不但能实现所要求的功能而且能在很大的程度上扩展功能,而且还可以方便的对系统进行升级,所以我们采用后一种方案。
本方案采用一种是用以89S51为核心的单片机控制方案。
利用单片机灵活的编程设计和丰富的I/O端口,及其控制的准确性,实现基本的密码锁功能。
初步设计思路如下:
输入密码用矩形键盘,包括数字键和功能键。
LED数码管显示输入密码,用74JS247驱动数码管发光显示数码,用74LS138控制各位显示器分时进行显示。
用发光二极管代替开锁的电路,发光表示开锁。
输入密码错误次数超过3次,系统报警。
打开电源后,显示器显示“000000”,设原始密码为“123456”,只要输入此密码便了开门。
这样可预防停电后再来电时无密码可用。
按“C”键,清除显示器为“000000”。
欲重新设定密码,先输入密码在案“*”。
输入密码,再按“D”键。
若密码与设定密码相同,则开门。
否则显示器清为“000000”。
软件的设计主要包括键盘键值的读取,LED显示程序,密码比较程序和报警程序。
第3章硬件电路设计
3.1键盘电路设计
使用矩阵键盘,所以本设计就采用行列式键盘,同时也能减少键盘与单片机接口时所占用的I/O线的数目,在按键比较多的时候,通常采用这样方法。
其原理如图3.1
。
图3.1矩阵键盘
每一条水平(行线)与垂直线(列线)的交叉处不相通,而是通过一个按键来连通,利用这种行列式矩阵结构只需要N条行线和M条列线,即可组成具有N×
M个按键的键盘。
在这种行列式矩阵键盘非键盘编码的单片机系统中,键盘处理程序首先执行等待按键并确认有无按键按下的程序段。
当确认有按键按下后,下一步就要识别哪一个按键按下。
对键的识别通常有两种方法:
一种是常用的逐行扫描查询法;
另一种是速度较快的线反转法。
对照图3.1所示的4×
4键盘,说明线反转个工作原理。
首先辨别键盘中有无键按下,有单片机I/O口向键盘送全扫描字,然后读入行线状态来判断。
方法是:
向行线输出全扫描字00H,把全部列线置为低电平,然后将列线的电平状态读入累加器A中。
如果有按键按下,总会有一根行线电平被拉至低电平从而使行线不全为1。
判断键盘中哪一个键被按下使通过将列线逐列置低电平后,检查行输入状态来实现的。
依次给列线送低电平,然后查所有行线状态,如果全为1,则所按下的键不在此列;
如果不全为1,则所按下的键必在此列,而且是在与零电平行线相交的交点上的那个键。
具体的功能设计如表3.1:
表3.1按键功能
按键
键名
功能说明
1-9键
数字键
输入密码
*键
重设密码