ds1302时间读取.docx
《ds1302时间读取.docx》由会员分享,可在线阅读,更多相关《ds1302时间读取.docx(31页珍藏版)》请在冰豆网上搜索。
ds1302时间读取
一、
//*************DS1302****************************************************
#include
#defineucharunsignedchar
#defineuintunsignedint
#defineLEDP0
#defineLED_OFF0xff
sbitds1302_clk=P2^2;
sbitds1302_io=P2^1;
sbitds1302_rst=P2^0;
uchartime[7]={0x30,0x24,0x15,0x08,0x12,0x01,0x08};
voidsettime_ds1302();
voidgettime_ds1302();
voidwritetime_ds1302(uchar,uchar);
ucharreadtime_ds1302(uchar);
ucharreadbyte_ds1302();
voidwritebyte_ds1302(uchar);
voidnumdis(uchar,uchar,uchar);
voidtime_display();
main()
{
settime_ds1302();//设置时间
while
(1)
{
gettime_ds1302();//读取时间
time_display();//显示时间
}
}
//*****************************************************************
//设置预置时间到DS1302当中
//*****************************************************************
voidsettime_ds1302()
{
uchari;
writetime_ds1302(0x8e,0x00);//writeenable
for(i=0;i<7;i++)//settime--second,munite,hour,day,month,week,year
{
writetime_ds1302(0x80+i*2,time[i]);
}
writetime_ds1302(0x8e,0x80);//writeprotect
}
//*****************************************************************
//从DS1302中一次读出所有的数据并存在数组time[7]当中
//*****************************************************************
voidgettime_ds1302()
{
uchari;
for(i=0;i<7;i++)//gettime--second,munite,hour,day,month,week,year
{
time[i]=readtime_ds1302(0x81+i*2);
}
}
//*****************************************************************
//往DS1302的地址ds1302_add处写入ds1302_cmd数据或命令
//*****************************************************************
voidwritetime_ds1302(uchards1302_add,uchards1302_cmd)
{
//ds1302_rst=0;
//ds1302_clk=0;
ds1302_rst=1;
writebyte_ds1302(ds1302_add);
writebyte_ds1302(ds1302_cmd);
//ds1302_clk=1;
ds1302_rst=0;
}
//*****************************************************************
//从DS1302的地址DS1302_ADD处读出时间值
//*****************************************************************
ucharreadtime_ds1302(uchards1302_add)
{
uchartemp_data;
//ds1302_rst=0;
//ds1302_clk=0;
ds1302_rst=1;
writebyte_ds1302(ds1302_add);
temp_data=readbyte_ds1302();
//ds1302_clk=1;
ds1302_rst=0;
returntemp_data;
}
//*****************************************************************
//从DS1302中读出一字节并返回
//*****************************************************************
ucharreadbyte_ds1302()
{
uchari;
uchartemp_data;
for(i=0;i<8;i++)
{
/*if(ds1302_io)//这个延时有没有也是一样的
temp_data=(temp_data>>1)|0x80;
else
temp_data>>=1;
*/
//***********以上被注释部分的代码也可以用,实际测试过****************
if(ds1302_io)
temp_data|=(1<
else
temp_data&=(~(1<
ds1302_clk=1;
ds1302_clk=0;
}
returntemp_data;
}
//*****************************************************************
//往DS31302中写入一字节
//*****************************************************************
voidwritebyte_ds1302(uchards1302_data)
{
uchari;
uchartemp_data=ds1302_data;
for(i=8;i>0;i--)
{
ds1302_io=temp_data&0x01;
temp_data>>=1;
ds1302_clk=1;
ds1302_clk=0;
}
}
//*****************************************************************
//将读到的时间显示在六个数码管上,该子程序只显示分秒时。
//*****************************************************************
voidtime_display()
{
uchari;
for(i=0;i<=2;i++)
{
numdis(time[i]&0x0f,i*2,20);
numdis(((time[i]&0xf0)>>4),i*2+1,20);
}
}
//*****************************************************************
//数码管显示子程序,将一个数num显示到某一位weixuan数码管
//*****************************************************************
voidnumdis(ucharnum,ucharweixuan,ucharbrightness)
{
while(brightness--)LED=num*0x10+weixuan*0x01;
LED=LED_OFF;
}
MS1602的读写时序**************************
voidWrite(uchartempdata)
{
DB0_DB7=tempdata;
RS=0;
RW=0;
E=0;
nop;
E=1;
nop;
CheckBusy();
}
voidWriteDDR(uchartempdata)
{
DB0_DB7=tempdata;
RS=1;
nop;
RW=0;
E=0;
nop;
E=1;
nop;
CheckBusy();
}
voidCheckBusy()
{
DB0_DB7=0xff;
RW=1;
RS=0;
E=0;
nop;
E=1;
do
{
nop;
TEMP=DB0_DB7;
}while((TEMP&0x80)==0x80);
RW=0;
}
二、
#include
#include
#defineucharunsignedchar
#defineuintunsignedint
sbitSCK=P3^6;
sbitSDA=P3^4;
sbitRST=P3^5;//DS1302复位
sbitset=P3^0;//定义按键端口
sbits1=P3^1;
sbits2=P3^2;
sbits3=P3^3;
/************液晶口定义*******/
sbitRS=P2^4;//RS为数据/指令选择1/0
sbitRW=P2^5;//读写
sbitE=P2^6;//E为使能信号
bitflag;//是否读取时间的标志位
ucharsetn=0;//复位键、增加键、减少键按下次数
ucharcodetime0[]="DATE:
--";
ucharcodetime1[]="TIME:
:
:
";
ucharl_tmpdate[7]={0,55,16,22,8,6,9};//秒分时日月周年//可随时更改
ucharcodewrite_add[7]={0x80,0x82,0x84,0x86,
0x88,0x8a,0x8c};//秒分时日月周年写的寄存器地址
ucharcoderead_add[7]={0x81,0x83,0x85,0x87,
0x89,0x8b,0x8d};//秒分时日月周年读的寄存器地址
ucharcodetable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d
0x7d,0x07,0x7f,0x6f,0x40};//共阴数码管0-9加'-'熄灭表
voiddelay(uintz)
{
while(--z);
}
voidwrite_com(ucharcom)//液晶写命令函数
{
RS=0;//写命令使能
RW=0;//写
delay(5000);
/****在高脉冲下命令输入*****/
E=0;
P0=com;
delay(500);
E=1;
delay(500);
E=0;
}
voidwrite_data(uchardat)//液晶写数据函数
{
RS=1;//写数据使能
RW=0;
delay(5000);
/****在高脉冲下数据输入*****/
E=0;
P0=dat;
delay(500);
E=1;
delay(500);
E=0;
}
voidinit()//液晶初始化
{
ucharnum;
E=0;
write_com(0x38);//显示模式设置
delay(500);
write_com(0x38);
delay(500);
write_com(0x38);
write_com(0x08);//显示关闭
delay(500);
write_com(0x01);//显示清屏
write_com(0x06);//光标移动设置整屏不移动
write_com(0x0c);//屏幕开、光标不闪(0)不显示(0)
delay(500);
write_com(0x80);
for(num=0;num<16;num++)
{
write_data(time0[num]);
delay(5);
}
write_com(0x80+0x40);
for(num=0;num<13;num++)
{
write_data(time1[num]);
delay(5);
}
}
voidWrite_Ds1302_Byte(uchartemp)//写一个字节
{
uchari;
for(i=0;i<8;i++)//循环8次写入数据
{
SCK=0;
SDA=temp&0x01;//每次传输低字节
temp>>=1;//右移一位
SCK=1;
}
}
/****************************************************************************/
voidWrite_Ds1302(ucharadd,uchardat)//向寄存器写数据
{
RST=0;
_nop_();
SCK=0;
_nop_();
RST=1;//启动
_nop_();
Write_Ds1302_Byte(add);//发送地址
Write_Ds1302_Byte(dat);//发送数据
RST=0;//恢复
}
ucharRead_Ds1302_Byte()//读一个字节
{
uchari,temp=0x00;
for(i=0;i<8;i++)//循环8次读取数据
{
if(SDA)
temp|=0x80;//每次传输低字节
SCK=0;
temp>>=1;//右移一位
SCK=1;
}
return(temp);
}
ucharRead_Ds1302(ucharaddress)//从寄存器读数据
{
uchardate;
RST=0;
_nop_();
SCK=0;
_nop_();
RST=1;
_nop_();
Write_Ds1302_Byte(address);
date=Read_Ds1302_Byte();
RST=0;
_nop_();//以下为DS1302复位的稳定时间
RST=0;
SCK=0;
_nop_();
SCK=1;
_nop_();
SDA=0;
_nop_();
SDA=1;
_nop_();
return(date);
}
/*********************************************************/
voidRead_RTC(void)//读取日历
{
uchari,*p;
p=read_add;//读的地址传递
for(i=0;i<7;i++)//分7次读取秒分时日月周年
{
l_tmpdate[i]=Read_Ds1302(*p);
p++;
}
}
/******************************************************/
voidSet_RTC(void)//设定日历
{
uchari,*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_add;//传要写的寄存器地址
for(i=0;i<7;i++)//7次写入秒分时日月周年
{
Write_Ds1302(*p,l_tmpdate[i]);
p++;
}
Write_Ds1302(0x8E,0x80);//打开写保护
}
voidwrite_lcd()
{
staticuchari,temp[2];
switch(i)
{
case0:
write_com(0x80+0x40+0x0b);break;//秒
case1:
write_com(0x80+0x40+8);break;//分
case2:
write_com(0x80+0x40+5);break;//时
case3:
write_com(0x80+0x0b);break;//日
case4:
write_com(0x80+8);break;//月
case5:
write_com(0x80+0x0e);break;//星期
case6:
write_com(0x80+5);break;//年
}
temp[0]=l_tmpdate[i]/16;//数据的转换
temp[1]=l_tmpdate[i]&0x0f;
write_data(0x30+temp[0]);
write_data(0x30+temp[1]);
i++;
if(i==7)
i=0;
}
ucharchange(ucharx)//十进制转换成十六进制
{
uchartep,y;
y=x;
tep=y/16;
y=y%16;
y=y+tep*10;
returny;
}
voidkeyscan()
{
uchartem[2],tp,Flag;//存储要更改的时间数据
if(set==0)
{
flag=1;//时间停止
delay(500);//去键盘按下抖动
if(set==0)
{
delay(500);
while(!
set);
delay(500);//去键盘抬起时抖动
while(!
set);
delay(500);
setn++;
if(setn==1)
{
write_com(0x80+0x40+12);//将光标移动到秒个位
write_com(0x0f);//显示光标并且闪烁
}
if(setn==2)
{
write_com(0x80+0x40+9);//将光标移动到分个位
write_com(0x0f);//显示光标并且闪烁
}
if(setn==3)
{
write_com(0x80+0x40+6);//将光标移动到时个位
write_com(0x0f);//显示光标并且闪烁
}
if(setn==4)
{
write_com(0x80+15);
write_com(0x0f);
}
if(setn==5)
{
write_com(0x80+12);
write_com(0x0f);
}
if(setn==6)
{
write_com(0x80+9);
write_com(0x0f);
}
if(setn==7)
{
write_com(0x80+6);
write_com(0x0f);
}
if(setn==8)
{
setn=0;
Write_Ds1302(0x8E,0X00);//关闭写保护
Write_Ds1302(write_add[0],l_tmpdate[0]);
Write_Ds1302(0x8E,0x80);//打开写保护
flag=0;//时钟正常运行
write_com(0x0c);//光标停止闪烁
}
}
}
if(setn!
=0)//更改时间
{
if(s1==0)//增加时间
{
delay(5000);
if(s1==0)
{
while(!
s1);
delay(5000);//去键盘抬起时抖动
while(!
s1);
if(setn==1)
{
l_tmpdate[0]=change(l_tmpdate[0]);
l_tmpdate[0]++;
if(l_tmpdate[0]>=60)
l_tmpdate[0]=0;
{
tp=l_tmpdate[0]/10;
l_tmpdate[0]=l_tmpdate[0]%10;
l_tmpdate[0]=l_tmpdate[0]+tp*16;
Write_Ds1302(0x8E,0X00);//关闭写保护
Write_Ds1302(write_add[0],l_tmpdate[0]);
Write_Ds1302(0x8E,0x80);//打开写保护
}
write_com(0x80+0x40+11);
tem[0]=l_tmpdate[0]/16;//数据的转换
tem[1]=l_tmpdate[0]&0x0f;
write_data(0x30+tem[0]);
write_data(0x30+tem[1]);
write_com(0x80+0x40+12);
Flag=1;
}
if(setn==2)
{l_tmpdate[1]=change(l_tmpdate[1]);
l_tmpdate[1]++;
if(l_tmpdate[1]==60)
l_tmpdate[1]=0;
{
tp=l_tmpdate[1]/10;
l_tmpdate[1]=l_tmpdate[1]%10;
l_tmpdate[1]=l_tmpdate[1]+tp*16;
Write_Ds1302(0x8E,0X00);//关闭写保护
Write_Ds1302(write_add[1],l_tmpdate[1]);
Write_Ds1302(0x8E,0x80);//打开写保护
}
write_com(0x80+0x40+8);
tem[0]=l_tmpdate[1]/16;//数据的转换
tem[1]=l_tmpdate[1]&0x0f;
write_data(0x30+tem[0]);
write_data(0x30+tem[