基于单片机数字式时钟的设计单片机设计报告论文毕设论文.docx
《基于单片机数字式时钟的设计单片机设计报告论文毕设论文.docx》由会员分享,可在线阅读,更多相关《基于单片机数字式时钟的设计单片机设计报告论文毕设论文.docx(86页珍藏版)》请在冰豆网上搜索。
基于单片机数字式时钟的设计单片机设计报告论文毕设论文
1系统的总体设计
1.1仿真电路设计
以AT89C52单片机为核心,DS1302实时时钟芯片,设计数字式电子钟。
人机接口包括按键、显示器、闹钟指示灯和蜂鸣器等,显示器显示时间,按键可以调节时间,并可控制电子钟的启停、闹钟设置。
蜂鸣器作半点和整点报时闹铃,半点和整点报时闹铃,时间延时10秒,自定义闹铃,时间延时30秒。
显示器用LCD。
图1.1-1仿真电路
1.1.1仿真电路中各模块的分析
1.1.1.1DS1302实时时钟芯片
DS1302是由美国DALLAS公司推出的具有涓细电流充电能力的低功耗实时时钟芯片。
DS1302的在实时显示时间中的应用。
它可以对年、月、日、周、时、分、秒进行计时,且具有闰年补偿等多种功能。
图1.1.1.1-1DS1302仿真电路
1.1.1.2LCD1602工业字符型液晶
工业字符型液晶,能够同时显示16x02即32个字符。
(16列2行。
它是一种专门用来显示字母、数字、符号等的点阵型液晶模块。
它由若干个5X7或者5X11等点阵字符位组成,每个点阵字符位都可以显示一个字符,每位之间有一个点距的间隔,每行之间也有间隔,起到了字符间距和行间距的作用,正因为如此所以它不能很好地显示图形(用自定义CGRAM,显示效果也不好)。
图1.1.1.2-1Lcd1602仿真电路
1.1.1.3AT89C52CMOS8位单片机
AT89C52是一个低电压,高性能CMOS8位单片机,片内含8kbytes的可反复擦写的Flash只读程序存储器和256bytes的随机存取数据存储器(RAM),器件采用ATMEL公司的高密度、非易失性存储技术生产,兼容标准MCS-51指令系统,片内置通用8位中央处理器和Flash存储单元,AT89C52单片机在电子行业中有着广泛的应用。
图1.1.1.3-1AT89C52引脚图
1.1.1.474HC573八进制3态非反转透明锁存器
74HC573包含八进制3态非反转透明锁存器。
图1.1.1.4-174HC573引脚图
1.1.1.574HC00四与非门
74HC00是一款高速CMOS器件,74HC00引脚兼容低功耗肖特基TTL(LSTTL)系列。
74HC00遵循JEDEC标准no.7A。
74HC00实现了2输入与非门功能。
图1.1.1.5-174HC00引脚图
图1.1.1.5-274HC00实验电路图
1.1.1.6蜂鸣器
输出脉冲到蜂鸣器,蜂鸣器就会响。
实验中P3.0口接蜂鸣器,给予特定脉冲可演奏《两只老虎》的音乐。
图1.1.1.6-2蜂鸣器
1.1.1.7Led灯
输出1到Led灯,Led灯就会亮。
实验中P3.1口接Led灯,交替输出1/0到Led灯,实现Led灯的闪烁。
图1.1.1.7-2Led灯
1.1.1.8按键
共有8个按键,功能如下:
>>:
选定下一个数值
+:
光标所在值增加
-:
光标所在值减少
延时:
5分钟后蜂鸣器响
定时:
按下后开始设定定时时间
设置:
按下后开始设定时间
暂停:
时钟停止
确定:
定时/设置的确定
图1.1.1.8-1键盘
1.2系统流程图分析
系统流程图分析
图1.2-1系统流程图
2系统的软件设计
2.1软件各模块分析
2.1.1时钟设置模块
时钟设置分析
2.1.2闹铃模块
时钟设置分析
2.1.3显示模块
显示分析
2.2调试结果分析
在电子时钟设计中程序比较长,遇到了各种各样的问题。
因此修改程序的时间很长,有语法错误,也有仿真时功能无法实现的问题,在此不能一一说明,只能对个别问题加以阐述。
比如开始时无法对DS1302,写入的值是错误的。
将写入的字符值改为数字后,问题解决了。
虽然现在回过头来发现这个问题很简单,但当时是百思不得其解。
我从中学到:
任何事情都会有出错的可能,有些时候人的思路中的一些错误是自己难以发现的,在工作和生活中要多对自己的想法提出质疑。
不光是这种明显的问题很多,有些细微的问题也一样出现了,但解决起来并不容易。
在最后的硬件实现阶段发现蜂鸣器不响。
虽然蜂鸣器接地,但是给蜂鸣器高电平也无法驱动蜂鸣器。
最后老师说要给蜂鸣器脉冲才能驱动蜂鸣器。
问题得以解决。
程序已基本实现要求的如下功能:
基本任务:
以AT89C52单片机为核心,设计数字式电子钟。
人机接口包括按键、显示器、闹钟指示灯和蜂鸣器等,显示器显示时间,按键可以调节时间,并可控制电子钟的启停、闹钟设置。
蜂鸣器作半点和整点报时闹铃,闹铃时间延时30秒。
显示器可以用数码管或LCD。
扩展任务
增加:
对日期的预设功能,通过按键,切换日期显示或时间显示。
其他任务:
增加闹钟种类:
每日指定时刻闹铃、延时闹铃,可以按任意键,停止闹铃。
2.3体会与心得
通过本次课程设计,我对基于单片机数字式时钟的设计有了深入的研究。
首先,我对课题进行了分析,分析了任务要求并理出了简单的设计思路。
电子钟最关键的就是对89C52芯片、DS1302。
接着,我就接着我的设计思路,开始编写程序,调试程序。
想法永远是很美好的,到自己开始写程序时,我又开始迷茫了,因为单片机课程是上学期学习的,很多知识点已经忘记了,我又进行了重新的学习。
后来我找到了一段相似的程序,然后进行了改编。
最后我的程序顺利的调试出来了。
通过这次的单片机大实验,使我加深了对单片机的认识,并且熟悉了单片机系统的设计流程,收获丰硕。
功能上基本达标:
时钟的显示,调时功能。
时钟显示功能,精确度完全可以满足日常生活显示时间的需要;调时功能,方便快捷,定时,整点报时,任意键停止闹铃,暂停时钟等。
随着现在互联网的越来越发达。
网络在本次设计中起到了很大作用,很多芯片资料,传统的纸质图书里是没有的。
如何在浩如烟海的网络中提取我们需要的知识也是我必须要提高的,网络作为一个平台,由于大家的无私奉献,才使得它丰富多彩,包罗万象。
但从这么多的资料中找到我想要的却不是那么容易,以后得着重加强这方面的能力。
从这次的设计中,我真正的体会到,什么叫书到用时方恨少,还有就是理论联系实践的重要性,如何把我们所学的理论知识运用到实际生活当中,这是最难的,也是我最缺的。
实践出真知,光有书本上的知识是远远不够的,我明白了,作为一个理工科学生,我必须多动手多实践。
2.4附录
2.4.1附录1参考文献
[1]单片机原理与应用系统设计---基于C51的Proteus仿真实验指导书
[2]教科书
[3]LCD工作原理及其应用方面的资料
[4]
[5]潘永雄.新编单片机原理与应用.第2版
[6]何宏森.多功能智能电子钟的设计.兵工自动化,2005
2.4.2附录2源代码
//main.c
/**
*基于单片机数字式时钟的设计
*尹永贤
*2014年11月17日--2014年11月28日
*yinyongxian@
*/
/**********引用库函数***********/
#include/*specialfunctionregisterdeclarations*/
#include/*prototypedeclarationsforI/Ofunctions*/
#include
#include
#include
#include
/*******************************/
/**********定义数据类型的简写形式***********/
#definebyteunsignedchar
#defineucharunsignedchar
#definewordunsignedint
#defineuintunsignedint
#defineulongunsignedlong
#defineBYTEunsignedchar
#defineWORDunsignedint
#defineTRUE1
#defineFALSE0
/*****************************************/
voidtime(unsignedintucMs);//延时单位:
ms
/**********ds1302.c文件中函数与变量的声明***********/
externvoidds1302_initial();
externvoidDs1302ReadAll();
externvoidDs1302DataConver();
externvoidDs1302WriteAll();
externcharDs1302Reg[];//ds1302内部日期寄存器(00-06)
externcharDate[];//时钟数据转换为字符存储
externcharDateTime[];
/**************************************************/
ucharxdataLcd1602CmdPort_at_0x8000;//E=1RS=0RW=0
ucharxdataLcd1602StatusPort_at_0x8001;//E=1->0RS=0RW=1
ucharxdataLcd1602WdataPort_at_0x8002;//E=1RS=1RW=0
ucharxdataLcd1602RdataPort_at_0x8003;//E=1->0RS=1RW=1
/**********设定闹钟保存所设定的时间***********/
charyear[2]={0},month[2]={0},day[2]={0},hour[2]={0},minute[2]={0},second[2]={0},week=1;
/**********设定时间保存所设定的时间***********/
charyearT[2]={0},monthT[2]={0},dayT[2]={0},hourT[2]={0},minuteT[2]={0},secondT[2]={0},weekT=1;
/****************************根据SetTime的值设定相应参数***********************************/
/**********0:
设置年1:
设置月2:
设置日3:
设置时4:
设置分5:
设置秒6:
设置星期***********/
charSetTime=0;
chardelayUp=-1;//为5时变为延时到
charstartDelay=0;//延时开始
#defineBUSY0x80//忙判别位
codeucharexampl[]="-DS1302/LCD1602-calendarclock";//首先显示
sbitBuzzer=P3^0;//蜂鸣器的接口
sbitLed=P3^1;//Led灯的接口
//Lcd1602驱动函数
voidLcdWriteData(chardataW);
voidLcdWriteCommand(ucharCMD,ucharAttribC);
voidLcdReset(void);
voidDisplay(uchardd);
voidDispOneChar(ucharx,uchary,ucharWdata);
voidPutstr(ucharx,uchary,ucharcode*ptr);
voidLocateXY(charposx,charposy);//显示光标定位
voiddisplayTTV(void);//显示时间
voidClock(void);//闹钟
voidyanzou(uchari,uintpai);//演奏定时音乐
voidpause(void);//暂停
voidsetled(void);//设置Led
charanyKeyDown(void);//任意键按下返回真
voidsetNowTime(void);//设置时间
voidsetClock(void);//设置闹钟
voidintegralPoint(void);//整点或半点报时
voiddelay5Min(void);//延时5分钟
/****************主程序*****************/
voidmain(void)
{
LcdReset();//初始化
Ds1302DataConver();
Putstr(0,0,exampl);//显示一个预定字符串exampl
time(2000);//保持2秒显示内容
Putstr(0,0,"");//清屏
Led=0;//灭灯//初始化后灯处于灭的状态
ds1302_initial();//设定2014年1月1日0时0分0秒星期三
while
(1)//程序初始化后开始循环运行
{
time(300);//防止出现光标移动
displayTTV();//显示时间
integralPoint();//整点或半点报时
delay5Min();//延时5分钟
Clock();//定时时间到程序
pause();//按下暂停键,停止时钟
setNowTime();//按下设置键,设置时钟
setClock();//按下定时键,设置闹钟
}
}
/***************设置时间*****************/
voidsetNowTime(void)
{
//-------------设置时间开始.----------
if(P1==0xDF){//按下设置键
while(P1==0xDF){;}
Putstr(0,0,"");//清屏
//获得当前时间值
yearT[1]=Date[12];yearT[0]=Date[11];
monthT[1]=Date[6];monthT[0]=Date[7];
dayT[1]=Date[8];dayT[0]=Date[9];
hourT[1]=Date[0];hourT[0]=Date[1];
minuteT[1]=Date[2];minuteT[0]=Date[3];
secondT[1]=Date[4];secondT[0]=Date[5];
weekT=Ds1302Reg[5];
while(P1!
=0x7F){//按确定键设定完成
time(200);//
//显示格式为:
**:
**:
**(表示时分秒)
if(P1==0xFE)//按右移
{
while(P1==0xFE){;}
if(SetTime==6)
{
SetTime=0;
}
else
{
SetTime=SetTime+1;
}
}
DispOneChar(0,0,'2');//显示设定的年份
DispOneChar(1,0,'0');
DispOneChar(2,0,yearT[1]);
DispOneChar(3,0,yearT[0]);
DispOneChar(4,0,'-');
DispOneChar(5,0,monthT[1]);//显示设定的月份
DispOneChar(6,0,monthT[0]);
DispOneChar(7,0,'-');
DispOneChar(8,0,dayT[1]);//显示设定的日期
DispOneChar(9,0,dayT[0]);
Putstr(11,0,"Time...");//显示一个预定字符串exampl
DispOneChar(0,1,hourT[1]);//显示设定的时
DispOneChar(1,1,hourT[0]);
DispOneChar(2,1,':
');
DispOneChar(3,1,minuteT[1]);//显示设定的分
DispOneChar(4,1,minuteT[0]);
DispOneChar(5,1,':
');
DispOneChar(6,1,secondT[1]);//显示设定的秒
DispOneChar(7,1,secondT[0]);
//switch(Ds1302Reg[5]){
switch(weekT){
case1:
Putstr(9,1,"Sun");//周日
break;
case2:
Putstr(9,1,"Mon");//周一
break;
case3:
Putstr(9,1,"Tue");//周二
break;
case4:
Putstr(9,1,"Wed");//周三
break;
case5:
Putstr(9,1,"Thu");//周四
break;
case6:
Putstr(9,1,"Fri");//周五
break;
case7:
Putstr(9,1,"Sat");//周六
break;
default:
Putstr(9,1,"Err");//错误
break;
}
//根据SetTime的值修改相应的值:
SetTime=00:
设置年1:
设置月2:
设置日3:
设置时4:
设置分5:
设置秒6:
设置星期
switch(SetTime){
case0:
LocateXY(0,0);//定位显示地址
if(P1==0xFD)//年+
{
while(P1==0xFD){;}
if(yearT[0]=='9')
{
yearT[0]='0';
if(yearT[1]=='9')
{
yearT[1]='0';
}
else
{
yearT[1]=yearT[1]+1;
}
}
else
{
yearT[0]=yearT[0]+1;
}
}
elseif(P1==0xFB)//年-
{
while(P1==0xFB){;}
if(yearT[0]=='0')
{
if(yearT[1]=='0')
{
yearT[1]='0';
yearT[0]='0';
}
else
{
yearT[1]=yearT[1]-1;
yearT[0]='9';
}
}
else
{
yearT[0]=yearT[0]-1;
}
}
break;
case1:
LocateXY(5,0);//定位显示地址
if(P1==0xFD)//月+
{
while(P1==0xFD){;}
if(monthT[0]=='2')
{
if(monthT[1]=='1')
{
monthT[1]='0';
monthT[0]='1';
}
else
{
monthT[0]=monthT[0]+1;
}
}
elseif(monthT[0]=='9')
{
monthT[1]='1';
monthT[0]='0';
}
else
{
monthT[0]=monthT[0]+1;
}
}
elseif(P1==0xFB)//月-
{
while(P1==0xFB){;}
if(monthT[0]=='1')
{
if(monthT[1]=='1')
{
monthT[0]='0';
}
else
{
monthT[1]='1';
monthT[0]='2';
}
}
elseif(monthT[0]=='0')
{
monthT[1]='0';
monthT[0]='9';
}
else
{
monthT[0]=monthT[0]-1;
}
}
break;
case2:
LocateXY(8,0);//定位显示地址
if(P1==0xFD)//日+
{
while(P1==0xFD){;}
if(dayT[0]=='1')
{
if(dayT[1]=='3'