在最初接触单片机的时候,很多人都想做一个时钟,有些方案是直接用单片机进行计算的,这个我做过;还有一种方案是使用时钟芯片,而在选择时钟芯片的时候,很多人的眼光都会聚焦在DS1302这个芯片上:
DS1302 是美国DALLAS公司推出的一种高性能、低功耗、带RAM的实时时钟电路,它可以对年、月、日、周日、时、分、秒进行计时,具有闰年补偿功能,工作电压为2.5V~5.5V。采用三线接口与CPU进行同步通信,并可采用突发方式一次传送多个字节的时钟信号或RAM数据。DS1302内部有一个31×8的用于临时性存放数据的RAM寄存器。DS1302是DS1202的升级产品,与DS1202兼容,但增加了主电源/后背电源双电源引脚,同时提供了对后背电源进行涓细电流充电的能力。
我当时在使用DS1302时,也曾收集了一些资料,附件是这块芯片的英文和中文资料,可下载参考。
同时,也贴上这个芯片与51单片机的底层通信代码(代码是本人网上搜集并稍作修改的),希望对大家有用。
sbit DS1302_clk=0xb7;
sbit DS1302_data=0xb6;
sbit DS1302_cs=0xb5;
unsigned char year,month,date,hour,minute,second,week;
void short_ds1302_delay()
{
unsigned char i;
for(i=0;i<5;i++);
}
void long_ds1302_delay()
{
unsigned char i;
for(i=0;i<25;i++);
}
void DS1302_write(unsigned char DS1302_temp)
{
unsigned char i,temp;
long_ds1302_delay();
temp=DS1302_temp;
for(i=0;i<8;i++)
{
DS1302_data=temp&0x01;
short_ds1302_delay();
DS1302_clk=1;
short_ds1302_delay();
DS1302_clk=0;
temp=temp>>1;
}
}
unsigned char DS1302_read(void)
{
unsigned char i,temp;
long_ds1302_delay();
temp=0;
for(i=0;i<8;i++)
{
temp=temp>>1;
if(DS1302_data==1)
temp=temp+0x80;
DS1302_clk=1;
short_ds1302_delay();
DS1302_clk=0;
short_ds1302_delay();
}
return temp;
}
/////////写操作设置,当a=0x80时禁止写操作,a=0x00时允许////////////////
void DS1302_write_able(unsigned char a)
{
DS1302_cs=0;
DS1302_clk=0;
short_ds1302_delay();
DS1302_cs=1;
DS1302_write(0x8e);
DS1302_data=1;
DS1302_write(a);
DS1302_cs=0;
short_ds1302_delay();
DS1302_clk=1;
}
////////////////////ds1302初始化////////////////////////
void DS1302_init()
{
unsigned char i;
DS1302_write_able(0x00); //允许写操作
DS1302_cs=0;
DS1302_clk=0;
short_ds1302_delay();
DS1302_cs=1;
DS1302_write(0x81);
DS1302_data=1;
i=DS1302_read();
DS1302_cs=0;
short_ds1302_delay();
DS1302_clk=1;
second=((i>>4)&0x07)*10+(i&0x0f);
DS1302_clk=0;
short_ds1302_delay();
DS1302_cs=1;
DS1302_write(0x80);
DS1302_data=1;
DS1302_write(0x7f&i);
DS1302_cs=0;
short_ds1302_delay();
DS1302_clk=1;
DS1302_clk=0; //充电设置
short_ds1302_delay();
DS1302_cs=1;
DS1302_write(0x90);
DS1302_data=1;
DS1302_write(0xa6); //允许充电,一个二极管 4k电阻
DS1302_cs=0;
short_ds1302_delay();
DS1302_clk=1;
DS1302_write_able(0x80); //禁止写操作
}
void DS1302_readdate()
{
unsigned char i;
DS1302_cs=0;
//读取second
DS1302_clk=0;
short_ds1302_delay();
DS1302_cs=1;
DS1302_write(0x81);
DS1302_data=1;
i=DS1302_read();
DS1302_cs=0;
short_ds1302_delay();
DS1302_clk=1;
second=((i>>4)&0x07)*10+(i&0x0f);
//读取分minute
DS1302_clk=0;
short_ds1302_delay();
DS1302_cs=1;
DS1302_write(0x83);
DS1302_data=1;
i=DS1302_read();
DS1302_cs=0;
short_ds1302_delay();
DS1302_clk=1;
minute=((i>>4)&0x07)*10+(i&0x0f);
//读取时hour
DS1302_clk=0;
short_ds1302_delay();
DS1302_cs=1;
DS1302_write(0x85);
DS1302_data=1;
i=DS1302_read();
DS1302_cs=0;
short_ds1302_delay();
DS1302_clk=1;
hour=((i>>4)&0x03)*10+(i&0x0f);
//读取日date
DS1302_clk=0;
short_ds1302_delay();
DS1302_cs=1;
DS1302_write(0x87);
DS1302_data=1;
i=DS1302_read();
DS1302_cs=0;
short_ds1302_delay();
DS1302_clk=1;
date=((i>>4)&0x03)*10+(i&0x0f);
//读取月份month
DS1302_clk=0;
short_ds1302_delay();
DS1302_cs=1;
DS1302_write(0x89);
DS1302_data=1;
i=DS1302_read();
DS1302_cs=0;
short_ds1302_delay();
DS1302_clk=1;
month=((i>>4)&0x01)*10+(i&0x0f);
//读取周week
DS1302_clk=0;
short_ds1302_delay();
DS1302_cs=1;
DS1302_write(0x8b);
DS1302_data=1;
i=DS1302_read();
DS1302_cs=0;
short_ds1302_delay();
DS1302_clk=1;
week=i&0x07;
//读取年份year
DS1302_clk=0;
short_ds1302_delay();
DS1302_cs=1;
DS1302_write(0x8d);
DS1302_data=1;
i=DS1302_read();
DS1302_cs=0;
short_ds1302_delay();
DS1302_clk=1;
year=((i>>4)&0x0f)*10+(i&0x0f);
}
void DS1302_writedate()
{
DS1302_write_able(0x00);
DS1302_cs=0;
//写second
DS1302_clk=0;
short_ds1302_delay();
DS1302_cs=1;
DS1302_write(0x80);
DS1302_data=1;
DS1302_write(0x7f&(((second/10)<<4)+(second%10)));
DS1302_cs=0;
short_ds1302_delay();
DS1302_clk=1;
//minute
DS1302_clk=0;
short_ds1302_delay();
DS1302_cs=1;
DS1302_write(0x82);
DS1302_data=1;
DS1302_write(0x7f&(((minute/10)<<4)+(minute%10)));
DS1302_cs=0;
short_ds1302_delay();
DS1302_clk=1;
//hour
DS1302_clk=0;
short_ds1302_delay();
DS1302_cs=1;
DS1302_write(0x84);
DS1302_data=1;
DS1302_write(0x3f&(((hour/10)<<4)+(hour%10)));
DS1302_cs=0;
short_ds1302_delay();
DS1302_clk=1;
//date
DS1302_clk=0;
short_ds1302_delay();
DS1302_cs=1;
DS1302_write(0x86);
DS1302_data=1;
DS1302_write(0x3f&(((date/10)<<4)+(date%10)));
DS1302_cs=0;
short_ds1302_delay();
DS1302_clk=1;
//month
DS1302_clk=0;
short_ds1302_delay();
DS1302_cs=1;
DS1302_write(0x88);
DS1302_data=1;
DS1302_write(0x1f&(((month/10)<<4)+(month%10)));
DS1302_cs=0;
short_ds1302_delay();
DS1302_clk=1;
//week
DS1302_clk=0;
short_ds1302_delay();
DS1302_cs=1;
DS1302_write(0x8a);
DS1302_data=1;
DS1302_write(0x07&week);
DS1302_cs=0;
short_ds1302_delay();
DS1302_clk=1;
//year
DS1302_clk=0;
short_ds1302_delay();
DS1302_cs=1;
DS1302_write(0x8c);
DS1302_data=1;
DS1302_write(((year/10)<<4)+(year%10));
DS1302_cs=0;
short_ds1302_delay();
DS1302_clk=1;
DS1302_write_able(0x80);
}