电子钟设计.docx
《电子钟设计.docx》由会员分享,可在线阅读,更多相关《电子钟设计.docx(19页珍藏版)》请在冰点文库上搜索。
![电子钟设计.docx](https://file1.bingdoc.com/fileroot1/2023-6/21/5fccc138-0e9e-4996-86bb-2725340afd68/5fccc138-0e9e-4996-86bb-2725340afd681.gif)
电子钟设计
电子钟设计
摘要
本课程设计目的是设计一个可显示年、月、日、星期、时、分、秒的电子钟,并通过简易的按键操作方便的更换显示的时刻。
该电子钟操纵电路由STC89C51单片机实现,时钟由DS1302时钟芯片提供,显示部分为1602液晶显示模块。
本项目差不多工作流程为:
上电后单片机给DS1302时钟芯片写入一组初始时刻,之后单片机定时向DS1302芯片读取时刻信息,并通过1602液晶显示模块显示出来,当有操纵按键按下后,单片机将更换的时刻信号写入DS1302芯片,由于单片机不停的从DS1302芯片中读取信息显示在1602液晶显示模块上,从而实现时刻的调整。
通过反复调试和改进完全实现了预期要求。
关键字:
单片机DS1302液晶显示
一、设计目的:
设计一个可显示年、月、日、星期、时、分、秒的电子钟,并通过简易的按键操作方便的更换显示的时刻。
二、设计中的问题及分析:
1)时钟信号的来源
电子钟的时钟信号的来源一样有两种:
单片机提供和时钟芯片提供。
这两种时钟信号各有其利弊。
采纳单片机提供的方案电路结构简单,程序编写方便,但由于不同单片机工作的时钟频率不同程序的移植性不强,时钟的精度不高,一样还需占据单片机的一两个定时计数器,在系统设计时占用了宝贵资源。
采纳时钟芯片提供的方案尽管电路复杂一些但具有专门高的时钟精度和程序的可移植性。
通过比对本设计采纳了时钟芯片DS1302来提供时钟信号。
2)显示方式的选择
显示方式也有两种方案:
数码管显示和液晶显示,数码管虽有其价格低廉的优势但其功耗大电路复杂,显示稳固度差。
出于功耗和显示质量的考虑在本设计中选用了1602液晶显示模块作为显示部分。
3)按键的设计
按键的作用是用于实现时刻信号的更换,可行的方案有两种:
数字键盘加功能键和只用功能键。
数字键盘加功能键能够提供方便快捷的操作,但过多的按键数不适用本设计通过简易的按键操作方便的更换显示的时刻的要求。
最终本设计选择了只用功能键的设计方案,通过一个按键循环选择更换对象,通过另一个按键来循环增加时刻值。
三、硬件电路设计:
1)电路如下所示:
由于本人在开发板上完成该电子课程设计工作,电路图取自DY500开发板说明书。
图1单片机电路
图2DS1302时钟芯片电路
图31602液晶显示电路
图4晶振、复位、按键电路
2)芯片及模块说明
1.DS1302时钟芯片
DS1302慢速充电时钟芯片包括实时时钟/日历和31字节的静态RAM。
它通过一个简单的串行接口与微处理器通信。
实时时钟/日历提供秒、分、时、日、周、月和年等信息。
关于小于31天的月,月末的日期自动进行调整,还包括了闰年校正的功能。
时钟的运行能够采纳24小时或带AM(上午)/PM(下午)的12小时格式。
使用同步串行通信,简化了DS1302与微处理器的通信。
与时钟/RAM通信仅需三根线:
(1)RST(复位)、
(2)I/O(数据线)、和(3)SCLK(串行时钟)。
数据能够以每次一个字节或多达31字节的多字节形式传送至时钟/RAM或从其中送出。
DS1302设计成能在专门低的功耗下工作,消耗小于1微瓦的功率便能储存数据和时钟信息。
2.1602液晶显示模块
工业字符型液晶,能够同时显示16x02即32个字符。
(16列2行)1602液晶模块内部的字符发生储备器(CGROM)差不多储备了160个不同的点阵字符图形,这些字符有:
阿拉伯数字、英文字母的大小写、常用的符号、和日文假名等,每一个字符都有一个固定的代码,比如大写的英文字母“A”的代码是01000001B(41H),显示时模块把地址41H中的点阵字符图形显示出来,我们就能看到字母“A”。
四、使用方法及其显示结果
如图4所示,有两个按键S1和S2,其作用分别为:
S1用于循环选择调整对象,如年份,日期等,被选择的对象所在位置光标闪耀用于指示位置。
S2键用于循环增加被S1选中的信息,单片机操纵被选信息的循环规律,如调整“月”的个位,当月的十位为零时,个位增加到9后才归零,而当十位为一时,个位增加到2后就归零,如此显示器上可不能显示与现实不符合的时刻。
当时刻调整时时钟会停止,直至一次调整完成才复原运行。
该时钟复位时刻为2000-00-00DAY
00:
00:
00,依次为年、月、日、星期、时、分、秒,其中DAY表示星期通过调整可显示星期的英文缩写MON、TUE、WED、THU、FRI、SAT、SUN。
液晶显示器右下角显示的“铃”形标志是本人用于在本电子钟上附加闹铃功能而设计的,但因闹铃功能设计尚未完成,故不能完成该部分工作。
图5单片机开发板图6上电5S时
图7调整年的各个位图8调整星期
由图7和图8能够看到被调整的时刻项的所在位置光标闪耀,同时时钟停止(两图时刻显示都为“00:
00:
43”)。
图9调整的当前时刻图10运行8分钟之后
由上所列图片,能够看到本设计能完全大道设计要求。
五.程序
/*电子钟设计,显示年、月、日、星期、时、分、秒
设计时刻2009-12-29*/
#include//完成显示和变化值显示
#defineuintunsignedint
#defineucharunsignedchar
uchardatatime[8]={0};
uchardatatime1[8]={0};
ucharcodet[]={0x04,0x0e,0x0e,0x1f,0x1f,0x00,0x04,0};//闹铃的代码
ucharcodeday[]={"DAYMONTUEWEDTHUFRISATSUN"};
ucharkey,n,n1;
sbitSCK=P3^5;
sbitSDA=P3^6;
sbitRST=P3^7;//DS1302复位
sbitrs=P2^2;
sbiten=P2^4;
sbitrw=P2^3;
sbitk1=P3^0;
sbitk2=P3^1;
sbitk3=P3^3;
voiddelay(ucharc)//延时
{
uchara,b;
for(a=0;afor(b=0;b<110;b++)
;
}
voidwrite1(uchartemp)//写
{
uchari;
for(i=0;i<8;i++)//循环8次写入数据
{
SCK=0;
SDA=temp&0x01;//每次传输低字节
temp>>=1;//右移一位
SCK=1;
}
}
voidwrite(ucharaddress,uchardat)//写一位
{
RST=0;
SCK=0;
RST=1;//启动
write1(address);//发送地址
write1(dat);//发送数据
RST=0;//复原
}
voidwrite_n()//写日历8位
{
ucharm;
RST=0;
SCK=0;
RST=1;
write1(0xbe);
for(m=0;m<8;m++)
write1(time[m]);
RST=0;
}
ucharread1()//读
{
uchari,tem;
for(i=0;i<8;i++)//循环8次读取数据
{
tem>>=1;
//每次传输低字节
SCK=0;
if(SDA)
tem|=0x80;//右移一位
SCK=1;
}
return(tem);
}
ucharread(ucharaddress)//读一位
{
uchartemp=0x00;
RST=0;
SCK=0;
RST=1;
write1(address);
temp=read1();
RST=0;//以下为DS1302复位的稳固时刻
SCK=0;
SDA=1;
return(temp);//返回
}
voidread_n()//读日历8位
{
ucharm;//liya_10
RST=0;
SCK=0;
RST=1;
write1(0xbf);
for(m=0;m<8;m++)
time[m]=read1();
RST=0;
SCK=0;
SDA=1;
}voiddsdate()//运算
{
ucharm;
for(m=0;m<8;m++)
{
time1[m]=time[m]>>4;
}
for(m=0;m<8;m++)
{
time[m]&=0x0f;
}
}
voiddelay1(ucharc)//延时
{
uinta,b;
for(a=0;afor(b=0;b<11;b++)
;
}
voidwrite_add(ucharadd)//1602写指令
{
en=0;
rs=0;
rw=0;
P0=add;
en=1;
en=0;
P0=0xff;
}
voidwrite_date(uchardate)//1602写数据
{
en=0;
rs=1;
rw=0;
P0=date;
en=1;
en=0;
P0=0xff;
}
voidchu()//1602初始化
{
write_add(0x01);
delay1
(1);
write_add(0x38);
delay1
(1);
write_add(0x0c);
delay1
(1);
write_add(0x06);
delay1
(1);
}
voidkey2(ucharm)
{
uchart;
if(k2==0)
{
delay(10);
while(k2==0);
time[m]++;
if(time[m]==n)
time[m]=0;
time1[m]<<=4;
t=time[m]+time1[m];
if(t>=n1)
t=0;
m<<=1;
m+=0x80;
write(m,t);
}
}
voidkey3(ucharm)
{
uchart;
if(k2==0)
{
delay(10);
while(k2==0);
time1[m]++;
if(time1[m]==n)
time1[m]=0;
time1[m]<<=4;
t=time[m]+time1[m];
if(t>=n1)
t=0;
m<<=1;
m+=0x80;
write(m,t);
}
}
voidkey1()//按键
{
ucharmao;
if(k1==0)
{
delay(10);
while(k1==0);
key++;
}
if(key!
=0)
{
mao=read(0x81);
mao|=0x80;
write(0x80,mao);
delay1
(1);
if(key==1)
{write_add(0x83);n=10;n1=0xa0;key3(6);}
if(key==2)
{write_add(0x84);n=10;n1=0xa0;key2(6);}
if(key==3)
{write_add(0x86);n=2;n1=0x13;key3(4);}
if(key==4)
{write_add(0x87);n=10;n1=0x13;key2(4);}
if(key==5)
{write_add(0x89);n=4;n1=0x32;key3(3);}
if(key==6)
{write_add(0x8a);n=10;n1=0x32;key2(3);}
if(key==7)
{write_add(0x8d);n=8;n1=8;key2(5);}
if(key==8)
{write_add(0xc2);n=3;n1=0x24;key3
(2);}
if(key==9)
{write_add(0xc3);n=10;n1=0x24;key2
(2);}
if(key==10)
{write_add(0xc5);n=6;n1=0x60;key3
(1);}
if(key==11)
{write_add(0xc6);n=10;n1=0x60;key2
(1);}
if(key==12)
key=0;
delay1
(1);
write_add(0x0F);
delay1
(1);
delay(60);
write_add(0x0c);
mao&=0x7f;
write(0x80,mao);
}
}
voidtu()
{
ucharm;
write_add(0x40);//自定义区入口地址
for(m=0;m<8;m++)//写代码
{
delay1
(1);
write_date(t[m]);
}
}
voidmain()
{
uchark,d;
key=0;
write_n();
//mao=read(0x81);
//mao|=0x80;
//write(0x80,0);
chu();
tu();
delay1
(2);
while
(1)
{
read_n();
dsdate();
write_add(0x81);//显示年
delay1
(1);
write_date('2');
delay1
(1);
write_date('0');
delay1
(1);
write_date(time1[6]+0x30);
delay1
(1);
write_date(time[6]+0x30);
delay1
(1);
write_date('-');
for(k=5;k>3;k--)//显示年月日
{
delay1
(1);
write_date(time1[k-1]+0x30);
delay1
(1);
write_date(time[k-1]+0x30);
delay1
(1);
if(k==4)
break;
write_date('-');
}
delay1
(1);
write_add(0x8d);//显示星期
delay1
(1);
d=time[5]<<2;
for(k=0;k<3;k++)
{
write_date(day[d+k]);
delay1
(1);
}
write_add(0x82+0x40);
delay1
(1);
for(k=3;k>0;k--)//显示时刻
{
delay1
(1);
time1[k-1]&=0x07;
write_date(time1[k-1]+0x30);
delay1
(1);
write_date(time[k-1]+0x30);
delay1
(1);
if(k==1)
break;
write_date(':
');
}
delay1
(1);
write_add(0x8d+0x40);
delay1
(1);
write_date(0);
key1();
}
}