基于单片机的可调时钟

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

《综合电子设计报告》
---“基于单片机的可调时钟”
专业电子信息科学与技术
班级电信(2)班
学生姓名
指导教师
提交日期 2011年 6 月 24日
目录
目录 (1)
引言 (1)
第1章时间计时原理 (2)
1.1时钟计时的方案选择 (2)
1.2时钟显示的方案选择 (3)
第2章系统的硬件设计 (4)
2.1 系统硬件的整体设计 (4)
2.2 主控制模块的方案选择与设计 (4)
2.2.1单片机STC89C52简介 (4)
2.2.2主控制模块电路 (5)
2.3时钟模块的方案选择与设计 (5)
2.3.1DS12887时钟芯片简介 (6)
2.3.2时钟模块电路 (6)
2.4按键电路的设计 (7)
2.5显示模块的方案设计 (7)
第3章系统软件设计 (8)
3.1系统主程序及流程图 (8)
3.2 DS12887时钟芯片的读操作流程图 (8)
3.3液晶模块的写操作流程图 (9)
第4章实验与调试 (9)
4.1硬件测试 (9)
结论 (12)
附录A:电路原理图 (13)
引言
1.课题的背景与意义
单片机应用的重要意义在于它从根本上改变了传统的控制系统设计思想和设计方法。

从前必须由模拟电路或数字电路实现的大部分功能,现在已能用单片机通过软件方法来实现了。

这种软件代替硬件的控制技术也称为微控制技术,是传统控制技术的一次革命。

单片机模块中最常见的是数字钟,数字钟是一种用数字电路技术实现时、分、秒计时的装置,与机械式时钟相比具有更高的准确性和直观性,且无机械装置,具有更更长的使用寿命,因此得到了广泛的使用。

数字钟是采用数字电路实现对.时,分,秒.数字显示的计时装置.因此本电子设计所做的数字时钟采用了以单片机为核心,结合相关的外围元器件例如液晶显示、按键电路、复位电路,再配以相应的软件,达到制作简易数字钟的目的,能实现实时时钟显示的功能,能进行年、月、日、时、分、秒的显示。

其硬件部分难点在于元器件的选择、布局及焊接。

2.课题任务与设计思路
按照课题的要求,初步确定设计系统由主控模块、时钟模块、显示模块、键扫描电路模块共4个模块组成。

设计采STC89系列单片机,以C语言为程序设计的基础,设计出用液晶显示年、月、日、周、时、分、秒的时钟。

第1章时间计时原理
单片机的接口信号是数字信号。

要想用单片机获取时间这类非电信号的信息,必须使用时间芯片,将时间信息转换为电流或电压输出。

如果转换后的电流或电压输出是模拟信号,还必须进行A/D转换,以满足单片机接口的需要。

如果是数字信号就可以直接送往单片机进行数据处理。

1.1时钟计时的方案选择
方案一:比较传统的基于单片机的时钟设计可以采用单片机内部的晶振来产生脉冲,然后通过单片机内部的计时器经过分频产生秒脉冲,然后通过软件编程来实现时钟的显示,这种设计方案的优点是外围器件少,电路简单清晰,电路焊接容易,出问题的故障几率小。

但是这种方案需由软件编程来实现秒脉冲的产生,编程相对来说比较复杂,而且也不利于排故。

另外由单片机内部时钟产生的秒脉冲由于受到温漂的影响和程序执行时的延时的影响,而使的计时会产生不定的误差,即使设计时间误差补偿程序也很难实现提供准确时间的功能。

另外,这种电路设计方案的另外一个设计要求就是晶振的选择要求晶振的振荡频率必须通过分频得到秒脉冲。

这种设计还有一个非常大的缺点就是如果单片机断电,时间计时就停止,再次上电时又从初始设定重新计时,这样就需要在每次上电都调整时间,比较麻烦。

方案二:在传统的基于单片机的数字时钟设计的基础上经过一些改进,引入12887时间芯片,将电路的控制部分和计时部分分开,电路的控制部分为单片机,计时部分为12887时间芯片。

12887芯片是独立计时,并且具有掉电保护功能,内部自带锂电池,能够在断电的情况下继续计时,主电路恢复供电之后能够不必调整时间,为时钟的日常操作省去了很大的麻烦,而且这种设计更节能,在需要观察时间的时候比如白天就可以给主电路通电。

而在夜晚不需要观察时钟的时候就可以给主电路断电,这样可以节约大量能量。

时间芯片12887采用了内部集成晶振的电路,并且具有内部温漂补偿电路设计。

能够准确计时,提供精确的时间,这样就简化了电路的器件选择,另外也使程序的设计更加简洁。

在硬件设计方面,由于只增加了一个12887时间芯片,因此并不是特别复杂,而且这种独立计时的设计使得产品排故更加方便。

比较上述两种方案可以看出,第二种方案计时更加准确而且电路硬件设计先对来说并不复杂,软件设计更加简洁,因此采用第二种方案。

1.2时钟显示的方案选择
方案一:时钟的显示可以用多位七段LED数码管显示,七段 LED数码管显示耗能多,而且显示位数有限,每增加一位都要在程序设计和硬件设计方面增加很多的工作量,不利于电路的扩展,而且无法显示年、月、日、星期这些汉字,使得显示不够直观,灵活。

但是这种设计方案在显示位数比较少时性价比比较高,价格便宜,方案二:采用点阵式数码管显示。

点阵式数码管是由八行八列的发光二极管组成,对于显示文字比较适合,而在本课题设计中的显示数字较多字符较少,而且此种方案耗能多,不符合现代的节能理念,所以不用此种作为显示。

方案三:采用LCD液晶显示器显示。

而LCD液晶显示则耗能少,能够显示年、月、日、星期等汉字,在显示方面更加灵活,而且改变显示时只要改变软件设计就可以,不用改变硬件电路的设计,易于电路的功能扩展。

电路的软件设计也很简单。

另外,这种设计硬件更加简洁。

采用LCD液晶显示方案的缺点是在显示位数比较少时,价格略显昂贵。

比较上述两种方案可以看出方案三耗能少,显示灵活,易于电路扩展而且不管是软件设计还是硬件设计都比较简单,因此采用第三种设计方案。

综上所述,本设计采用独立计时,引入时钟日历芯片12887的设计方案。

第2章系统的硬件设计
根据实时时钟的功能要求,基于单片机的设计方案要运用集成时钟芯片,实现实时数据记录,实现数据与出现该数据的时间同时记录。

实时时钟的要求:基本要求
a)具有年、月、日、星期、时、分、秒等功能;
a)具备年、月、日、星期、时、分、秒校准功能;
2.1 系统硬件的整体设计
主控芯片使用51系列STC89C52单片机,时钟芯片使用美国DALLAS公司推出的一种高性能、低功耗、带RAM和内置电池的实时时钟DS12887。

采用DS12887作为主要计时芯片,可以做到计时准确。

更重要的是,DS12887可以在外部电源断电的情况下继续计时,在没有外部供电的情况下,DS12887可以连续计时10年以上。

系统由主控制器STC89C52、时钟芯片DS12887、LCD液晶显示电路、键扫描电路模块电路组成。

2.2 主控制模块的方案选择与设计
系统的设计可采用数字电路实现,也可以采用单片机来完成。

若用数字电路完成,所设计的电路相当复杂,大概需要十几片数字集成块,其功能也主要依赖数字电路的各功能模块的组合来实现。

若用单片机来设计完成,由于其功能的实现主要通过软件编程来实现的,那么就降低了硬件电路的复杂性,所以在该设计中采用单片机作为主控模块。

另外这个课题设计的软件程序比较简单,不需要很强大的单片机,只要用简单的单片机就可以满足要求,因此我选用了性价比比较高的低端STC89C52单片机。

2.2.1单片机STC89C52简介
STC89C52 是低电压,高性能 CMOS 8 位单片机,片内含 8k bytes 的可反复擦写的Flash只读程序存储器和256 bytes 的随机存取数据存储器(RAM),器件采用高密度、非易失性存储技术生产,与标准 MCS-51 指令系统及8052产品引脚兼容,片内置通用8位中央处理器(CPU)和 Flash 存储单元,功能强大 STC89C52 单片机适合于许多较为复杂控制应用场合。

STC89C52单片机为40引脚双列直插芯片,有四个I/O口P0、P1、P2、P3,每一条I/O线都能独立地作输出或输入。

STC89C52 PDIP
管脚封装,如图2-2所示。

图2-2 STC89C52 PDIP管脚封装
2.2.2主控制模块电路
单片机STC89C52的P0口作为输出口。

P1与DS12887的AD相连,进行时间数据
的采集;P3.4DS12887的17脚DS相连, P3.7脚与DS12887的13脚CS相连;P3.6
脚与DS12887的14脚AS相连。

单片机的第18引脚和19引脚接时钟电路,XTAL1接
外部晶振和微调电容的一端,XTAL2接外部晶振和微调电容的另一端。

对外接电容的
值虽然没有严格的要求,但电容的大小会影响震荡器频率的高低、震荡器的稳定性、
起振的快速性和温度的稳定性。

因此,此系统电路的晶体振荡器的值为11.0592MHz,
电容应尽可能的选择陶瓷电容,电容值约为30pF。

第9引脚为复位输入端,接上电
容,电阻后构成上电复位电路。

20引脚为接地端,40引脚为电源端。

/EA端(31引
脚)接+5V电压。

2.3时钟模块的方案选择与设计
方案一:美国Dallas公司生产的串行时钟DS1302芯片是一种高性能的时钟芯片,可自动地对秒、分、时、日、周、月、年进行计数,而且工作电压2.5V~5.5V范围内,2.5V时耗电小于300nA,可方便地与单片机接口,从而解决并行实时芯片使得电路结构复杂的问题,但是DS1302时钟芯片没有内置电池,在电路掉电的情况下不能继续计时,在电路恢复供电之后需要校正时间比较麻烦。

方案二:美国Dallas公司生产的串行时钟DS12887芯片也是一种高性能的时钟
芯片,可自动地对秒、分、时、日、周、月、年进行计数,可以方便地与单片机接口,
从而解决并行实时芯片使得电路结构复杂的问题,而且DS12887时钟芯片没有内置电池,在电路掉电的情况下能继续计时,在电路恢复供电之后不需要校正时间因此选用DS12887芯片。

2.3.1 DS12887时钟芯片简介
DS12887是美国DALLAS公司生产的时钟日历芯片,具有24个引脚。

DS12887和MC146818B及DS1287管脚兼容。

内部自带锂电池,在没有外部电源的情况下可工作十年。

它有内部集成晶振。

可计算到2100年前的时、分、秒、星期、日、月、年七种日历信息,并带闰年补偿。

用2进制或BCD码代表日历或闹钟信息。

可选用夏令时模式。

可以选用MOTOROLA和INTEL两种总线模式。

它采用数据地址总线复用模式。

内键128字节RAM,这128字节RAM中前14字节是时钟控制寄存器。

其余为通用RAM。

它可以输出可编程方波。

它可以产生3种可编程中断;一,时间中断,可产生每秒一次直到每天一次中断;二,周期性中断,可产生122ms到500ms周期性中断;三,时间更新结束中断。

DS12887有24个引脚,其引脚如图2-5所示。

图2-5DS12887引脚图
2.3.2时钟模块电路
时钟模块DS12887的AD口与单片机的P0口相连,进行时间、日历数据输出。

其它各功能端口的连接在主控电路中已有描述,不在赘述。

另外DS12887的12脚与电源地相连,24脚与电源相连。

总线选择端口MOT端与电源地相连。

电路图如图2-8所示。

图2-8 时钟模块电路
2.4按键电路的设计
根据设计要求,系统的按键电路用4个按键和一个拨码开关就可以进行对时间的调整,按键就采用最简单的点动式按钮,由单片机的I/O进行扫描,来实现扫描按键功能。

其中,时间调整按钮与单片机STC89C52的P3.5相连,其功能是当按下此键时,开始调整年、月、日、星期、时、分、秒,没按一次就改变一个相应的要改变的位;闹钟调整按钮与单片机STC89C52的P2.5相连,其功能是当按下此键时开始进行闹钟调整,并且每按一次就改变一次要调整的位;加法按钮与单片机STC89C52的P2.6连,其功能是每按一次此键就将相应的要改变的位的数值加一;减法按钮与单片机STC89C52的P2.7连,其功能是每按下一次此键就将要改变的位的数值减一。

2.5显示模块的方案设计
此设计方案采用了LCD液晶显示,由于此设计不需要显示太多内容,因此选用了1602液晶显示器。

图2-10 显示模块
第3章系统软件设计
软件是系统的主要组成部分,也是整个调试的重点和难点工作。

依据课题设计的要求,采用C语言进行软件编程,用模块化程序设计思想,将软件划分成若干模块单元;包括:DS12887时钟模块、1602液晶显示模块,键盘扫描子程序。

3.1系统主程序及流程图
主程序的主要功能是显示日期时间信息。

在主程序中,系统上电自动复位以后首先进行系统的液晶显示、时钟芯片DS12887初始化,然后读写日期、时间等信息,待数据读写结束后显示时钟。

主程序流程如图3-1所示。

开始
清屏
初始化
读12887子程序
显示子程序
扫描键盘
No
判断是否
有按键
Yes
显示时间调整屏
键值判断
调整时间
图3-1 主程序流程图
主程序说明,当主程序运行时,先将液晶显示器清屏,然后将单片机和时钟日历芯片DS12887初始化。

3.2 DS12887时钟芯片的读操作流程图
首先对时钟芯片DS12887初始化,经过对状态寄存器判断之后,对DS12887进行读操作,读操作时利用时钟日历地址相邻的特点,直接使地址增加,随后判断数据是否读完了。

若读完了,则返回主程序;若没有读完,则继续增加地址,直到读数据完成为止。

如图3-2所示。

开始初始化
判断12887是否可读
读12887返回
Yes
等待
No
图3-2 DS12887时钟芯片的读操作流程图
3.3液晶模块的写操作流程图
本设计用的液晶是1602液晶模块,第一行显示年,月,日,星期,第二行显示时,分,秒。

开始清屏
发送要显示字符代码
显示设置
设置显示字符的首地址显示返回
图3-3 时间显示,屏一显示流程图
第4章 实验与调试
验证理论的最好的方法是实践,因此本设计通过实验,用实物的调试来验证之上设计的可行性。

虽然现在很多设计采用仿真来模拟结果,但是放着和实际还是有一定差距的,而且有些实际问题是仿真所不能显示的,为了更好的验证本设计方案,因此本设计采用实物来验证。

4.1硬件测试
本设计的硬件验证电路完全由按照上述理论进行焊接。

其电路焊接如图4-1所
示。

图4-1 焊接面实物图
硬件焊接好后需要测试是否都连接好了,本设计采用的测试方法是用万用表来测量,用万用表的两个表笔分别接连线的两端,测试是否电阻为零,如果电阻为零说明连接正确,如果有电阻说明没有连接好。

由于实验板上的有些焊点离的比较近,在焊接时可能由于不小心将焊锡滴落在两个焊点之间造成短路,短路是对电路板最大的危害之一,因此要细心的检查每两个相邻的焊点之间是否有短路发生。

图 4-2 实物图
结论
1、本文的主要工作和成果
系统采用了以广泛使用的单片机STC89C52为核心,配合时钟芯片DS12887,并采用LCD显示电路。

主要工作和成果如下:
(1)介绍基于单片机的时钟电路的设计方法,并对基于单片机的时钟的应用进行了初步探讨。

(2)介绍了时钟芯片DS12887的基本原理、特性及使用方法。

对单片机软硬件资源和接口扩展都有了深入的学习。

(3)在系统的软件仿真调试中,运用了PROTEL等软件;学习了他们的基本操作,掌握了程序的编译过程、电路图的绘制过程。

(4)课题设计取得了较好的效果,达到了课题的基本要求。

2、课题设计中不足及其展望
本设计重点研究实现了基于单片机与时钟芯片这种模式的时钟,从原理上对单片机和时钟芯片有了深一步的认识。

但是,时钟除了能够显示基本日期时间功能外,还可以显示、设置闹钟并可在工业测量控制系统中起到定时、监控作用,以及对某些影像数据的实时记录功能等。

所以说,实时时钟在工农业的监控中,它能发挥的作用会更多更大!它的这些功能还没有完善,希望以后有机会可继续完善其相应的功能。

附录A:电路原理图
附录A:源程序
/********************************************* writer: xulin
*/
#include"reg52.h"
#define uchar unsigned char
#define uint unsigned int
#include"1602.h"
#include"ds12887.h"
sbit s1=P2^5;
sbit s2=P2^6;
sbit s3=P2^7;
uchar s1num,flag;
void keyscan();
/************main function*****************/ void main()
{
flag=1;
s1num=0;
init_ds12887();
init_1602();
// set_time();
printf();
while(1)
{
keyscan();
if(flag==1)
printf();
}
}
/******************************************************/
/*********设置时间子函数**********/
void keyscan()
{
if(s1==0)
{
delay(20);
if(s1==0)
{
s1num++;
flag=0; //进入设置时间函数后把标志位置0.让程序暂时不进入printf函数。

while(!s1);
if(s1num==1)
{
write_com(0x80+0x40+11);
write_com(0x0f); // 显示光标,光标闪烁。

}
if(s1num==2)
{
write_com(0x80+0x40+8);
}
if(s1num==3)
{
write_com(0x80+0x40+5);
}
if(s1num==4)
{
s1num=0;
write_com(0x0c);
flag=1;
}
}
}
if(s1num!=0)
{
if(s2==0)
{
delay(20);
if(s2==0)
{
while(!s2);
if(s1num==1)
{
second++;
if(second==60)
second=0;
DislpaySecondLine(11,second);
write_com(0x80+0x40+12);
write_ds(0,second); //调好时间后还必须写到ds12887里面,再显示时候就是调好的时间啦。

}
if(s1num==2)
{
minute++;
if(minute==60)
minute=0;
DislpaySecondLine(8,minute);
write_com(0x80+0x40+8);
write_ds(2,minute);
}
if(s1num==3)
{
hour++;
if(hour==24)
hour=0;
DislpaySecondLine(5,hour);
write_com(0x80+0x40+5);
write_ds(4,hour);
}
}
}
if(s3==0)
{
delay(20);
if(s3==0)
{
while(!s3);
if(s1num==1)
{
second--;
if(second==-1)
second=59;
DislpaySecondLine(11,second);
write_com(0x80+0x40+11);
write_ds(0,second);
}
if(s1num==2)
{
minute--;
if(minute==-1)
minute=59;
DislpaySecondLine(8,minute);
write_com(0x80+0x40+8);
write_ds(2,minute);
}
if(s1num==3)
{
hour--;
if(hour==-1)
hour=23;
DislpaySecondLine(5,hour);
write_com(0x80+0x40+5);
write_ds(4,hour);
}
}
}
}
}
/***********************************************************************/
sbit rs=P2^0;
sbit e=P2^1;
uchar code years[]=" 20 / : /"; uchar code time[]="time : :";
/***1ms延时子函数***/
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
/***1602液晶写指令子函数***/
void write_com(uchar com)
{
rs=0;
P0=com;
delay(5);
e=1;
delay(5);
e=0;
}
/***1602液晶写数据子函数***/
void write_data(uchar date)
{
rs=1;
P0=date;
delay(5);
e=1;
delay(5);
e=0;
}
/***1602液晶初始化函数***/
void init_1602()
{
uchar n1,n2;
e=0;
write_com(0x01); //00000001 清屏
write_com(0x38); //00111000 设置为16*2显示
write_com(0x0c); //00001110 开显示,不显示光标
write_com(0x06); //00000110 写一个字符后地址指针加1
write_com(0x80); //00001000 设置数据地址指针,从80h开始
for(n1=0;n1<13;n1++)
{
write_data(years[n1]);
}
write_com(0x80+0x40);
for(n2=0;n2<11;n2++)
{
write_data(time[n2]);
}
}
/*******DS12887位声明**********
*******MOT 引脚接GND 选择Intel时序
*******rest 接高******************/
sbit dscs=P3^7;
sbit dsas=P3^6;
sbit dsrw=P3^5;
sbit dsds=P3^4;
/****写数据子函数,先写地址,再写数据*****/
void write_ds(uchar add,uchar date)
{
dscs=0;
dsas=1;
dsds=1;
dsrw=1;
P1=add;
dsas=0;
dsrw=0;
P1=date;
dsrw=1;
dsas=1;
dscs=1;
}
/****读数据子函数*****/
uchar read_ds(uchar add)
{
uchar ds_date;
dsas=1;
dsds=1;
dsrw=1;
dscs=0;
P1=add;
dsas=0;
dsds=0;
P1=0xff;
ds_date=P1;
dsds=1;
dsas=1;
dscs=1;
return ds_date;
}
/****这个是显示子函数显示在1602第一行显示日期***/
void DisplayFirstLine(uchar add,uchar date)
{
uchar shi,ge;
shi=date/10;
ge=date%10;
write_com(0x80+add);
write_data(0x30+shi); //把读到的值加30h 再显示,因为显示是ASCLL码write_data(0x30+ge);
}
/**** 显示在1602第二行显示时间***/
void DislpaySecondLine(uchar add,uchar date)
{
uchar shi,ge;
shi=date/10;
ge=date%10;
write_com(0x80+0x40+add);
write_data(0x30+shi);
write_data(0x30+ge);
}
/***设置时间子函数*****/
void set_time()
{
write_ds(0,32);
write_ds(2,39);
write_ds(4,16);
write_ds(6,04);
write_ds(7,02);
write_ds(8,06);//month
write_ds(9,11);
}
/***对DS12887时钟芯片的初始化****/
uchar second,minute,hour,day,date,month,year;
void init_ds12887()
{
write_ds(0x0a,0x20); // 这个初始化很重要,没有时钟是不会走的。

控制寄存器A写数据。

write_ds(0x0B,0x26); // 没有会乱走。

}
/***显示位置的设置子函数***/
void printf()
{
second=read_ds(0);
minute=read_ds(2);
hour=read_ds(4);
day=read_ds(6);
date=read_ds(7);
month=read_ds(8);
year=read_ds(9);
DisplayFirstLine(4,year);
DisplayFirstLine(7,month);
DisplayFirstLine(10,date);
DisplayFirstLine(13,day);
DislpaySecondLine(5,hour);
DislpaySecondLine(8,minute);
DislpaySecondLine(11,second);
}。

相关文档
最新文档