实时操作时钟DS1302的C程序应用.docx
《实时操作时钟DS1302的C程序应用.docx》由会员分享,可在线阅读,更多相关《实时操作时钟DS1302的C程序应用.docx(20页珍藏版)》请在冰豆网上搜索。
实时操作时钟DS1302的C程序应用
#include"reg52.h"
#include"intrins.h"
#defineuintunsignedint
#defineucharunsignedchar
unsignedcharcodeled[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0x0F8,0x80,0X90,0xbf};
unsignedcharcodewx[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
unsignedchardatadist[8];
unsignedchardatadisd[8];
sbitDS1302_CLK=P1^7;//实时时钟时钟线引脚
sbitDS1302_IO=P1^6;//实时时钟数据线引脚
sbitDS1302_RST=P1^5;//实时时钟复位线引脚
sbitACC0=ACC^0;
sbitACC7=ACC^7;
charhide_sec,hide_min,hide_hour,hide_day,hide_week,hide_month,hide_year;//秒,分,时到日,月,年位闪的计数
sbitSet=P3^4;//模式切换键
sbitUp=P3^5;//加法按钮
sbitDown=P3^6;//减法按钮
sbitxz=P3^7;//选择按钮
sbitbuzzer=P3^1;//定义蜂铃器接口
chardone,count,temp=0x00,flag,up_flag,down_flag,done1,count1;
/**********************************DS1302时钟部分子程序***************************************/
unsignedcharSecond;
unsignedcharMinute;
unsignedcharHour;
unsignedcharWeek;
unsignedcharDay;
unsignedcharMonth;
unsignedcharYear;
#defineAM(X)X
#definePM(X)(X+12)//转成24小时制
#defineDS1302_Second0x80//时钟芯片的寄存器位置,存放时间
#defineDS1302_Minute0x82
#defineDS1302_Hour0x84
#defineDS1302_Week0x8A
#defineDS1302_Day0x86
#defineDS1302_Month0x88
#defineDS1302_Year0x8C
/////////////////////////////////////////////////////////////////////////////////////
voiddelay1ms(unsignedintt)//1ms延时程序
{
unsignedinti,j;
for(i=0;i<=t;i++)
for(j=0;j<120;j++)
{}
}
////////////////////////////////////////////////////////////////////////////////////
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;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
unsignedcharRead1302(unsignedcharucAddr)//读取DS1302某地址的数据
{
unsignedcharucData;
DS1302_RST=0;
DS1302_CLK=0;
DS1302_RST=1;
DS1302InputByte(ucAddr|0x01);//地址,命令
ucData=DS1302OutputByte();//读1Byte数据
DS1302_CLK=1;
DS1302_RST=0;
return(ucData);
}
///////////////////////////////////////////////////////////////////////////////////////////
voidDS1302_SetProtect(bitflag)//是否写保护
{
if(flag)
Write1302(0x8E,0x10);
else
Write1302(0x8E,0x00);
}
/////////////////////////////////////////////////////////////////////////////////////////
voidDS1302_SetTime(unsignedcharAddress,unsignedcharValue)//设置时间函数
{
DS1302_SetProtect(0);
Write1302(Address,((Value/10)<<4|(Value%10)));
}
///////////////////////////////////////////////////////////////////////////////////////
voidDS1302_GetTime()//获取时钟芯片的时钟数据到自定义的结构型数组
{
unsignedcharReadValue;
ReadValue=Read1302(DS1302_Second);
Second=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);
ReadValue=Read1302(DS1302_Minute);
Minute=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);
ReadValue=Read1302(DS1302_Hour);
Hour=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);
ReadValue=Read1302(DS1302_Day);
Day=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);
ReadValue=Read1302(DS1302_Week);
Week=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);
ReadValue=Read1302(DS1302_Month);
Month=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);
ReadValue=Read1302(DS1302_Year);
Year=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);
}
////////////////////////////////////////////////////////////////////////////////////////////
voidTimeToSmg()//数据送数码管显示
{
unsignedchark;
if(count1==0)
{
dist[0]=Hour/10;dist[1]=Hour%10;
dist[2]=10;dist[3]=Minute/10;
dist[4]=Minute%10;dist[5]=10;
dist[6]=Second/10;dist[7]=Second%10;
for(k=0;k<8;k++)
{P0=led[dist[k]];P2=wx[k];delay1ms
(1);P2=0xff;}
}
if(count1==1)
{
disd[0]=Year/10;disd[1]=Year%10;
disd[2]=10;disd[3]=Month/10;
disd[4]=Month%10;disd[5]=10;
disd[6]=Day/10;disd[7]=Day%10;
for(k=0;k<8;k++)
{P0=led[disd[k]];P2=wx[k];delay1ms
(1);P2=0xff;}
}
}
/////////////////////////////////////////////////////////////////////////////////////////////
voidInitial_DS1302(void)//初始化ds1302
{
unsignedcharSecond=Read1302(DS1302_Second);
if(Second&0x80)
DS1302_SetTime(DS1302_Second,0);
DS1302_SetTime(DS1302_Minute,30);
DS1302_SetTime(DS1302_Hour,21);
DS1302_SetTime(DS1302_Day,28);
DS1302_SetTime(DS1302_Month,11);
DS1302_SetTime(DS1302_Year,10);
}
/****************************************按键部分程序****************************************/
voiddidi()//蜂铃器程序
{
buzzer=0;
delay1ms(20);
buzzer=1;
}
/////////////////////////////////////////////////////////////////////////////////////////////
voidfpkey()//跳出调整模式,返回默认显示
{
xz=1;
if(xz==0)
{
delay1ms(8);
if(xz==0)
{
didi();
count1=count1+1;//Setkey按一次,count就加1
if(count1==2)
count1=0;
}
}while(xz==0)TimeToSmg();
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
voidUpkey()//升序按键
{
Up=1;
fpkey();
if(Up==0)
{
delay1ms(8);
if(Up==0)
{
didi();
if(count1==0)
{
switch(count)
{case1:
temp=(Second+1)/10*16+(Second+1)%10;
if(Second==59)
temp=0;//秒数加1
up_flag=1;//数据调整后更新标志
break;
case2:
temp=(Minute+1)/10*16+(Minute+1)%10;
if(Minute==59)
temp=0;//分数加1
up_flag=1;
break;
case3:
temp=(Hour+1)/10*16+(Hour+1)%10;
if(Hour==23)
temp=0;//小时数加1
up_flag=1;
break;
default:
break;
}while(Up==0)TimeToSmg();
}
if(count1==1)
{
switch(count)
{
case1:
temp=(Day+1)/10*16+(Day+1)%10;
if(Day==31)
temp=0;//天数加1
up_flag=1;//数据调整后更新标志
break;
case2:
temp=(Month+1)/10*16+(Month+1)%10;
if(Month==12)
temp=0;//月数加1
up_flag=1;//数据调整后更新标志
break;
case3:
temp=(Year+1)/10*16+(Year+1)%10;
if(Year==49)
temp=0;//年加1
up_flag=1;//数据调整后更新标志
break;
default:
break;
}while(Up==0)TimeToSmg();
}
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
voidDownkey()//降序按键
{
Down=1;
fpkey();
if(Down==0)
{
delay1ms(8);
if(Down==0)
{
didi();
if(count1==0)
{
switch(count)
{case1:
temp=(Second-1)/10*16+(Second-1)%10;
if(Second==0)
temp=89;//秒数减1
down_flag=1;//数据调整后更新标志
break;
case2:
temp=(Minute-1)/10*16+(Minute-1)%10;
if(Minute==0)
temp=89;//分数减1
down_flag=1;
break;
case3:
temp=(Hour-1)/10*16+(Hour-1)%10;
if(Hour==0)
temp=35;//小时数减1
down_flag=1;
break;
default:
break;
}while(Down==0)TimeToSmg();
}
if(count1==1)
{
switch(count)
{
case1:
temp=(Day-1)/10*16+(Day-1)%10;
if(Day==0)
temp=49;//秒数减1
down_flag=1;
break;
case2:
temp=(Month-1)/10*16+(Month-1)%10;
if(Month==0)
temp=18;//秒数减1
down_flag=1;
break;
case3:
temp=(Year-1)/10*16+(Year-1)%10;
if(Year==0)
temp=73;//秒数减1
down_flag=1;
break;
default:
break;
}while(Down==0)TimeToSmg();
}
}
}
}
//////////////////////////////////////////////////////////////////////////////////////////////
voidSetkey()//模式选择按键
{
Set=1;
if(Set==0)
{
delay1ms(8);
if(Set==0)
{didi();
count=count+1;//Setkey按一次,count就加1
if(count==5)
count=1;
done=1;//进入调整模式
}
}while(Set==0)TimeToSmg();
}
/////////////////////////////////////////////////////////////////////////////////////////////
voidkeydone()//按键功能执行
{
if(flag==0)//关闭时钟,停止计时
{Write1302(0x8e,0x00);//写入允许
temp=Read1302(0x80);
Write1302(0x80,temp|0x80);
Write1302(0x8e,0x80);//禁止写入
flag=1;
}
if(count1==0)
{
Setkey();//扫描模式切换按键
switch(count)
{case1:
do//count=1,调整秒
{
Upkey();//扫描加按钮
Downkey();//扫描减按钮
if(up_flag==1||down_flag==1)//数据更新,重新写入新的数据
{
Write1302(0x8e,0x00);//写入允许
Write1302(0x80,temp|0x80);//写入新的秒数
Write1302(0x8e,0x80);//禁止写入
up_flag=0;
down_flag=0;
}
DS1302_GetTime();
TimeToSmg();//数码管显示数据
}while(count==2);break;
case2:
do//count=2,调整分
{
Upkey();
Downkey();
if(up_flag==1||down_flag==1)
{
Write1302(0x8e,0x00);//写入允许
Write1302(0x82,temp);//写入新的分数
Write1302(0x8e,0x80);//禁止写入
up_flag=0;
down_flag=0;
}
DS1302_GetTime();
TimeToSmg();
}while(count==3);break;
case3:
do//count=3,调整小时
{
Upkey();
Downkey();
if(up_flag==1||down_flag==1)
{
Write1302(0x8e,0x00);//写入允许
Write1302(0x84,temp);//写入新的小时数
Write1302(0x8e,0x80);//禁止写入
up_flag=0;
down_flag=0;
}
DS1302_GetTime();
TimeToSmg();
}while(count==4);break;
case4:
do
{
count=0;
Second=Read1302(DS1302_Second);
Write1302(0x8e,0x00);//写入允许
Write1302(0x80,Second&0x7f);
Write13