基于AT89S51D单片机的多功能电子万年历设计 2.docx
- 文档编号:8955504
- 上传时间:2023-05-16
- 格式:DOCX
- 页数:14
- 大小:56.20KB
基于AT89S51D单片机的多功能电子万年历设计 2.docx
《基于AT89S51D单片机的多功能电子万年历设计 2.docx》由会员分享,可在线阅读,更多相关《基于AT89S51D单片机的多功能电子万年历设计 2.docx(14页珍藏版)》请在冰点文库上搜索。
基于AT89S51D单片机的多功能电子万年历设计2
单片机应用系统设计
课题:
基于AT89S51D单片机的多功能电子万年历设计
姓名:
班级:
学号:
指导老师:
日期:
基于AT89S51单片机的多功能电子万年历的设计
目录:
第一章绪论
设计背景及意义
第二章系统总体方案设计
1、系统设计硬件框图
2、系统实现的基本原理
第三章硬件系统设计
1、选择元器件
2、硬件原理图
第四章软件系统设计
1、软件流程图
1.1主函数流程图
1.2LCD显示流程图(孙慧)
1.3DS1302流程图
2、系统的仿真调试
2.1运行步骤
2.2调试过程
第五章设计总结
第六章参考文献
第七章附录
1、源程序代码
1.1主函数源程序代码
1.2LCD显示源程序代码(孙慧)
1.3DS1302源程序代码
第一章绪论
单片机技术是现代电子工程领域一门迅速发展的技术,它的应用已经渗透到各种嵌入式系统中。
可以毫不夸张地说:
掌握单片机技术是电子信息类专业学生就业的一个重要条件。
同时单片机技术又是一门实践性很强的学科。
课程设计教学环节的设计和实施,在很大程度上决定了学生对单片机技术的掌握程度。
为了更好地完成课程设计这一重要教学环节,我们采用Proteus软件与Keil软件整合构建单片机虚拟实验平台。
学生首先在PC上利用Proteus软件自己搭建硬件电路,并利用系统提供的功能完成电路分析、系统调试和输出显示的硬件设计部分;同时在Keil软件中编制程序,进行相应的编译和仿真,完成系统的软件设计部分。
当系统的设计工作完成后,学生可以在PC上看到最终的运行效果。
最后再通过proteus设计PCB,再完成真正硬件的调试。
本次任务完成基于AT89S51单片机的多功能电子万年历的设计,可以让我们在学习理论知识的基础上,更进一步的了解单片机,认识单片机,运用单片机。
目前市场上提供的无论是机械钟还是石英钟在晚上无照明的情况下都是不可见的。
要知道当前的时间,必须先开灯,故较为不便。
现在市场上也出现了一些电子钟,它以六只LED数码管来显示时分秒,与传统的以指针显示秒的方式不同,违背了人们传统的习惯与理念,而且这类电子钟一般是采用大型显示器件,适用于银行、车站等公共场所,且外观设计欠美观,很少进入百姓家庭。
此外,无论是机械钟、石英钟还是电子钟,都存在着共同的问题:
时间误差。
针对以上存在的问题,我们设计了一款采用LCD显示器件显示的电子时钟,有效克服了时钟存在的误差问题。
第二章系统总体方案设计
2-1、电子钟的原理框图如图2-1所示。
它由以下几个部件组成:
单片机89C2051、DS1302芯片、LCD显示部件。
运行时,时间由DS1302芯片实时输出当前到单片机中,在通过单片机写入到LCD显示器中,通过LCD实时显示当前时间。
用LCD显示可以更加清晰看到显示结果,而如果用LED则看到的结果不能很清楚的表示。
2-1原理框图
2-2、DS1302引脚(如图2-2)的功能:
X1,X2:
2.768KHZ晶振接入引脚
I/O:
数据输入/输出引脚,具有三态功能
SCLK:
串行时钟输入引脚
VCC1、VCC2:
工作电源引脚、备用电源引
GND:
接地
:
复位引脚,低电平有效
2-2DS1302的引脚图
第三章硬件系统设计
本设计主要用到单片机AT89C51、时钟芯片DS1302和LCD显示器,还需要按钮、导线、电阻、电容等器件。
总的电路连接图3-1所示:
3-1硬件原理图
用P1.0到P1.4选择和控制时间的校准,P1.0到P1.4可分别对年月、月、日、时、分进行加、减运算,通过P2.4口进行控制这5个口是加还是减。
而DS1302芯片只能有2位的年份,故加一变量qn,并赋值为20作为年份的头部,和DS1302的年份拼起来可一得到20XX年,如超过2099年可通过P2.3口对qn进行加一操作,使其显示21XX年的时间,其他连线如图。
第四章系统软件设计
4-1、设计原理
启动DS1302,初始化芯片,设置初始时间,读出时间,存放在结构体SYSTEMTIME中,然后将时间转化为字符数组,送往LCD显示器。
每隔1S读出时间,重复以上步骤。
这样可以实现时钟的正常显示。
也可以通过按下按钮对时间进行修改校正。
4-2、DS1302流程图
4-3、仿真调试
1)主要步骤:
Ⅰ、在keil软件中新建项目,名位clock;
Ⅱ、在项目中新建文件,写入所有程序代码;
Ⅲ、编译、连接可生成clock.hex文件;
Ⅳ、在Proteus中设计好硬件电路,将clock.hex文件加载到单片机中去;
Ⅴ、运行硬件电路。
2)调试
Ⅰ、起初,运行时只能显示末两位的年份,而且LCD中的Print函数一次最多只能输出8个字符,因此加入YearToStr()函数,在年份前面拼上20后与DS1302输出的时间一起转换为字符数组YearString[],然后在LCD上显示,可以看到20XX的显示格式,之后在显示剩下的数值。
Ⅱ、校时函数起初没有复0功能,以至月份等能加到最大值以上,如月份可以达到14,因此加入if语句进行控制,当超过最大值时将进行清零。
Ⅲ、起初校时函数没有减功能,以至数值一不小心点到后很难改回,后引入P2.4口控制P1.0到P1.4进行加或者减的切换。
第五章设计总结
通过这次单片机课程设计,我不仅加深了对单片机理论的理解,将理论很好地应用到实际当中去,而且我还学会了如何去培养我们的创新精神,从而不断地战胜自己,超越自己。
创新可以是在原有的基础上进行改进,使之功能不断完善,成为真己的东西。
我觉得作为一名电子专业的学生,单片机的课程设计是很有意义的。
更重要的是如何把自己平时所学的东西应用到实际中。
虽然自己对于这门课懂的并不多,很多基础的东西都还没有很好的掌握,觉得很难,也没有很有效的办法通过自身去理解,但是靠着这一个多礼拜的“学习”,在小组同学的帮助和讲解下,渐渐对这门课逐渐产生了些许的兴趣,自己开始主动学习并逐步从基础慢慢开始弄懂它。
我认为这个收获应该说是相当大的。
一开始我们从参考书上找来了课题,但是毕竟是参考书,做到后来发现很多程序都是不完整的,这让我们伤透了脑筋。
看着别的小组都弄得有模有样了,可是我们连一个课题都还没有定好。
好不容易又找到了课题,可是结果还是很不尽人意。
程序接线什么的都弄好了,调试也没有问题,可是就是无法达到预期想要的结果。
我们一起齐心协力,从平时做的实验﹑老师上课的举例﹑书本上的知识以及老师的辅导和其他同学的帮助下终于完成了。
应该说这是通过我们小组成员的共同努力和动脑完成的,虽然内容并不是很复杂,但是我们觉得设计的过程相当重要,学到了很多,收获了很多。
我觉得课程设计反映的是一个从理论到实际应用的过程,但是更远一点可以联系到以后毕业之后从学校转到踏上社会的一个过程。
小组人员的配合﹑相处,以及自身的动脑和努力,都是以后工作中需要的。
第六章参考资料
[1]林志琦.基于Proteus的单片机可视化软硬件仿真[M].北京:
北京航空航天大学出版社,2006.9
[2]周润景,张丽娜.基于PROTEUS的电路及单片机系统设计与仿真[M].北京:
北京航空航天大学出版社,2006.5
[3]谢维成单片机原理与应用及C51程序设计[M].北京:
清华大学出版社
[4]谭浩强C语言程序设计[M]清华大学出版社
第七章附录
3、DS1302源程序代码
#ifndef_REAL_TIMER_DS1302_2003_7_21_
#define_REAL_TIMER_DS1302_2003_7_21_
sbitDS1302_CLK=P1^6;//实时时钟时钟线引脚
sbitDS1302_IO=P1^7;//实时时钟数据线引脚
sbitDS1302_RST=P1^5;//实时时钟复位线引脚
sbitACC0=ACC^0;
sbitACC7=ACC^7;
typedefstruct__SYSTEMTIME__
{
unsignedcharSecond;
unsignedcharMinute;
unsignedcharHour;
unsignedcharWeek;
unsignedcharDay;
unsignedcharMonth;
unsignedcharYear;
unsignedcharYearString[9];
unsignedcharDateString[9];
unsignedcharTimeString[9];
}SYSTEMTIME;//定义的时间类型
#defineAM(X)X
#definePM(X)(X+12)//转成24小时制
#defineDS1302_SECOND0x80
#defineDS1302_MINUTE0x82
#defineDS1302_HOUR0x84
#defineDS1302_WEEK0x8A
#defineDS1302_DAY0x86
#defineDS1302_MONTH0x88
#defineDS1302_YEAR0x8C
#defineDS1302_RAM(X)(0xC0+(X)*2)//用于计算DS1302_RAM地址的宏
voidDS1302InputByte(unsignedchard)//实时时钟写入一字节(内部函数)
{
unsignedchari;
ACC=d;
for(i=8;i>0;i--)
{
DS1302_IO=ACC0;
DS1302_CLK=1;
DS1302_CLK=0;
ACC=ACC>>1;
}
}
unsignedcharDS1302OutputByte(void)//实时时钟读取一字节(内部函数)
{
unsignedchari;
for(i=8;i>0;i--)
{
ACC=ACC>>1;
ACC7=DS1302_IO;
DS1302_CLK=1;
DS1302_CLK=0;
}
return(ACC);
}
voidWrite1302(unsignedcharucAddr,unsignedcharucDa)//ucAddr:
DS1302地址,ucData:
要写的数据
{
DS1302_RST=0;
DS1302_CLK=0;
DS1302_RST=1;
DS1302InputByte(ucAddr);//地址,命令
DS1302InputByte(ucDa);//写1Byte数据
DS1302_CLK=1;
DS1302_RST=0;
}
unsignedcharRead1302(unsignedcharucAddr)//读取DS1302某地址的数据
{
unsignedcharucData;
DS1302_RST=0;
DS1302_CLK=0;
DS1302_RST=1;
DS1302InputByte(ucAddr|0x01);//地址,命令
ucData=DS1302OutputByte();//读1Byte数据
DS1302_CLK=1;
DS1302_RST=0;
return(ucData);
}
voidDS1302_SetProtect(bitflag)//是否写保护
{
if(flag)
Write1302(0x8E,0x10);
else
Write1302(0x8E,0x00);
}
voidDS1302_SetTime(unsignedcharAddress,unsignedcharValue)//设置时间函数
{
DS1302_SetProtect(0);
Write1302(Address,((Value/10)<<4|(Value%10)));
}
voidDS1302_GetTime(SYSTEMTIME*Time)
{
unsignedcharReadValue;
ReadValue=Read1302(DS1302_SECOND);
Time->Second=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);
ReadValue=Read1302(DS1302_MINUTE);
Time->Minute=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);
ReadValue=Read1302(DS1302_HOUR);
Time->Hour=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);
ReadValue=Read1302(DS1302_DAY);
Time->Day=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);
ReadValue=Read1302(DS1302_WEEK);
Time->Week=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);
ReadValue=Read1302(DS1302_MONTH);
Time->Month=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);
ReadValue=Read1302(DS1302_YEAR);
Time->Year=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);
}
voidYearToStr(SYSTEMTIME*Time,unsignedcharx)
{
Time->YearString[0]=x/10+'0';
Time->YearString[1]=x%10+'0';
Time->YearString[2]=Time->Year/10+'0';
Time->YearString[3]=Time->Year%10+'0';
Time->YearString[4]='\0';
}
voidDateToStr(SYSTEMTIME*Time)
{
Time->DateString[0]='-';
Time->DateString[1]=Time->Month/10+'0';
Time->DateString[2]=Time->Month%10+'0';
Time->DateString[3]='-';
Time->DateString[4]=Time->Day/10+'0';
Time->DateString[5]=Time->Day%10+'0';
Time->DateString[6]='\0';
}
voidTimeToStr(SYSTEMTIME*Time)
{
Time->TimeString[0]=Time->Hour/10+'0';
Time->TimeString[1]=Time->Hour%10+'0';
Time->TimeString[2]=':
';
Time->TimeString[3]=Time->Minute/10+'0';
Time->TimeString[4]=Time->Minute%10+'0';
Time->TimeString[5]=':
';
Time->TimeString[6]=Time->Second/10+'0';
Time->TimeString[7]=Time->Second%10+'0';
Time->DateString[8]='\0';
}
voidInitial_DS1302(void)
{
unsignedcharSecond=Read1302(DS1302_SECOND);
if(Second&0x80)
DS1302_SetTime(DS1302_SECOND,0);
}
voidBurstWrite1302(unsignedchar*pWClock)//往DS1302写入时钟数据(多字节方式)
{
unsignedchari;
Write1302(0x8e,0x00);//控制命令,WP=0,写操作?
DS1302_RST=0;
DS1302_CLK=0;
DS1302_RST=1;
DS1302InputByte(0xbe);//0xbe:
时钟多字节写命令
for(i=8;i>0;i--)//8Byte=7Byte时钟数据+1Byte控制
{
DS1302InputByte(*pWClock);//写1Byte数据
pWClock++;
}
DS1302_CLK=1;
DS1302_RST=0;
}
voidBurstRead1302(unsignedchar*pRClock)//读取DS1302时钟数据(时钟多字节方式)
{
unsignedchari;
DS1302_RST=0;
DS1302_CLK=0;
DS1302_RST=1;
DS1302InputByte(0xbf);//0xbf:
时钟多字节读命令
for(i=8;i>0;i--)
{
*pRClock=DS1302OutputByte();//读1Byte数据
pRClock++;
}
DS1302_CLK=1;
DS1302_RST=0;
}
voidDS1302_TimeStop(bitflag)//是否将时钟停止
{
unsignedcharData;
Data=Read1302(DS1302_SECOND);
DS1302_SetProtect(0);
if(flag)
Write1302(DS1302_SECOND,Data|0x80);
else
Write1302(DS1302_SECOND,Data&0x7F);
}
#endif
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 基于AT89S51D单片机的多功能电子万年历设计 基于 AT89S51D 单片机 多功能 电子 万年历 设计