
这是ds1302的主要特点:时钟计数功能,可以对秒、分钟、小时、月、星期、年的计数。年计数可达到2100 年。有31*8 位的额外数据暂存寄存器(即RAM,掉电丢失)等等。

看完以上这些我们大致知道了ds1302这个芯片能干什么,接下来我们就要搞清楚如何使用它。首先要知道各个引脚是干什么用的 
在这里,我们主要是对5 CE、6 I/O、7 SCLK这三个引脚进行操作去驱动ds1302这个芯片。
CE: 输入。 在读取或写入期间,CE信号必须置为高电平。 这个引脚有一个内部40kΩ(典型值)的下拉电阻接地。 注意:以前的数据表修订简称CE为RST。 引脚的功能没有改变;
I/O: 输入/推挽输出。 I / O引脚是3线的双向数据引脚接口。 该引脚有一个内部40kΩ(典型值)下拉电阻接地;
SCLK: 输入。 SCLK用于同步串行接口上的数据移动。 这个引脚有一个内部40kΩ(典型值)下拉电阻接地。
知道了各个引脚的功能后,我们看时序图,通过时序图来编写驱动程序,对于刚学单片机的同学来说可能一开始看不懂,那就多找几个时序图对应着别人写好的驱动程序好好看看,总结总结,应该就能看懂了,然后再自己试着写写,毕竟我们不是庖丁,要想达到庖丁那样的神技,两个字:多练

我们可以看到这是一个单字节读写时序图,前面八位读写的是地址,代表着不同的功能,后面八位读写的是数据。读写操作明显的不同之处是后面八位数据位的操作不同,读操作时是SCLK的下降沿锁存数据,也就是说如果我们要想从I/O口读出一位数据,就得先把SCLK引脚拉高,然后再拉低,有一个由高到低的跳变,这样才能读出数据。而写操作时是SCLK的上升沿锁存数据。道理都一样。还有一点就是,我们可以发现读写数据都是从低位到高位:D0-D7
再接着我们要知道如何对寄存器进行操作,我的理解就是一张真值表,不同的值有什么功能:

下面我们来编写ds1302的驱动程序,从实践中加深理解:
/********************************************************************/
/********************************************************************/ /*单字节读出一字节数据*/unsigned char Read_Ds1302_Byte(void) { unsigned char i, dat=0; for (i=0;i<8;i++) { dat = dat >> 1; if (IO) //等价于if(IO==1) /*读取IO口电平*/ { dat |= 0x80; } else { dat &= 0x7F; } SCLK_SET; //时钟线SCLK置高,再置低,就是一个下降沿,锁存数据 SCLK_CLR; // 置低,而且数据传输完成后时钟线SCLK拉低 } return dat;} CE_CLR; /*初始时CE置低电平*/ SCLK_CLR; /*初始时SCLK置低电平*/ /********************************************************************/ /*从DS1302单字节读出一字节数据*/unsigned char Ds1302_Single_Byte_Read(unsigned char addr) { unsigned char temp; CE_CLR; /*CE置低电平,初始化*/ SCLK_CLR; /*SCLK置低电平,初始化*/ void ds1302_init(){ Ds1302_Single_Byte_Write(0x8e, 0x00); //关闭写保护 Ds1302_Single_Byte_Write(ds1302_sec_addr, 0x40); //写秒地址0x80 Ds1302_Single_Byte_Write(ds1302_min_addr, 0x20); //写分地址0x82 Ds1302_Single_Byte_Write(ds1302_hr_addr, 0x10); //写时地址0x84 初始时间为10时20分40秒 Ds1302_Single_Byte_Write(0x8e, 0x80); //开写保护} { uchar i=0; for(i=0;i<8;i++) { clock(0xc0,wei); switch(i) { case 0:clock(0xe0,duan[time[2]/16]);break; case 1:clock(0xe0,duan[time[2]&0x0f]);break; case 2:clock(0xe0,0xbf);break; case 3:clock(0xe0,duan[time[1]/16]);break; case 4:clock(0xe0,duan[time[1]&0x0f]);break; case 5:clock(0xe0,0xbf);break; case 6:clock(0xe0,duan[time[0]/16]);break; case 7:clock(0xe0,duan[time[0]&0x0f]);break; default:break; } Delay2ms(); } }
|