51单片机—DS1302

DS1302

典型工作电路

命令字

图中显示的是命令字.命令字启动每一次数据传输. MSB (位 7)必须是逻辑 1. 如果是 0,则禁止对 DS1302写入. 位 6 在逻辑 0时规定为时钟/日历数据,逻辑 1时为 RAM数据.

位 1 至 位 5 表示了输入输出的指定寄存器.LSB (位 0) 在逻辑0时为写操作(输出),逻辑1时为读操作(输入).命令字以 LSB (位 0)开始总是输入.

CE 与时钟控制

所有数据传输开始驱动 CE输入高.CE输入实现两个功能.第一, CE 开启允许对地址/命令序列的移位寄存器进行读写的控制逻辑. 第二 CE 信号为单字节和多字节 CE数据传输提供了终止的方法.

一个时钟周期是一系列的上升沿伴随下降沿.要输入数据在时钟的上升沿数据必须有效,而且在下降沿要输出数据位.如果 CE输入为低电平,则所有数据传输终止,并且 I/O 口成高阻抗状态.图 4 显示了数据传输. 在上电时, CE必须为逻辑 0直到 VCC 大于 2.0V. 同样, SCLK 必须为逻辑 0当 CE 变成逻辑 1状态

数据输入

输入写命令字的 8个 SCLK周期后,接下来的 8个 SCLK 周期的上升沿数据字节被输入。如不慎发生, 多余的 SCLK 周期将被忽略,数据输入以位 0开始. 

数据输出

输入读命令字的 8个 SCLK周期后, 随后的 8个 SCLK 周期的下降沿,一个数据字节被输出。注意第一个数据位的传送发生在命令字节被写完后的第一个下降沿.
 

写保护位 

控制寄存器的位 7是写保护位,前 7位(位 0至位 6)被强制为 0且读取时总是读 0. 在任何对时钟或 RAM的写操作以前,位 7必须为 0.当为高时,写保护位禁止任何寄存器的写操作. 初始加电状态未定义. 因此,在试图写器件之前应该清除 WP位.
 

DS1302_Init();
DS1302_WriteByte(0x8E,0x00); //清楚WP位

时钟/日历
 

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

BCD
 

 BCD码(Binary Coded Decimal‎),用4位二进制数来表示1位十进制数

 例:0001 0011表示131000 0101表示850001 1010不合法

 在十六进制中的体现:0x13表示130x85表示850x1A不合法

 BCD码转十进制:DEC=BCD/16*10+BCD%16;2BCD

 十进制转BCD码:BCD=DEC/10*16+DEC%10;2BCD

数据传输摘要 

 

 寄存器地址/定义

 

 


 代码实现

#include <REGX51.H>

sbit DS1302_SCLK = P3^6;
sbit DS1302_IO = P3^4;
sbit DS1302_CE = P3^5;

#define DS1302_SECOND  0x80        //寄存器写入秒的地址
#define DS1302_MINUTE  0x82		   //寄存器写入分钟的地址
#define DS1302_HOUR    0x84        //寄存器写入小时的地址
#define DS1302_DATA    0x86        //寄存器写入日的地址
#define DS1302_MONTH   0x88        //寄存器写入月份的地址
#define DS1302_DAY     0x8A        //寄存器写入星期的地址
#define DS1302_YEAR    0x8C        //寄存器写入年的地址
#define DS1302_WP      0x8E        //寄存器写保护位的地址

unsigned char DS1302_Time[] = {24,4,25,19,18,30,4};

void DS1302_Init(void)  //时钟芯片开始默认CE和SCLK为0,但单片机上电所有IO口置1,所以需要手动初始化
{
	DS1302_CE = 0;
	DS1302_SCLK = 0;
}

unsigned char DS1302_ReadByte(unsigned char Command)
{
	unsigned char i,Data = 0x00;
	Command |= 0x01;  //将寄存器写的地址改为读的地址
	DS1302_CE = 1;
	for (i=0;i<8;i++)
	{
		DS1302_IO = Command & (0x01 << i);
		DS1302_SCLK = 0;
		DS1302_SCLK = 1;
	}
	for (i=0;i<8;i++)
	{
		DS1302_SCLK = 1; //重复置一次1让时序保持一致
		DS1302_SCLK = 0;
		if (DS1302_IO) 
			Data |= (0x01 << i);
	}
	DS1302_CE = 0;
	DS1302_IO = 0; //读取后将数据IO置0,否则读出的数据会出错
	return Data;
}

void DS1302_WriteByte(unsigned char Command,Data)
{
	unsigned char i;
	DS1302_CE = 1;
	for (i=0;i<8;i++)
	{
		DS1302_IO = Command & (0x01 << i);
		DS1302_SCLK = 1;
		DS1302_SCLK = 0;
	}
	for (i=0;i<8;i++)
	{
		DS1302_IO = Data & (0x01 << i);
		DS1302_SCLK = 1;
		DS1302_SCLK = 0;
	}
	DS1302_CE = 0;
}

void DS1302_ReadTime(void)
{
	//把DS1302现在的时间放到Time数组中去
	unsigned char temp;
	temp = DS1302_ReadByte(DS1302_YEAR);
	DS1302_Time[0] = temp/16*10+temp%16; //将BCD转换成10进制数
	temp = DS1302_ReadByte(DS1302_MONTH);
	DS1302_Time[1] = temp/16*10+temp%16;
	temp = DS1302_ReadByte(DS1302_DATA);
	DS1302_Time[2] = temp/16*10+temp%16;
	temp = DS1302_ReadByte(DS1302_HOUR);
	DS1302_Time[3] = temp/16*10+temp%16;
	temp = DS1302_ReadByte(DS1302_MINUTE);
	DS1302_Time[4] = temp/16*10+temp%16;
	temp = DS1302_ReadByte(DS1302_SECOND);
	DS1302_Time[5] = temp/16*10+temp%16;
	temp = DS1302_ReadByte(DS1302_DAY);
	DS1302_Time[6] = temp/16*10+temp%16;
}

void DS1302_SetTime(void)
{
	//Time数组中存放的是十进制数,而设置数据进DS1302中的数据是BCD数,所以要进行数据转换
	DS1302_WriteByte(DS1302_WP,0x00);  //清楚WP位
	DS1302_WriteByte(DS1302_YEAR,DS1302_Time[0]/10*16+DS1302_Time[0]%10);
	DS1302_WriteByte(DS1302_MONTH,DS1302_Time[1]/10*16+DS1302_Time[1]%10);
	DS1302_WriteByte(DS1302_DATA,DS1302_Time[2]/10*16+DS1302_Time[2]%10);
	DS1302_WriteByte(DS1302_HOUR,DS1302_Time[3]/10*16+DS1302_Time[3]%10);
	DS1302_WriteByte(DS1302_MINUTE,DS1302_Time[4]/10*16+DS1302_Time[4]%10);
	DS1302_WriteByte(DS1302_SECOND,DS1302_Time[5]/10*16+DS1302_Time[5]%10);
	DS1302_WriteByte(DS1302_DAY,DS1302_Time[6]/10*16+DS1302_Time[6]%10);
	DS1302_WriteByte(DS1302_WP,0x00); //开启写保护位
}




 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值