基于ds12c887的电子时钟制作

1179799903 贡献于2012-05-02

作者 Administrator  创建于2011-06-12 02:12:00   修改者Administrator  修改于2011-06-18 18:45:00字数4760

文档摘要:本项目以stc89c52单片机为控制单元,ocmj4x8c(128X64)为时钟显示器件,ds12c887时钟芯片作为系统的核心时钟器件,它能够自动产生世纪、 年、月、日、时、分、秒等时间信息,通过单片机从时钟芯片读取出来,再送到液晶屏显示。系统还需要设定四个按键,可以调节时间和日期,以及设定闹钟时间。每次有按键按下,蜂鸣器会发声。
关键词:

基于ds12c887的电子时钟方案 一. 方案概述: 本项目以stc89c52单片机为控制单元,ocmj4x8c(128X64)为时钟显示器件,ds12c887时钟芯片作为系统的核心时钟器件,它能够自动产生世纪、 年、月、日、时、分、秒等时间信息,通过单片机从时钟芯片读取出来,再送到液晶屏显示。系统还需要设定四个按键,可以调节时间和日期,以及设定闹钟时间。每次有按键按下,蜂鸣器会发声。 二.系统器件的选择: 1. 单片机: 该系统采用stc系列单片机,stc89c52单片机是一种最基本的单片机,操作简单,它的功能完全能够满足该系统的要求,所以选用stc89c52作为该系统的控制器件。 2. 显示器件: 方案一:采用7段数码管作为显示器件,根据本项目的要求,我们要制作的时钟需要显示时间,需要8个数码管,还要显示日期,星期等信息,需要的数码管数量较多,并且使用数码管还要加上译码器,进行位选,驱动电路较为复杂,并且占用的I/O口较多,故本方案不采用数码管作为显示器件。 方案二:采用OCMJ4X8C液晶作为显示器件,OCMJ4X8C是一种128X64的液晶,能显示汉字,图形,数字,符号等,并且所用的外围电路连接较少,比数码管占用的I/O口要少,故本项目采用OCMJ4X8c液晶作为显示器件。 3. 时钟芯片: 本项目采用ds12c887作为系统的时钟产生器件,它可以自动产生世纪、年、月、时、分、秒、等时间信息,其内 部又增加了世纪寄存器,从而利用硬件电路 解决子“千年”问题;DS12C887 中自带有锂电池,外部掉电时,其内部时间信息还能够保 持 10 年之久;对于一天内的时间记录,有12 小时制和 24 小时制两种模式。在 12 小时 制模式中,用 AM 和 PM 区分上午和下午;还可以设定闹钟,再通过外部中断,实现闹钟响铃。其内部集成了晶振,无需外加震荡电路,所需外围电路较少,故本系统采用它作为时钟产生芯片。 4.电源: 方案一:选用干电池作为该系统的供电器件,该系统的三个器件都需要+5V电源供电,如果使用干电池,需要四节才能满足要求,功耗较大,并且本项目作为实验项目,用干电池必然造成浪费,故不采用。 方案二:采用USB供电,USB为标准的+5V输出,输出电压稳定,能够满足本系统要求,故选用该方案。 三.系统组成: 经以上比较分析,该系统由STC89C52,OCMJ4X8C,DS12C887,四按键键盘,电源构成,系统框图如下,其中DS12C887是一个时钟芯片,其内部可以自动产生时、分、秒、年、月、日等信息,并且其内部有相应的寄存器保存这些信息,单片机可以通过相应的寄存器地址,读取这些信息,然后将这些信息送到液晶进行显示,四按键键盘接在单片机的I/O端口上,可以对单片机进行调节;蜂鸣器接在I/O口上,接收从单片机传来的信息,实现闹铃、按键提示的功能。 OCMJ4X8C液晶 DS12C887时钟芯片 STC89C52 四按键键盘 蜂鸣器 四.单元电路设计: 1. 蜂鸣器驱动电路:蜂鸣器是靠电流驱动的,51单片机I/O口的输出电流太小,无法驱动蜂鸣器发声,故需要接上三级管来驱动之,其驱动电路如下所示,蜂鸣器的正极连接VCC,负极接三极管,三级管的基级通过一个10k的电阻连接到单片机的P3.6口,可以通过控制P3.6口的电平来控制蜂鸣器的发声。 2. 液晶连接电路: 项目中所使用的液晶为OCMJ4X8C,它是一个20脚的器件,1,2脚为接地端和电源端;3脚为背光亮度调节端,该引脚需要连接一个电位器和VCC,进行背光亮度调节;4,5,6脚是与单片机通信的控制端,分别是RS,R/W和E,它们的操作要严格按照其时序图,系统中将他们分别连接至P1.0,P1.1,P1.2;7~14脚是8位数据口,与单片机的P2口连接;15脚为串/并行选择端,本项目使用并行操作,接高电平;17脚为复位口,接VCC;19,20脚为背光电源正负级,固定连接。故经以上分析,液晶电路如下: 3. DS12C887连接电路 DS12c887的连接方式与OCMJ4X8C连接方法类似,不再赘述,其连接电路如下: 五.软件设计: 本系统的软件部分主要由主函数,液晶写数据与命令子函数(2个子函数),DS12c887读、写子程序(2个子函数),键盘扫描(设定时间与闹钟时间),蜂鸣器发声子程序,初始化子程序,外部中断1(用来实现闹钟中断,使蜂鸣器发声),程序初步设计如下(真正实际能使用的程序还要在此基础上调试): #define uchar unsigned char //端口与变量的定义 #define uint unsigned int sbit rs=P1^0; sbit lcden=P1^2; sbit lcdrw=P1^1; sbit s1=P1^0; sbit s2=P1^1; sbit s3=P1^2; sbit s4=P1^3; sbit beep=P3^6; sbit dscs=P1^4; sbit dsas=P1^5; sbit dsrw=P1^6; sbit dsds=P1^7; sbit dsirq=P3^3; uchar count,s1num,flag,flag1; char miao,shi,fen; uchar code table[]=" 2007-7-30 MON"; uchar code table1[]=" : : "; #include #include void delay(uint z) //延时函数 { uint x,y; for(x=z;x>0;x--) for(y=110;y>0;y--); } void didi() //蜂鸣器发声函数 { beep=0; delay(50); beep=1; delay(100); beep=0; delay(50); beep=1; } void write_com(uchar com) //液晶写命令函数 { rs=0; lcden=0; P0=com; delay(5); lcden=1; delay(5); lcden=0; } void write_date(uchar date) //液晶写命令函数 { rs=1; lcden=0; P0=date; delay(5); lcden=1; delay(5); lcden=0; } void init() //初始化函数 { uchar num; EA=1; EX0=1; IT0=1; lcden=0; // set_time(); set_alarm(14,13,10); write_ds(0x0B,0x26); read_ds(0x0c); // fen=59; // miao=53; // shi=23; write_com(0x38); write_com(0x0c); write_com(0x06); write_com(0x01); write_com(0x80); for(num=0;num<15;num++) { write_date(table[num]); delay(5); } write_com(0x80+0x40); for(num=0;num<12;num++) { write_date(table1[num]); delay(5); } } void write_sfm(uchar add,uchar date) //液晶显示子函数 { uchar shi,ge; shi=date/10; ge=date%10; write_com(0x80+0x40+add); write_date(0x30+shi); write_date(0x30+ge); } void keyscan() //键盘扫描 { rd=0; if(flag1==1) { if(s2==0) { delay(5); if(s2==0) { while(!s2); flag1=0; } } if(s3==0) { delay(5); if(s3==0) { while(!s3); flag1=0; } } } if(s1==0) { delay(5); if(s1==0) { s1num++; flag=1; flag1=0; while(!s1); if(s1num==1) { TR0=0; write_com(0x80+0x40+10); write_com(0x0f); } } if(s1num==2) { write_com(0x80+0x40+7); } if(s1num==3) { write_com(0x80+0x40+4); } if(s1num==4) { s1num=0; write_com(0x0c); flag=0; write_ds(0,miao); write_ds(2,fen); write_ds(4,shi); } } if(s1num!=0) { if(s2==0) { delay(1); if(s2==0) { while(!s2); if(s1num==1) { miao++; if(miao==60) miao=0; write_sfm(10,miao); write_com(0x80+0x40+10); } if(s1num==2) { fen++; if(fen==60) fen=0; write_sfm(7,fen); write_com(0x80+0x40+7); } if(s1num==3) { shi++; if(shi==24) shi=0; write_sfm(4,shi); write_com(0x80+0x40+4); } } } if(s3==0) { delay(1); if(s3==0) { while(!s3); if(s1num==1) { /* if(miao==0) { miao=59; write_sfm(10,miao); write_com(0x80+0x40+10); }*/ miao--; if(miao==-1) miao=59; write_sfm(10,miao); write_com(0x80+0x40+10); } if(s1num==2) { fen--; if(fen==-1) fen=59; write_sfm(7,fen); write_com(0x80+0x40+7); } if(s1num==3) { shi--; if(shi==-1) shi=23; write_sfm(4,shi); write_com(0x80+0x40+4); } } } } } void write_ds(uchar add,uchar date) //ds12c887写函数 { dscs=0; dsas=1; dsds=1; dsrw=1; P0=add; dsas=0; dsrw=0; P0=date; dsrw=1; dsas=1; dscs=1; } uchar read_ds(uchar add) //DS12c887读函数 { uchar ds_date; dsas=1; dsds=1; dsrw=1; dscs=0; P0=add; dsas=0; dsds=0; P0=0xff; ds_date=P0; dsds=1; dsas=1; dscs=1; return ds_date; } void set_time() //设定初始时间 { write_ds(4,12); write_ds(2,0); } void set_alarm(uchar ashi,uchar afen,uchar amiao) //设定闹钟时间 { write_ds(1,amiao); write_ds(3,afen); write_ds(5,ashi); } void main() //主函数 { init(); while(1) { keyscan(); if(flag1==1) didi(); if(flag==0) { miao=read_ds(0); fen=read_ds(2); shi=read_ds(4); write_sfm(10,miao); write_sfm(7,fen); write_sfm(4,shi); } } } void exter() interrupt 0 //外部中断1 { uchar c; flag1=1; c=read_ds(0x0c); }

下载文档到电脑,查找使用更方便

文档的实际排版效果,会与网站的显示效果略有不同!!

需要 3 金币 [ 分享文档获得金币 ] 4 人已下载

下载文档