基于单片机电子时钟设计概要.docx
《基于单片机电子时钟设计概要.docx》由会员分享,可在线阅读,更多相关《基于单片机电子时钟设计概要.docx(19页珍藏版)》请在冰豆网上搜索。
基于单片机电子时钟设计概要
基于单片机电子时钟设计
摘要
电子时钟主要是利用电子技术将时钟电子化、数字化,拥有时钟精确、体积小、界面友好、可扩展性能强等特点,被广泛应用于生活和工作当中。
另外,在生活和工农业生产中,也常常需要温度,这就需要电子时钟具有多功能性。
本设计主要为实现一款可正常显示时钟/日历功能电子时钟。
本文对当前电子钟开发手段进行了比较和分析,最终确定了采用单片机技术实现多功能电子时钟。
本设计应用STC89C52RC芯片作为核心,四位共阴LED数码管显示,使用DS1302实时时钟日历芯片完成时钟/日历的基本功能。
这种实现方法的优点是电路简单,性能可靠,实时性好,时间精确,操作简单,编程容易。
该电子时钟可以应用于一般的生活和工作中,也可通过改装,提高性能,增加新功能,从而给人们的生活和工作带来更多的方便。
关键词:
电子时钟;多功能;STC89C52RC;时钟日历芯片
1.引言
时间是人类生活必不可少的重要元素,如果没有时间的概念,社会将不会有所发展和进步。
从古代的水漏、十二天干地支,到后来的机械钟表以及当今的石英钟,都充分显现出了时间的重要,同时也代表着科技的进步。
致力于计时器的研究和充分发挥时钟的作用,将有着重要的意义。
1.1多功能电子时钟研究的背景和意义
20世纪末,电子技术获得了飞速的发展。
在其推动下,现代电子产品几乎渗透到了社会的各个领域,有力的推动和提高了社会生产力的发展与信息化程度,同时也使现代电子产品性能进一步提升,产品更新换代的节奏也越来越快。
时间对人们来说总是那么宝贵,工作的忙碌性和繁杂容易使人忘记当前的时间。
然而遇到重大事情的时候,一旦忘记时间,就会给自己或他人造成很大麻烦。
平时我们要求上班准时,约会或召开会议必然要提及时间;火车要准点到达,航班要准点起飞;工业生产中,很多环节都需要用时间来确定工序替换时刻。
所以说能随时准确的知道时间并利用时间,是我们生活和工作中必不可少的[1]。
电子钟是采用电子电路实现对时、分、秒进行数字显示的计时装置,广泛应用于个人家庭,车站,码头办公室等公共场所,成为人们日常生活中不可少的必需品。
由于数字集成电路的发展和石英晶体振荡器的广泛应用,使得数字钟的精度,远远超过老式钟表,钟表的数字化给人们生产生活带来了极大的方便,而且大大地扩展了钟表原先的报时功能。
诸如定时自动报警、0按时自动打铃、定时广播、自动起闭路灯、定时开关烘箱、通断动力设备、甚至各种定时电气的自动启用等,所有这些,都是以钟表数字化为基础的。
因此,研究数字钟及扩大其应用,有着非常现实的意义。
1.2电子时钟的功能
电子时钟主要是利用电子技术将时钟电子化、数字化,拥有时间精确、体积小、界面友好、可扩展性能强等特点,被广泛应用于生活和工作当中。
当今市场上的电子时钟品类繁多,外形小巧别致。
也有体型较大的,诸如公共场所的大型电子报时器等。
电子时钟首先是数字化了的时间显示或报时器,在此基础上,人们可以根据不同场合的要求,在时钟上加置其他功能,比如定时闹铃,万年历,环境温度、湿度检测,环境空气质量检测,USB扩展口功能等。
本设计电子时钟主要功能为:
具有时间显示和手动校对功能,24小时制。
2.基于单片机的电子时钟硬件选择分析
考虑单片机货源充足、价格低廉,可软硬件结合使用,能够较方便的实现系统的多功能性,故采用单片机作为本设计的硬件基础。
2.1主要IC芯片选择
2.1.1微处理器选择
目前在单片机系统中,应用比较广泛的微处理器芯片主要为8XC5X系列单片机。
该系列单片机均采用标准MCS-52内核,硬件资源相互兼容,品类齐全,功能完善,性能稳定,体积小,价格低廉,货源充足,调试和编程方便,所以应用极为广泛。
例如比较常用的STC89C52RC单片机,带有2KBFlash可编程、可擦除只读存储器(E2PROM)的低压、高性能8位CMOS微型计算机。
拥有15条可编程I/O引脚,2个16位定时器/计数器,6个中断源,可编程串行UART通道,并能直接驱动LED输出。
仅仅是为了完成时钟设计或者是环境温度采集设计,应用STC89C52RC单片机完全可以实现。
但是将两种功能结合在一片单片机上,就需要更多的I/O引脚,故本设计采用具有32根I/O引脚的STC89C52RC单片机。
STC89C52单片机是一款低功耗,低电压,高性能CMOS8位单片机,片内含4KB(可经受1000次擦写周期)的FLASH可编程可反复擦写的只读程序存储器(EPROM),器件采用CMOS工艺和STC公司的高密度、非易失性存储器(NURAM)技术制造,其输出引脚和指令系统都与MCS-52兼容。
片内的FLASH存储器允许在系统内可改编程序或用常规的非易失性存储器编程器来编程。
因此,STC89C52RC是一种功能强,灵活性高且价格合理的单片机,可方便的应用在各个控制领域[6]。
STC89C52RC具有以下主要性能:
1.4KB可改编程序Flash存储器;
2.全静态工作:
0——24Hz;
3.128×8字节内部RAM;
4.32个外部双向输入/输出(I/O)口;
5.6个中断优先级;2个16位可编程定时计数器;
6.可编程串行通道;
7.片内时钟振荡器。
此外,STC89C52RC是用静态逻辑来设计的,其工作频率可下降到0Hz,并提供两种可用软件来选择的省电方式——空闲方式(IdleMode)和掉电方式(PowerDownMode)。
在空闲方式中,CPU停止工作,而RAM、定时器/计数器、串行口和中断系统都继续工作。
在掉电方式中,片内振荡器停止工作,由于时钟被“冻结”,使一切功能都暂停,只保存片内RAM中的内容,直到下一次硬件复位为止。
图2.1STC89C52RC引脚说明
STC89C52RC为适应不同的产品需求,采用PDIP、TQFP、PLCC三种封装形式,本系统采用双列直插PDIP封装形式。
2.1.2DS1302简介
DS1302是美国DALLAS公司推出的一种高性能、低功耗的实时时钟日历芯片,附加31字节静态RAM,采用SPI三线接口与CPU进行同步通信,并可采用突发方式一次传送多个字节的时钟信号和RAM数据。
实时时钟可提供秒、分、时、日、星期、月和年,一个月小于31天时可以自动调整,且具有闰年补偿功能。
工作电压宽达2.5~5.5V。
采用双电源供电(主电源和备用电源),可设置备用电源充电方式,提供了对后备电源进行涓细电流充电的能力。
有主电源和备份电源双引脚,而且备份电源可由大容量电容(>1F)来替代。
需要强调的是,DS1302需要使用32.768KHz的晶振。
2.1.3DS1302引脚说明
图2.2DS1302芯片引脚图
其的引脚功能参照表2.1。
表2.1DS1302引脚功能说明
引脚号
名称
功能
1
VCC1
备份电源输入
2
X1
32.768KHz晶振输入
3
X2
32.768KHz晶振输出
4
GND
地
5
RST
控制移位寄存器/复位
6
I/O
数据输入/输出
7
SCLK
串行时钟
8
VCC2
主电源输入
2.1.474HC138译码器说明
74HC138是一款高速CMOS器件,74HC138引脚兼容低功耗肖特基TTL(LSTTL)系列。
74HC138译码器可接受3位二进制加权地址输入(A0,A1和A2),并当使能时,提供8个互斥的低有效输出(Y0至Y7)。
74HC138特有3个使能输入端:
两个低有效(E1和E2)和一个高有效(E3)。
除非E1和E2置低且E3置高,否则74HC138将保持所有输出为高。
利用这种复合使能特性,仅需4片74HC138芯片和1个反相器,即可轻松实现并行扩展,组合成为一个1-32(5线到32线)译码器。
任选一个低有效使能输入端作为数据输入,而把其余的使能输入端作为选通端,则74HC138亦可充当一个8输出多路分配器,未使用的使能输入端必须保持绑定在各自合适的高有效或低有效状态。
74HC138与74HC238逻辑功能一致,只不过74HC138为反相输出。
图2.374HC138引脚图
图2.474HC138译码表
2.1.574HC573说明
74HC573包含八进制3态非反转透明锁存器,是一种高性能硅门CMOS器件。
SL74HC573跟LS/AL573的管脚一样。
器件的输入是和标准CMOS输出兼容的,加上拉电阻他们能和LS/ALSTTL输出兼容。
输入是和标准CMOS输出兼容的;加上拉电阻,他们能和LS/ALSTTL输出兼容。
当锁存使能端LE为高时,这些器件的锁存对于数据是透明的(也就是说输出同步)。
当锁存使能变低时,符合建立时间和保持时间的数据会被锁存。
74HC573主要参数:
1.三态总线驱动输出
2.置数全并行存取
3.缓冲控制输入
4.使能输入有改善抗扰度的滞后作用
原理说明:
M54HC563/74HC563/M54HC573/74HC573的八个锁存器都是透明的D型锁存器,当使能(G)为高时,Q输出将随数据(D)输入而变。
当使能为低时,输出将锁存在已建立的数据电平上。
输出控制不影响锁存器的内部工作,即老数据可以保持,甚至当输出被关闭时,
新的数据也可以置入。
这种电路可以驱动大电容或低阻抗负载,可以直接与系统总线接口并驱动总线,而不需要外接口。
特别适用于缓冲寄存器,I/O通道,双向总线驱动器和工作寄存器。
2.1.5.1数据锁存
当输入的数据消失时,在芯片的输出端,数据仍然保持;这个概念在并行数据扩展中经常使用到。
图2.574HC573引脚图逻辑符号图2.674HC573国际电工委员会逻辑符号
2.2电子时钟硬件电路设计
电子闹钟至少要包括秒信号发生器、时间显示电路、按键电路、供电电源、闹铃指示电路等几部分。
硬件电路框图参照图2.3。
该系统使用STC89C52单片机作为核心,通过读取时钟日历芯片DS1302数据,完成此电子时钟的主要功能——时钟。
使用比较通用的8段共阴数码管,做7位显示,分别显示时、分、秒。
键盘是为了完成时钟/日历的校对和日历/温度的显示功能。
由于此电子时钟要求具有闹铃功能,所以设计有闹铃电路,进行声音响铃。
整个电路使用了两种电源,+5V电源将为整个电路供电。
而+3V电源仅作为DS1302的备用电源。
当+5V电源被切断后,DS1302启用+3V电源,可以保持DS1302继续工作。
当+5V电源恢复供电,LED依旧显示当前时间,而不会因为断电使系统复位到初始化时间,避免了重新校时的麻烦。
2.2.1时钟电路设计
系统时钟应用了实时时钟日历芯片DS1302,其连接如图2.4。
该硬件电路设计简单,抗干扰能力强。
如图,stc89c52rc单片机P3.5直接接DS1302的RST端,上电后,STC89C52RC的P3.5脚自动输出高电平。
P3.6作为串行时钟接口,P3.4作为时钟数据的I/O。
DS1302采用双电源供电,平时由+5V电源供电,当+5V掉电之后,由图中BT1(+3V备用电池)供电。
特别需要注意X1和X2两端连接的晶振Y1,该晶振频率为32.768KHz。
图2.7系统时钟电
3.Protel软件画原理图
图3.1电路连接设计图
4.源程序
#include//包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#include
sbitSCK=P3^6;//时钟
sbitSDA=P3^4;//数据
sbitRST=P3^5;//DS1302复位
sbitLS138A=P2^3;
sbitLS138B=P2^2;
sbitLS138C=P2^1;
bitReadRTC_Flag;//定义读DS1302标志
unsignedcharl_tmpdate[7]={0,0,12,15,5,3,8};//秒分时日月周年08-05-1512:
00:
00
unsignedcharl_tmpdisplay[8];
codeunsignedcharwrite_rtc_address[7]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};//秒分时日月周年最低位读写位
codeunsignedcharread_rtc_address[7]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};
codeunsignedchartable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40};
//共阴数码管0-9'-''熄灭‘表
/******************************************************************/
/*函数声明*/
/******************************************************************/
voidWrite_Ds1302_byte(unsignedchartemp);
voidWrite_Ds1302(unsignedcharaddress,unsignedchardat);
unsignedcharRead_Ds1302(unsignedcharaddress);
voidRead_RTC(void);//readRTC
voidSet_RTC(void);//setRTC
voidInitTIMER0(void);//initaltimer0
/******************************************************************/
/*主函数*/
/******************************************************************/
voidmain(void)
{
InitTIMER0();//初始化定时器0
Set_RTC();//写入时钟值,如果使用备用电池时候,不需要没每次上电写入,此程序应该屏蔽
while
(1)
{
if(ReadRTC_Flag)
{
ReadRTC_Flag=0;
Read_RTC();
l_tmpdisplay[0]=l_tmpdate[2]/16;//数据的转换,因我们采用数码管0~9的显示,将数据分开
l_tmpdisplay[1]=l_tmpdate[2]&0x0f;
l_tmpdisplay[2]=10;//加入"-"
l_tmpdisplay[3]=l_tmpdate[1]/16;
l_tmpdisplay[4]=l_tmpdate[1]&0x0f;
l_tmpdisplay[5]=10;
l_tmpdisplay[6]=l_tmpdate[0]/16;
l_tmpdisplay[7]=l_tmpdate[0]&0x0f;
}
}
}
/******************************************************************/
/*定时器0初始化*/
/******************************************************************/
voidInitTIMER0(void)
{
TMOD|=0x01;//定时器设置16位
TH0=0xef;//初始化值
TL0=0xf0;
ET0=1;
TR0=1;
EA=1;
}
/******************************************************************/
/*写一个字节*/
/******************************************************************/
voidWrite_Ds1302_Byte(unsignedchartemp)
{
unsignedchari;
for(i=0;i<8;i++)//循环8次写入数据
{
SCK=0;
SDA=temp&0x01;//每次传输低字节
temp>>=1;//右移一位
SCK=1;
}
}
/******************************************************************/
/*写入DS1302*/
/******************************************************************/
voidWrite_Ds1302(unsignedcharaddress,unsignedchardat)
{
RST=0;
_nop_();
SCK=0;
_nop_();
RST=1;
_nop_();//启动
Write_Ds1302_Byte(address);//发送地址
Write_Ds1302_Byte(dat);//发送数据
RST=0;//恢复
}
/******************************************************************/
/*读出DS1302数据*/
/******************************************************************/
unsignedcharRead_Ds1302(unsignedcharaddress)
{
unsignedchari,temp=0x00;
RST=0;
_nop_();
_nop_();
SCK=0;
_nop_();
_nop_();
RST=1;
_nop_();
_nop_();
Write_Ds1302_Byte(address);
for(i=0;i<8;i++)//循环8次读取数据
{
if(SDA)
temp|=0x80;//每次传输低字节
SCK=0;
temp>>=1;//右移一位
_nop_();
_nop_();
_nop_();
SCK=1;
}
RST=0;
_nop_();//以下为DS1302复位的稳定时间
_nop_();
RST=0;
SCK=0;
_nop_();
_nop_();
_nop_();
_nop_();
SCK=1;
_nop_();
_nop_();
SDA=0;
_nop_();
_nop_();
SDA=1;
_nop_();
_nop_();
return(temp);//返回
}
/******************************************************************/
/*读时钟数据*/
/******************************************************************/
voidRead_RTC(void)//读取日历
{
unsignedchari,*p;
p=read_rtc_address;//地址传递
for(i=0;i<7;i++)//分7次读取秒分时日月周年
{
l_tmpdate[i]=Read_Ds1302(*p);
p++;
}
}
/******************************************************************/
/*设定时钟数据*/
/******************************************************************/
voidSet_RTC(void)//设定日历
{
unsignedchari,*p,tmp;
for(i=0;i<7;i++){//BCD处理
tmp=l_tmpdate[i]/10;
l_tmpdate[i]=l_tmpdate[i]%10;
l_tmpdate[i]=l_tmpdate[i]+tmp*16;
}
Write_Ds1302(0x8E,0X00);
p=write_rtc_address;//传地址
for(i=0;i<7;i++)//7次写入秒分时日月周年
{
Write_Ds1302(*p,l_tmpdate[i]);
p++;
}
Write_Ds1302(0x8E,0x80);
}
/******************************************************************/
/*定时器中断函数*/
/******************************************************************/
voidtim(void)interrupt1using1
//中断,用于数码管扫描
{
staticunsignedchari,num;
TH0=0xf5;
TL0=0xe0;
P0=table[l_tmpdisplay[i]];//查表法得到要显示数字的数码段
switch(i)
{
case0:
LS138A=0;LS138B=0;LS138C=0;break;
case1:
LS138A=1;LS138B=0;LS138C=0;break;
case2:
LS138A=0;LS138B=1;LS138C=0;break;
case3:
LS138A=1;LS138B=1;LS138C=0;break;
case4:
LS138A=0;LS138B=0;LS138C=1;break;
case5:
LS138A=1;LS138B=0;LS138C=1;break;
case6:
LS138A=0;LS138B=1;LS138C=1;break;
case7:
LS138A=1;LS138B=1;LS138C=1;break;
}
i++;
if(i==8)
{
i=0;
num++;
if(10==num)//隔段时间读取1302的数据。
时间间隔可以调整
{
ReadRTC_Flag=1;//使用标志位判断
num=0;
}
}
}
5.总结