基于DS1302的单片机数字时钟.docx
《基于DS1302的单片机数字时钟.docx》由会员分享,可在线阅读,更多相关《基于DS1302的单片机数字时钟.docx(14页珍藏版)》请在冰豆网上搜索。
基于DS1302的单片机数字时钟
源程序如下:
#include
#include
//定义共阳极字型码0123456789-
//unsignedcharcodedispcode[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf};
unsignedcharcodedispcode[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40};
unsignedchartime[]={0,0,0,0,0,0,0,0};//用来储存时间
unsignedchardate[]={0,0,0,0,0,0,0,0};//用来储存日期
SYSTEMTIMEtime1;//在ds1302.h文件中已经定义了一个名字为SYSTEMTIME的结构体,在这里我们定义一个变量名
//为time的SYSTEMTIME结构体
voiddelay(unsignedchari)//延时子程序
{
unsignedcharj;
while((i--)!
=0)
{
for(j=123;j>0;j--);
}
}
unsignedcharbutton_time(n,x,y)//时钟调整子程序
unsignedcharn,x,y;
{
if(P1_7==0)
{
delay(50);
if(P1_7==0)
{
n++;
if(n==x)
n=0;
while(P1_7==0);
}
}
if(P1_5==0)
{
delay(50);
if(P1_5==0)
{
if(n==0)
n=y;
else
n--;
while(P1_5==0);
}
}
returnn;
}
unsignedcharbutton_date(n,x,y)//日期调整子程序
unsignedcharn,x,y;
{
if(P1_7==0)
{
delay(50);
if(P1_7==0)
{
n++;
if(n==x)
n=1;
while(P1_7==0);
}
}
if(P1_5==0)
{
delay(50);
if(P1_5==0)
{
if(n==1)
n=y;
else
n--;
while(P1_5==0);
}
}
returnn;
}
voiddisplay(second10,second1,minute10,minute1,hour10,hour1)//显示子程序
unsignedcharsecond10,second1,minute10,minute1,hour10,hour1;
{
P2=0xfe;
P0=dispcode[second10];//显示秒的十位
delay
(1);
P2=0xfd;
P0=dispcode[second1];//显示秒的个位
delay
(1);
P2=0xfb;
P0=dispcode[10];//显示"-"
delay
(1);
P2=0xf7;
P0=dispcode[minute10];//显示分的十位
delay
(1);
P2=0xef;
P0=dispcode[minute1];//显示分的个位
delay
(1);
P2=0xdf;
P0=dispcode[10];//显示"-"
delay
(1);
P2=0xbf;
P0=dispcode[hour10];//显示时的十位
delay
(1);
P2=0x7f;
P0=dispcode[hour1];//显示时的个位
delay
(1);
}
voidmain()
{
unsignedcharflag;
Initial_DS1302();//初始化DS1302这个时钟芯片,
while
(1)
{
DS1302_GetTime(&time1);//读取时间参数
time[5]=(time1.Second)%10;//把秒的个位数据存入time[5]
time[4]=(time1.Second)/10;//把秒的十位数据存入time[4]
time[3]=(time1.Minute)%10;//把分的个位数据存入time[3]
time[2]=(time1.Minute)/10;//把分的十位数据存入time[2]
time[1]=(time1.Hour)%10;//把时的个位数据存入time[1]
time[0]=(time1.Hour)/10;//把时的十位数据存入time[0]
date[5]=(time1.Day)%10;
date[4]=(time1.Day)/10;
date[3]=(time1.Month)%10;
date[2]=(time1.Month)/10;
date[1]=(time1.Year)%10;
date[0]=(time1.Year)/10;
if(P1_4==0)//如果按下TimeStart键一下,时钟开始正常显示时间,再按一下,显示日期
{
delay(50);
if(P1_4==0)
{
flag++;
if(flag>1)
{
flag=0;
}
}
while(P1_4==0);
}
if(P1_6==0)//如果按下TimeSet键一下,开始显示日期,再按一下进入日期跟时钟的调节模式
{
delay(50);
if(P1_6==0)
{
flag++;
if(flag>7)
{
flag=0;
}
}
while(P1_6==0);
}
switch(flag)
{
case0:
display(time[0],time[1],time[2],time[3],time[4],time[5]);//调用子函数display,把存入数组time的数据给显示出来
break;
case1:
display(date[0],date[1],date[2],date[3],date[4],date[5]);//调用子函数display,把存入数组date的数据给显示出来
break;
case2:
time1.Year=button_date(time1.Year,100,99);//调整年
DS1302_SetTime(0x8c,time1.Year);
display(date[0],date[1],10,10,10,10);
break;
case3:
time1.Month=button_date(time1.Month,13,12);//调整月
DS1302_SetTime(0x88,time1.Month);
display(10,10,date[2],date[3],10,10);
break;
case4:
time1.Day=button_date(time1.Day,32,31);//调整日
DS1302_SetTime(0x86,time1.Day);
display(10,10,10,10,date[4],date[5]);
break;
case5:
time1.Hour=button_time(time1.Hour,24,23);//调整时
DS1302_SetTime(0x84,time1.Hour);
display(time[0],time[1],10,10,10,10);
break;
case6:
time1.Minute=button_time(time1.Minute,60,59);//调整分
DS1302_SetTime(0x82,time1.Minute);
display(10,10,time[2],time[3],10,10);
break;
case7:
time1.Second=button_time(time1.Second,60,59);//调整秒
DS1302_SetTime(0x80,time1.Second);
display(10,10,10,10,time[4],time[5]);
break;
}
}
}
头文件ds1302.h程序如下:
#ifndef_REAL_TIMER_DS1302_2003_7_21_
#define_REAL_TIMER_DS1302_2003_7_21_
#include
sbitDS1302_CLK=P1^0;//实时时钟时钟线引脚
sbitDS1302_IO=P1^1;//实时时钟数据线引脚
sbitDS1302_RST=P1^2;//实时时钟复位线引脚
sbitACC0=ACC^0;
sbitACC7=ACC^7;
typedefstruct__SYSTEMTIME__
{
unsignedcharSecond;
unsignedcharMinute;
unsignedcharHour;
unsignedcharWeek;
unsignedcharDay;
unsignedcharMonth;
unsignedcharYear;
unsignedcharDateString[9];
unsignedcharTimeString[9];
}SYSTEMTIME;//定义的时间类型
#defineAM(X)X
#definePM(X)(X+12)//转成24小时制
#defineDS1302_SECOND0x80//秒寄存器
#defineDS1302_MINUTE0x82//分寄存器
#defineDS1302_HOUR0x84
#defineDS1302_WEEK0x8A
#defineDS1302_DAY0x86
#defineDS1302_MONTH0x88
#defineDS1302_YEAR0x8C
#defineDS1302_RAM(X)(0xC0+(X)*2)//用于计算DS1302_RAM地址的宏
voidDS1302InputByte(unsignedchard)//实时时钟写入一字节(内部函数)
{
unsignedchari;
ACC=d;
for(i=8;i>0;i--)
{
DS1302_IO=ACC0;//相当于汇编中的RRC
DS1302_CLK=1;
DS1302_CLK=0;//发一个高跳变到低的脉冲
ACC=ACC>>1;
}
}
unsignedcharDS1302OutputByte(void)//实时时钟读取一字节(内部函数)
{
unsignedchari;
for(i=8;i>0;i--)
{
ACC=ACC>>1;//相当于汇编中的RRC
ACC7=DS1302_IO;
DS1302_CLK=1;
DS1302_CLK=0;//发一个高跳变到低的脉冲
}
return(ACC);
}
voidWrite1302(unsignedcharucAddr,unsignedcharucDa)//ucAddr:
DS1302地址,ucData:
要写的数据
{
DS1302_RST=0;
DS1302_CLK=0;
DS1302_RST=1;
DS1302InputByte(ucAddr);//地址,命令
DS1302InputByte(ucDa);//写1Byte数据
DS1302_CLK=1;
DS1302_RST=0;//RST0->1->0,CLK0->1
}
unsignedcharRead1302(unsignedcharucAddr)//读取DS1302某地址的数据
{
unsignedcharucData;
DS1302_RST=0;
DS1302_CLK=0;
DS1302_RST=1;//enable
DS1302InputByte(ucAddr|0x01);//地址,命令
ucData=DS1302OutputByte();//读1Byte数据
DS1302_CLK=1;//RST0->1->0,CLK0->1
DS1302_RST=0;
return(ucData);
}
voidDS1302_SetProtect(bitflag)//是否写保护
{
if(flag)
Write1302(0x8E,0x10);//WP=1,不能写入
else
Write1302(0x8E,0x00);//WP=0,可以写入
}
voidDS1302_SetTime(unsignedcharAddress,unsignedcharValue)//设置时间函数
{
DS1302_SetProtect(0);
Write1302(Address,((Value/10)<<4|(Value%10)));//高4位为十位,低4位为个位
}
voidDS1302_GetTime(SYSTEMTIME*Time)
{
unsignedcharReadValue;
ReadValue=Read1302(DS1302_SECOND);
Time->Second=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);//转换成10进制的秒
ReadValue=Read1302(DS1302_MINUTE);
Time->Minute=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);
ReadValue=Read1302(DS1302_HOUR);
Time->Hour=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);
ReadValue=Read1302(DS1302_DAY);
Time->Day=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);
ReadValue=Read1302(DS1302_WEEK);
Time->Week=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);
ReadValue=Read1302(DS1302_MONTH);
Time->Month=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);
ReadValue=Read1302(DS1302_YEAR);
Time->Year=((ReadValue&0xf0)>>4)*10+(ReadValue&0x0F);
}
/*
voidDateToStr(SYSTEMTIME*Time)
{
Time->DateString[0]=Time->Year/10+'0';//数字类型转化为字符类型
Time->DateString[1]=Time->Year%10+'0';
Time->DateString[2]='-';
Time->DateString[3]=Time->Month/10+'0';
Time->DateString[4]=Time->Month%10+'0';
Time->DateString[5]='-';
Time->DateString[6]=Time->Day/10+'0';
Time->DateString[7]=Time->Day%10+'0';
Time->DateString[8]='\0';
}
voidTimeToStr(SYSTEMTIME*Time)
{
Time->TimeString[0]=Time->Hour/10+'0';//数字类型转化为字符类型
Time->TimeString[1]=Time->Hour%10+'0';
Time->TimeString[2]=':
';
Time->TimeString[3]=Time->Minute/10+'0';
Time->TimeString[4]=Time->Minute%10+'0';
Time->TimeString[5]=':
';
Time->TimeString[6]=Time->Second/10+'0';
Time->TimeString[7]=Time->Second%10+'0';
Time->DateString[8]='\0';
}
*/
voidInitial_DS1302(void)
{
unsignedcharSecond=Read1302(DS1302_SECOND);
if(Second&0x80)//如果第七为1(表明没有启动),则启动时钟
DS1302_SetTime(DS1302_SECOND,0);
}
/********************************************************************************
voidBurstWrite1302(unsignedchar*pWClock)//往DS1302写入时钟数据(多字节方式)
{
unsignedchari;
Write1302(0x8e,0x00);//控制命令,WP=0,写操作?
DS1302_RST=0;
DS1302_CLK=0;
DS1302_RST=1;
DS1302InputByte(0xbe);//0xbe:
时钟多字节写命令
for(i=8;i>0;i--)//8Byte=7Byte时钟数据+1Byte控制
{
DS1302InputByte(*pWClock);//写1Byte数据
pWClock++;
}
DS1302_CLK=1;
DS1302_RST=0;
}
voidBurstRead1302(unsignedchar*pRClock)//读取DS1302时钟数据(时钟多字节方式)
{
unsignedchari;
DS1302_RST=0;
DS1302_CLK=0;
DS1302_RST=1;
DS1302InputByte(0xbf);//0xbf:
时钟多字节读命令
for(i=8;i>0;i--)
{
*pRClock=DS1302OutputByte();//读1Byte数据
pRClock++;
}
DS1302_CLK=1;
DS1302_RST=0;
}
voidDS1302_TimeStop(bitflag)//是否将时钟停止
{
unsignedcharData;
Data=Read1302(DS1302_SECOND);
DS1302_SetProtect(0);
if(flag)
Write1302(DS1302_SECOND,Data|0x80);//停止
else
Write1302(DS1302_SECOND,Data&0x7F);不停止
}
********************************************************************************/
#endif