51单片机控制ds1302时钟模块

本文主要参考ds1302中文技术手册

引脚接入:

CLK P2^7 
DAT P2^6 
RST P2^5 

原理图剖析

在这里插入图片描述
ds1302的原理图很简单很好理解,X1、X2接入晶振给模块提供振荡电路;VCC2作为供电电源、VCC1作为备用电源在VCC2不供电的时候保持续航;SCLK是时钟引脚、DAT(IO)是数据交流引脚、RST(CE)是复位引脚。

注意:RST置1才允许数据交流,但RST置1之前要先保证CLK为1。

时钟\控制寄存器

在这里插入图片描述
在代码中,我们实际需要用到的有:控制寄存器(control)、秒、分、时、日、月、年(sec、min、hr、day、month、year)。研究这些寄存器的字节数据可以发现,无非是7位实际地址+1位读写位的形式。控制寄存器的主要功能是是否禁用写保护,也就是在要进行写入数据的时候要先设置控制寄存器为0x00,写完后设置为0x80。

写地址{0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c}
读地址{0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d}

时序

在这里插入图片描述
可以看到,一个周期内,要先进行寄存器地址的写入,再进行读或者写。周期内读的话,就是RST为高电平,CLK下降沿读入一个数据;写的话,就是RST为高电平,CLK上升沿写入一个新数据。但在实际操作中,我读和写都是在下降沿才能成功,这就很无语。

代码

ds1302.c

#include "ds1302.h"

sbit CLK=P2^7;
sbit DAT=P2^6;
sbit RST=P2^5;

void ds1302_write(u8 addrs,u8 datas)
{
	u8 i = 0;
	RST = 0;
	_nop_();
	
	CLK = 0;//只有在SCLK为低电平时,才能将RST置为高电平
	_nop_();
	RST = 1;//RST为高,允许数据交换
	_nop_();
	
	for(i=0;i<=7;i++)
	{
		DAT = addrs & 0x01;
		addrs = addrs>>1; 
		CLK = 1;
		_nop_();
		
		CLK = 0;
		_nop_();
	
	}
	
	for(i=0;i<=7;i++)
	{
		DAT = datas & 0x01;
		datas = datas>>1; 
		CLK = 1;
		_nop_();
		
		CLK = 0;
		_nop_();
	}
	
	RST = 0;//RST为低,结束数据传输
	_nop_();
}


u8 ds1302_read(u8 addrs)
{
	u8 ret = 0,i =0,datas = 0;
	
	RST = 0;
	_nop_();
	
	CLK = 0;//只有在SCLK为低电平时,才能将RST置为高电平
	_nop_();
	RST = 1;//RST为高,允许数据交换
	_nop_();
	
	for(i=0;i<=7;i++)
	{
		DAT = addrs & 0x01;
		addrs = addrs>>1; 
		CLK = 1;
		_nop_();
		
		CLK = 0;
		_nop_();
	}
	_nop_();
	
	for(i=0;i<=7;i++)
	{
		datas = DAT;
		ret = (ret>>1)|(datas<<7);
		CLK = 1;
		_nop_();
		
		CLK = 0;
		_nop_();
	}
	
	RST = 0;//RST为低,结束数据传输
	_nop_();
	
	return ret;
}

void ds1302_init(u8 *times)
{
	//秒分时日月周年     
	u8 code addrs[7] = {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c};
	u8 i =0;
	
	ds1302_write(0x8E,0x00);//关闭写保护,这样才能写入数据
	for(i=0;i<7;i++)
		ds1302_write(addrs[i],times[i]);
	ds1302_write(0x8E,0x80);//打开写保护
}



void time_read(u8 *times,u8 *display_data)
{
	u8 n = 0;
	u8 code addrs[7] = {0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d}; 
	for (n=0; n<7; n++)//读取7个字节的时钟信号:分秒时日月周年
	{
		times[n] = ds1302_read(addrs[n]);
	}
	datapros(times,display_data);
}

ds1302.h

#ifndef __DS1302__H
#define __DS1302__H

#include "reg52.h"
#include "delay.h"
#include "datapros.h"

void ds1302_init(u8 *times);
void time_read(u8 *times,u8 *display_data);

#endif
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值