#DS1302#--拓展模块使用教程和心得(一):时钟模块DS1302

成就更好的自己

本系列为全网最详细的拓展模块使用心得和教程,欢迎各位看官发表高见,对您有所帮助将是我最大的荣幸,创作不易,点赞评论,拒绝白嫖,从我做起。

作者希望系本列只起到快速开发和辅助学习的作用,允许的话应该从数据手册下手,以便锻炼自己阅读数据手册和自主开发的能力。

 

目录

DS1302功能及参数指标

PIN讲解

数据的输入输出及时序

寄存器和RAM

常用寄存器

RAM空间

涓流充电

代码篇

 

 


DS1302功能及参数指标(划重点)

  • 具有涓细电流充电能力;
  • 31*8位通用暂存RAM;
  • 在2V电压工作时,电流小于300nA;
  • 备用电源掉电走时,超低功耗;
  • 主电源/后备电源双电源引脚;
  • 它可以对年、月、日、周、时、分、秒进行计时;
  • 具有闰年补偿等多种功能;
  • 工作电压为2.0V~5.5V;
  • 采用三线接口与CPU进行串行同步通信(类SPI通信);
  • 备用电源可以用纽扣电池或者超级电容器(0.1F以上);
  • 需外接32.768kHz晶振;
  • 存放的时间数据为BCD码形式;

 

 

 

PIN讲解

#DS1302#--拓展模块使用教程和心得(一):时钟模块DS1302_第1张图片

  • VCC2:提供工作电源,在主电源供电情况下在对涓流充电寄存器进行设置后,将对VCC1所接的后备电源进行充电;
  • GND:接地,VCC1和VCC2共地;
  • VCC1:接后备电源正极;
  • SCLK:时钟信号,由主机产生并控制,在通信提供统一的节拍;
  • I/O:数据线;
  • RST(有的称为CE):复位(作者认为应该理解为片选),只有在RST为1的时候(相当于选中该芯片),所有数据才进行传输,否则DS1302的I/O引脚将呈现出高阻态;

 

 

数据的输入输出及时序

  1.  每次通信(不论读写),都是由两个字节组成;如果是修改DS1302的数据,第一字节发送命令,第二字节发送数据;如果是读DS1302的数据,第一字节发送命令,第二字节接收数据;
  2. 在CLK上升沿时DS1302采集I/O线上的电平,在CLK下降沿时DS1302将数据放到I/O线上,请注意主机提供数据,采集数据,跳变时钟的节律;
  3. 只有在SCLK为低电平时,才能将RST置为高电平;
  4.  在控制指令字输入后的下一个SCLK时钟的上升沿时,数据被写入DS1302,在紧跟8位的控制指令字后的下一个SCLK脉冲的下降沿读出DS1302的数据;
  5. 读写数据均为低位(0位)在前,高位(7位)最后;
  6. 读DS1302和写DS1302有不一样的地方,写的时候单片机IO口一直是输出状态,但读的时候单片机先是输出状态后是输入状态,而且要记得改变时钟信号的顺序;

#DS1302#--拓展模块使用教程和心得(一):时钟模块DS1302_第2张图片

总时序如下:在进行操作之前先将SCLK置低电平,然后将RST置为高电平,接着开始在IO上面放入要传送的电平信号,然后跳变SCLK。数据在SCLK上升沿时,DS1302读写数据,在SCLK下降沿时,DS1302放置数据到IO;

 

 

寄存器和RAM

DS1302有12个寄存器,其中有7个寄存器与日历、时钟相关,存放的数据位为BCD码形式,其日历、时间寄存器。此外,DS1302 还有年份寄存器、控制寄存器、充电寄存器、时钟突发寄存器及与RAM相关的寄存器等;

RAM相关的寄存器分为两类:一类是单个RAM单元,共31个,每个单元组态为一个8位的字节,其命令控制字为C0H~FDH,其中奇数为读操作,偶数为写操作;另一类为突发方式下的RAM寄存器,此方式下可一次性读写所有的RAM的31个字节;

常用的寄存器的命令格式:

D7:固定为1;

D6:RAM/CK位,=1片内RAM,=0日历、时钟寄存器选择位;

D5~D1:地址位,用于选择进行读写的日历、时钟寄存器或片内RAM;

D0: 读写选择,=0写,=1读;

对应的常用寄存器命令的见表:

(秒寄存器,分寄存器,时寄存器,日寄存器,月寄存器,周寄存器,年寄存器,控制寄存器,充电寄存器,爆破寄存器(忽略,这个用不上))

#DS1302#--拓展模块使用教程和心得(一):时钟模块DS1302_第3张图片

以下详细介绍常用寄存器,左图为命令格式,右图为寄存器数据格式:

秒寄存器

读命令0x81,写命令0x80;

寄存器数据内容:0~3位为秒个位的BCD码;4~6位为秒十位BCD码;7位为CH位,控制时钟振荡源是否被禁止进而控制时钟的计时,CH=1时,时钟停止,时间保持为停摆前的一刻,CH=0时,从最后一次状态开始计时;

分钟计时器

读命令0x83,写命令0x82;

寄存器数据内容:0~3位为分钟个位的BCD码;4~6位为分钟十位BCD码;7位无意义,默认0;

时钟寄存器

读命令0x85,写命令0x84;

寄存器数据内容:0~3位为小时个位的BCD码;4或5位为小时十位BCD码;6位无意义,默认0;7位,控制12/24小时制,为1时,12小时制,为0时,24小时制;

日寄存器

读命令0x87,写命令0x86;

寄存器数据内容:0~3位为日个位的BCD码;4~5位为日十位BCD码;6~7位无意义,默认0;

月寄存器

读命令0x89,写命令0x88;

寄存器数据内容:0~3位为月个位的BCD码;4位为月十位BCD码;5~7位无意义,默认0;

周寄存器

读命令0x8b,写命令0x8a;

寄存器数据内容:0~3位为周的BCD码;4~7位无意义,默认0;

年寄存器

读命令0x8d,写命令0x8c;

 

寄存器数据内容:0~3位为年的BCD码;4~7位为年十位BCD码;

控制寄存器

读命令0x8f,写命令0x8e;

寄存器数据内容:7位为WP位,保护数据不被写入,WP=1时,开启保护,WP=0时,关闭保护;0~6位无意义,默认0;

充电寄存器

读命令0x91,写命令0x90;

寄存器数据内容:后边解释;

爆破寄存器

读命令0x93,写命令0x92;

寄存器数据内容:基本用不上,忽略即可;

 

 

 

除此之外,DS1302还有31个字节的RAM空间:

按照上文的指令格式可以自由读写,地址空间如下:

 

#DS1302#--拓展模块使用教程和心得(一):时钟模块DS1302_第4张图片

 

 

 

涓流充电

由涓流充电寄存器控制;

2-3位:

DS=01 为一个二极管

DS=10 为二个二极管

DS=00 无二极管,不能充电

DS=11 无二极管,不能充电

 

0-1位:

RS=00 无电阻,不能充电

RS=01                 2K

RS=10                 4K

RS=11                 8K

 

4-7位:

TCS=1010 能充电        

其它组合都不能充电

 

10100101   一个二极管 电阻2K

10100110   一个二极管 电阻4K

10100111   一个二极管 电阻8K

10101001   两个二极管 电阻2K

10101010   两个二极管 电阻4K

10101011   两个二极管 电阻8K

01011100   初始化电源

 

选择一个二极管和一个电阻(2K) 充电电流约 2.2mA;

选择一个二极管和一个电阻(4K) 充电电流约 1.1mA;

选择一个二极管和一个电阻(8K) 充电电流约 0.5mA;

 

 

 

代码篇:

平台:STC89C52;以下为端口函数:

//---DS1302写入和读取时分秒的地址命令---//
//---秒分时日月周年 最低位读写位;-------//
uchar code READ_RTC_ADDR[7] = {0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d}; 
uchar code WRITE_RTC_ADDR[7] = {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c};

 

/*******************************************************************************
* 函 数 名         : Ds1302Write
* 函数功能		   : 向DS1302命令(地址+数据)
* 输    入         : addr,dat
* 输    出         : 无
*******************************************************************************/

void Ds1302Write(uchar addr, uchar dat)
{
	uchar n;
	RST = 0;
	_nop_();

	SCLK = 0;//先将SCLK置低电平。
	_nop_();
	RST = 1; //然后将RST(CE)置高电平。
	_nop_();

	for (n=0; n<8; n++)//开始传送八位地址命令
	{
		DSIO = addr & 0x01;//数据从低位开始传送
		addr >>= 1;
		SCLK = 1;//数据在上升沿时,DS1302读取数据
		_nop_();
		SCLK = 0;
		_nop_();
	}
	for (n=0; n<8; n++)//写入8位数据
	{
		DSIO = dat & 0x01;
		dat >>= 1;
		SCLK = 1;//数据在上升沿时,DS1302读取数据
		_nop_();
		SCLK = 0;
		_nop_();	
	}	
		 
	RST = 0;//传送数据结束
	_nop_();
}

 

/*******************************************************************************
* 函 数 名         : Ds1302Read
* 函数功能		   : 读取一个地址的数据
* 输    入         : addr
* 输    出         : dat
*******************************************************************************/

uchar Ds1302Read(uchar addr)
{
	uchar n,dat,dat1;
	RST = 0;
	_nop_();

	SCLK = 0;//先将SCLK置低电平。
	_nop_();
	RST = 1;//然后将RST(CE)置高电平。
	_nop_();

	for(n=0; n<8; n++)//开始传送八位地址命令
	{
		DSIO = addr & 0x01;//数据从低位开始传送
		addr >>= 1;
		SCLK = 1;//数据在上升沿时,DS1302读取数据
		_nop_();
		SCLK = 0;//DS1302下降沿时,放置数据
		_nop_();
	}
	_nop_();
	for(n=0; n<8; n++)//读取8位数据
	{
		dat1 = DSIO;//从最低位开始接收
		dat = (dat>>1) | (dat1<<7);
		SCLK = 1;
		_nop_();
		SCLK = 0;//DS1302下降沿时,放置数据
		_nop_();
	}

	RST = 0;
	_nop_();	//以下为DS1302复位的稳定时间,必须的。
	SCLK = 1;
	_nop_();
	DSIO = 0;
	_nop_();
	DSIO = 1;
	_nop_();
	return dat;	
}

 

/*******************************************************************************
* 函 数 名         : Ds1302Init
* 函数功能		   : 初始化DS1302.
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/

void Ds1302Init()
{
	uchar n;
	Ds1302Write(0x8E,0X00);		 //禁止写保护,就是关闭写保护功能
	for (n=0; n<7; n++)//写入7个字节的时钟信号:分秒时日月周年
	{
		Ds1302Write(WRITE_RTC_ADDR[n],TIME[n]);	
	}
	Ds1302Write(0x8E,0x80);		 //打开写保护功能
}

 

/*******************************************************************************
* 函 数 名         : Ds1302ReadTime
* 函数功能		   : 读取时钟信息
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/

void Ds1302ReadTime()
{
	uchar n;
	for (n=0; n<7; n++)//读取7个字节的时钟信号:分秒时日月周年
	{
		TIME[n] = Ds1302Read(READ_RTC_ADDR[n]);
	}
		
}

头文件如下:

//---重定义关键词---//
#ifndef uchar
#define uchar unsigned char
#endif

#ifndef uint 
#define uint unsigned int
#endif

//---定义ds1302使用的IO口---//
sbit DSIO=P3^4;
sbit RST=P3^5;
sbit SCLK=P3^6;

//---定义全局函数---//
void Ds1302Write(uchar addr, uchar dat);
uchar Ds1302Read(uchar addr);
void Ds1302Init();
void Ds1302ReadTime();

参考资料:

文章构思来自https://wenku.baidu.com/view/1c014a0616fc700abb68fc45.html

涓流充电测评来自https://blog.csdn.net/jinn3/article/details/7320070?locationNum=7&fps=1

鸣谢

你可能感兴趣的:(单片机拓展模块讲解)