ds1302实时时钟程序说明

  • 格式:doc
  • 大小:185.00 KB
  • 文档页数:5

DS1302是美国达拉斯公司生产的一款实时时钟芯片,采用SPI三线接口方式与单片机进行
通信,内部提供年、月、日、星期、时、分、秒,还有闰年补偿等功能。具有宽电压,低功
耗,高性能等优点。DS1302内部有31个静态数据寄存器,可以进行BCD码数据存储。
在对DS1302进行操作时候,先要写入控制字。,选择相应的寄存器地址进行读或者写操作。

DS1302的读时序图

RST相当于片选信号,只有当RST为高电平期间,才能有效对DS1302进行操作,在SCLK
的上升沿写入数据,低位在前,高位在后,先写入控制字,这里是进行读操作,所以在紧接
着第8个时钟之后的第一个下降沿就读取数据,也是低位在前,高位在后的。
DS1302的写时序图

同理,也是在RST为高电平期间,才能有效地操作DS1302,先写入控制字,接着在第8个
时钟之后的第一个上升沿的时候,就写入数据,也是低位在前的,这样就完成了写操作。
下面是DS1302内部寄存器的地址的说明。
DS1302实时时钟在数码管上进行实时显示的程序
#include
#include
#define uint unsigned int
#define uchar unsigned char
sbit rst=P2^4;
sbit io=P2^0;
sbit clk=P2^1;
sbit duan=P2^6;
sbit wei=P2^7;
uchar code table[]={0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71,0x00,0x40};
uchar code table2[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};
uchar time_data[7]={14,2,4,8,19,20,30};//设置一个数组作为时间校对的初值
uchar write_add[7]={0x8c,0x8a,0x88,0x86,0x84,0x82,0x80};//寄存器的地址写操作 年周月日
时分秒
uchar read_add[7]={0x8d,0x8b,0x89,0x87,0x85,0x83,0x81};//寄存器的地址读操作
uchar disp[8]; //进行显示的数值
void delay(uint x)
{
uint i,j;
for(i=x;i>0;i--)
for(j=110;j>0;j--);
} //约为x毫秒时间
void write_byte(uchar dat) //写一个字节的函数
{
uchar i; //高电平数据稳定,低电平变化
for(i=0;i<8;i++)
{
clk=0;
io=dat&0x01;
dat>>=1;
clk=1;

}
}
void write_ds1302(uchar add,uchar dat) //这里需要对rst进行拉高,才能传输数据
{
rst=0;
_nop_(); //进行简短延时约为2us
clk=0;
_nop_();
rst=1; //进行rst拉高操作
_nop_();
write_byte(add);//写寄存器地址
write_byte(dat);//接着就写数据不需要延时
rst=0;
_nop_();
clk=1;
_nop_();
io=1;
_nop_(); //释放数据线

}
uchar read_ds1302(uchar add)
{
uchar i,temp;
rst=0;
_nop_();
clk=0;
_nop_();
rst=1;
_nop_();
write_byte(add); //先选中要读取数据的寄存器
for(i=0;i<8;i++)
{
temp>>=1; //移位7次
clk=0; //读取时低电平数据稳定,高电平变化
if(io)
temp|=0x80;
clk=1;

}
rst=0;
_nop_();
clk=1;
_nop_();
io=1;
_nop_(); //进行释放总线操作

return temp;
}
void set_rtc()
{ uchar i,j;
for(i=0;i<7;i++) //例58
{
j=time_data[i]/10; //十位5
time_data[i]%=10; //各位8
time_data[i]=time_data[i]+j*16;

}
write_ds1302(0x8e,0x00); //去除写保护
for(i=0;i<7;i++)
{
write_ds1302(write_add[i],time_data[i]);

}
write_ds1302(0x8e,0x80); //进行写保护
}
void read_rtc()
{
uchar i;
for(i=0;i<7;i++)
{
time_data[i]=read_ds1302(read_add[i]);
}
}
void time_pros()
{
disp[0]=time_data[6]%16;//将BCD码(这里与十六进制没有区别)进行十位个位的分离
disp[1]=time_data[6]/16;
disp[2]=17;
disp[3]=time_data[5]%16;
disp[4]=time_data[5]/16;
disp[5]=17;
disp[6]=time_data[4]%16;
disp[7]=time_data[4]/16;

}
void display()
{
uchar i;
for(i=0;i<8;i++)
{
duan=1;
P0=table[disp[i]];
duan=0;
P0=0xff;
wei=1;
P0=table2[i];
wei=0;
delay(2);

}
}
void main()
{
set_rtc();
while(1)
{
read_rtc();//读取初值,在相应的寄存器里读取数值
time_pros();//进行数据的转换
display(); //进行实时显示
}
}