ds1302

ds1302

注意事项

在日历/时钟寄存器中都是以 BCD 码存放数据,往相关寄存器中写入数据时先要转化为BCD码格式在进行写入;读取数据时,读到的是BCD码,使用时需要转化为相应的十进制或十六进制;

注: 在操作 DS1302 之前关闭写保护;不然指令无法进入控制寄存器;

ds1302

​ DS1302 有一个控制寄存器、12 个日历、时钟寄存器和 31 个 RAM。

​ DS1302是一种低功耗实时时钟芯片,实时时钟计算年、月、日、时、分、秒、星期,直到 2100 年,并有闰年调节功能。每月的天数和闰年的天数可自动调整。时钟操作可通过 AM/PM 指示决定采用 24 或 12 小时格式。DS1302 与 单片机之间能简单地采用同步串行的方式进行通信,仅需用到三根通信线:1、CE使能线;2、I/O 数据线;3、SCLK 串行时钟线;

晶振

​ 一个 32.768kHz 晶振可以通过管脚2和3(X1,X2)直接连接到DS1302

管脚

在这里插入图片描述

管脚名称功能
1VCC2双供电配置中的主电源供应管脚(单片机供电);
2X1DS1302 外部晶振引脚,通常需外接 32.768K 晶振;
3X2DS1302 外部晶振引脚,通常需外接 32.768K 晶振;
4GND电源地;
5CE使能引脚,也是复位引脚,CE信号在读写时必须保持高电平;
6I/O串行数据引脚,数据输出或者输入
7SCLK串行数据引脚
8VCC1备用电源

控制寄存器

​ 控制寄存器用于存放 DS1302 的控制命令字,DS1302 的CE引脚回到高电平后写入的第一个字节就为控制命令。它用于对 DS1302 读写过程进行控制:

​ 每一次启动数据传输. MSB (位 7)必须是逻辑1,如果是 0,则禁止对DS1302写入;位 6 在逻辑0时规定为时钟/日历数据,逻辑1时为RAM数据;位 1 至 位 5 表示了输入输出的指定寄存器,LSB (位 0) 在逻辑0时为写操作(输出),逻辑1时为读操作(输入);控制寄存器以LSB (位 0)开始总是输入

在这里插入图片描述

控制命令

​ 读取适当的寄存器字节可以得到时间和日历信息

​ 写入适当的寄存器字节可以设置或初始化时间和日历

时间和日历寄存器的内容是二进制编码的十进制(BCD)格式的

在这里插入图片描述

秒寄存器:低四位为秒的个位,高的次三位为秒的十位。最高位 CHDS1302 的运行标志,当 CH=0 时,DS1302 内部时钟运行,反之 CH=1 时停止 ;

数据格式

在这里插入图片描述

时寄存器:最高位为 12/24 小时的格式选择位,该位为 1 时 表示 12 小时格式。当设置为 12 小时显示格式时,第 5 位的高电平表示下午 (PM);而当设置为 24 小时格式时,第 5 位位具体的时间数据;

**写保护寄存器:**当该寄存器最高位 WP 为 1 时,DS1302 只读不写,所以要在往 DS1302 写数据之前确保 WP 为0;

读写时序在这里插入图片描述

电气特性(延时)

在这里插入图片描述

CE(RST):复位时序,即在RST引脚产生一个正脉冲,在整个读写器件, RST要保持高电平,一次字节读写完毕之后,要注意把RST返回低电平准备下次读写周期;

**单字节写入:**在CE为高电平后,SCLK会输出周期脉冲,每一个上升沿,IO线的数据就会进入控制寄存器,当控制寄存器配置完成(为写入数据,并且地址已给),紧接着的脉冲IO线的数据就会在上升沿进入对应地址的寄存器;

**单字节读出:**在CE为高电平后,SCLK会输出周期脉冲,每一个上升沿,IO线的数据就会进入控制寄存器,当控制寄存器配置完成(为读出数据,并且地址已给),紧接着对应地址的寄存器的数据就会在下降沿进入IO线;

//管脚定义
sbit DS1302_RST=P3^5;//复位管脚
sbit DS1302_CLK=P3^6;//时钟管脚
sbit DS1302_IO=P3^4 ;//数据管脚

//变量声明
extern u8 gDS1302_TIME[7];//存储时间

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

//---DS1302时钟初始化2021年5月20日星期四13点51分47秒。---//
//---存储顺序是秒分时日月周年,存储格式是用BCD码---//
u8 gDS1302_TIME[7] = {0x47, 0x51, 0x13, 0x20, 0x04, 0x05, 0x21};


//函数声明
void ds1302_init(void);
void ds1302_read_time(void);

/*******************************************************************************
* 函 数 名       : ds1302_write_byte
* 函数功能		 : DS1302写单字节
* 输    入       : addr:地址/命令
				   dat:数据
* 输    出    	 : 无
*******************************************************************************/
void ds1302_write_byte(u8 addr,u8 dat)
{
	u8 i=0;
	
	DS1302_RST=0;
	;	
	DS1302_CLK=0;//CLK低电平
	;
	DS1302_RST=1;//RST由低到高变化
	;

	for(i=0;i<8;i++)//循环8次,每次写1位,先写低位再写高位
	{
		DS1302_IO=addr&0x01;
		addr>>=1;
		DS1302_CLK=1;
		;
		DS1302_CLK=0;//CLK由低到高产生一个上升沿,从而写入数据
		;		
	}
	for(i=0;i<8;i++)//循环8次,每次写1位,先写低位再写高位
	{
		DS1302_IO=dat&0x01;
		dat>>=1;
		DS1302_CLK=1;
		;
		DS1302_CLK=0;
		;		
	}
	DS1302_RST=0;//RST拉低
	;	
}
/*******************************************************************************
* 函 数 名       : ds1302_read_byte
* 函数功能		 : DS1302读单字节
* 输    入       : addr:地址/命令
* 输    出    	 : 读取的数据
*******************************************************************************/
u8 ds1302_read_byte(u8 addr)
{
	u8 i=0;
	u8 temp=0;
	u8 value=0;
   // uart_init(0XFA);

	DS1302_RST=0;
	;	
	DS1302_CLK=0;//CLK低电平
	;
	DS1302_RST=1;//RST由低到高变化
	;
	
	for(i=0;i<8;i++)//循环8次,每次写1位,先写低位再写高位
	{
		DS1302_IO=addr&0x01;
		addr>>=1;	
		DS1302_CLK=1;
		;
		DS1302_CLK=0;//CLK由低到高产生一个上升沿,从而写入数据
		;		
	}
	for(i=0;i<8;i++)//循环8次,每次读1位,先读低位再读高位
	{
		temp=DS1302_IO;
		value=(temp<<7)|(value>>1);//先将value右移1位,然后temp左移7位,最后或运算
		DS1302_CLK=1;
		;
		DS1302_CLK=0;
		;		
	}
//	DS1302_RST=0;//RST拉低,当DS1302与DS18B20同时使用时,注释掉该调语句
	;	
	DS1302_CLK=1;//对于实物中,P3.4口没有外接上拉电阻的,此处代码需要添加,使数据口有一个上升沿脉冲。
	;
	DS1302_IO = 0;
	;
	DS1302_IO = 1;
	;	
    
  //  SBUF=value;
	return value;		
}

/*******************************************************************************
* 函 数 名       : ds1302_init
* 函数功能		 : DS1302初始化时间
* 输    入       : 无
* 输    出    	 : 无
*******************************************************************************/
void ds1302_init(void)
{
	u8 i=0;
	ds1302_write_byte(0x8E,0X00);//关闭写保护
	for(i=0;i<7;i++)
	{
		ds1302_write_byte(gWRITE_RTC_ADDR[i],gDS1302_TIME[i]);	
	}
	ds1302_write_byte(0x8E,0X80);	//打开写保护
}

/*******************************************************************************
* 函 数 名       : ds1302_read_time
* 函数功能		 : DS1302读取时间
* 输    入       : 无
* 输    出    	 : 无
*******************************************************************************/
void ds1302_read_time(void)
{
	u8 i=0;
	for(i=0;i<7;i++)
	{
		gDS1302_TIME[i]=ds1302_read_byte(gREAD_RTC_ADDR[i]);	
	}	
}
  • 17
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值