一.DS1302使用(三线SPI协议)

1.地址/命令字节

在这里插入图片描述

第7位:固定值1;
第6位:1—使用RAM功能,0—使用时钟功能;
第5~1位:寄存器地址;
第0位:1—读,0—写;

2.相关寄存器

在这里插入图片描述

前7个寄存器是保存时间(通过上表可看出,时间的存储方式采用BCD码)。
补充:第一个寄存器的最高位CH用来控制是否开始计数。0—正常计数;1—停止计数。默认为0。

第8个寄存器是写保护寄存器:第7位为1—打开写保护,禁止向其他寄存器写数据;为0—关闭写保护。

3.单字节读/写时序

在这里插入图片描述

二.代码

开发板原理图

在这里插入图片描述

sbit SCK=P1^7;		//时钟线
sbit SDA=P2^3;		//数据线
sbit RST=P1^3;    //复位线											

//循环写入一字节
void Write_Ds1302(unsigned  char temp) 
{
	unsigned char i;
	for (i=0;i<8;i++)     	
	{ 
		SCK=0;
		SDA=temp&0x01;		//与IIC类似,在每个时钟脉冲到来之前写入一位数据(先写低位)
		temp>>=1; 
		SCK=1;	
	}
}   

//向指定寄存器地址写入一字节数据
void Write_Ds1302_Byte( unsigned char address,unsigned char dat )     
{
 	RST=0;	_nop_();	//按时序图,为写数据做准备
 	SCK=0;	_nop_();
 	RST=1; 	_nop_();  
 	
 	Write_Ds1302(address);	//写地址和命令字节
 	Write_Ds1302(dat);		//写入数据
 	RST=0; 
}

//从指定寄存器地址读出一字节数据
unsigned char Read_Ds1302_Byte ( unsigned char address )
{
 	unsigned char i,temp=0x00;
 	RST=0;	_nop_();	//准备阶段
 	SCK=0;	_nop_();
 	RST=1;	_nop_();
 	
 	Write_Ds1302(address);		//写地址和命令字节
 	for (i=0;i<8;i++) 	
 	{		
		SCK=0;
		temp>>=1;	
 		if(SDA)
 		temp|=0x80;		//先读低位
 		SCK=1;
	} 
	
 	RST=0;	_nop_();	//结束阶段
 	SCK=0;	_nop_();
	SCK=1;	_nop_();
	SDA=0;	_nop_();
	SDA=1;	_nop_();
	return (temp);			
}

//写入初始化时间
void Write_Ds1302_Time(unsigned char shi,unsigned char fen, unsigned char miao)
{
	Write_Ds1302_Byte(0x8E,0);	//关闭写保护
	
	Write_Ds1302_Byte(0x80,miao/10*16+miao%10);	//转换成BCD码再储存
	Write_Ds1302_Byte(0x82,fen/10*16+fen%10);
	Write_Ds1302_Byte(0x84,shi/10*16+shi%10);
	
	Write_Ds1302_Byte(0x8E,0x80);	//打开写保护
}

void main()
{
	unsigned char hour, min, sec;
	Write_Ds1302_Time(23,59,58);
	
	while(1)
	{
		sec=Read_Ds1302_Byte(0x81);		//BCD码转换回十进制	
		sec=sec/16*10+sec%16;

		min=Read_Ds1302_Byte(0x83);
		min=min/16*10+min%16;
		
		hour=Read_Ds1302_Byte(0x85);
		hour=hour/16*10+hour%16;		
	}
}