【蓝桥杯单片机组】实时时钟RTC(DS1302)

1、寄存器表

【蓝桥杯单片机组】实时时钟RTC(DS1302)_第1张图片

注意:

(1)ds1302.h中提供的寄存器地址是写地址,读寄存器时需要将地址加一

(2)

#define ds1302_control_addr		0x8Ee		//写保护命令字单元地址
对应上图倒数第二行: BIT7 = 0(取消写保护)、BIT7 = 1(上写保护)
(3) 读一次寄存器后需要增加一条写指令(不知道为什么):

curtime[i] = Ds1302_Single_Byte_Read(read_addr[i]);
Ds1302_Single_Byte_Write(0x00, 0x00);	
(4)在提供的ds1302.c中使用到的函数为:

/********************************************************************/ 
/*向DS1302单字节写入一字节数据*/
extern void Ds1302_Single_Byte_Write(unsigned char addr, unsigned char dat);
/********************************************************************/ 
/*从DS1302单字节读出一字节数据*/
extern unsigned char Ds1302_Single_Byte_Read(unsigned char addr);



2、DS1302相关知识(from datasheet ):


X1、X2:32.768KHZ晶振

SCLK:串行时钟

CE:复位脚,在数据读写期间必须为高

I/O:数据

两电源引脚关系为备用电源,Vcc1为主电源

CLK I/O经常与I2C总线接在一个引脚上,但DS1302并不是I2C总线,是一种三线式总线


3、DS1302驱动分析(比赛提供)

驱动步骤:

(1)CE  = 1

(2)在上升沿按位传输地址字

(3)读取 / 写入相应地址的数据

(4)CE = 0

附:驱动文件ds1302.c

/********************************************************************/ 
/*向DS1302 单字节写入一字节数据*/
void Ds1302_Single_Byte_Write(unsigned char addr, unsigned char dat)
{ 

	RST_CLR;			/*RST脚置低,实现DS1302的初始化*/
	SCK_CLR;			/*SCK脚置低,实现DS1302的初始化*/

	RST_SET;			/*启动DS1302总线,RST=1电平置高 */
	addr = addr & 0xFE;	 
	Write_Ds1302_Byte(addr); /*写入目标地址:addr,保证是写操作,写之前将最低位置零*/	
	Write_Ds1302_Byte(dat);	 /*写入数据:dat*/
	RST_CLR;				 /*停止DS1302总线*/
}

/********************************************************************/ 
/*从DS1302单字节读出一字节数据*/
unsigned char Ds1302_Single_Byte_Read(unsigned char addr) 
{ 
	unsigned char temp;
	RST_CLR;			/*RST脚置低,实现DS1302的初始化*/
	SCK_CLR;			/*SCK脚置低,实现DS1302的初始化*/

	RST_SET;	/*启动DS1302总线,RST=1电平置高 */	
	addr = addr | 0x01;	 
	Write_Ds1302_Byte(addr); /*写入目标地址:addr,保证是读操作,写之前将最低位置高*/
	temp=Read_Ds1302_Byte(); /*从DS1302中读出一个字节的数据*/		
	RST_CLR;	/*停止DS1302总线*/
	return temp;
}


4、设定 / 读取时间

(1)设定时间

uchar settime[6] = {1,11,22,17,20,0};

uchar write_addr[6] = {0x8C,0x88,0x86,0x84,0x82,0x80};
uchar read_addr[6] = {0x8d,0x89,0x87,0x85,0x83,0x81};

void DS1302_settime(uchar stime[])			//输入十进制数字
{
	uchar temptime[6];
	int i;
	for(i = 0;i < 6;i++)  					//按寄存器格式整理输入数据
	{
		temptime[i] = ((stime[i]/10)<<4)+(stime[i]%10);
	}
	Ds1302_Single_Byte_Write(ds1302_control_addr, 0x00); 	//取消写保护
	for(i=0;i<6;i++)
	{
		Ds1302_Single_Byte_Write(write_addr[i], temptime[i]);//设置时间	
	}
	Ds1302_Single_Byte_Write(ds1302_control_addr, 0x80); 	//上写保护
}

注意:为了方便起见,将用到的寄存器地址位放入数组,取值参照ds1302.h,read_addr = write_addr + 1


(2)获取时间

uchar curtime[6];

void gettime()									//输出十进制数字
{
	int i;
	for(i=0;i<6;i++)
	{	
		curtime[i] = Ds1302_Single_Byte_Read(read_addr[i]);
		Ds1302_Single_Byte_Write(0x00, 0x00);	
		curtime[i] = ((curtime[i] & 0xf0)>>4)*10+(curtime[i] & 0x0f);
	}	
}

附:测试程序

void main()
{
	cls_buzz();
	UartInit();

	DS1302_settime(settime);

	Delay100ms(100);
	gettime();
	sendtime(curtime);

	while(1);
}

void sendtime(char dat[])
{
	int i;
	for(i=0;i<6;i++)
	{
		SBUF = 	dat[i];
		while(!TI);
		TI = 0;
	}

}




你可能感兴趣的:(蓝桥杯单片机组)