DS1302实时时钟

1.介绍
DS1302是一种串行接口的实时时钟,芯片内部具有可编程的日历时钟和31个字节的静态RAM。
2.内部结构请添加图片描述
(1)SCLK:串行时钟输入端,控制数据输入与输出。
(2)I/O:双向输入线
(3)CE:使能端,CE为高时允许DS1302读写数据,CE端为低时DS1302数据不可读写
(4)X1与X2:外接32.768的圆形晶振,给时钟芯片提供晶振频率。
3.时钟日历控制寄存器
请添加图片描述
(1)秒寄存器(0X81,0X80): 当CH=1秒位停止关闭。
(2)小时寄存器(0x85,0x84):当BIT7为1时为12小时制,当BIT7为0时为24小时制。
(3)控制寄存器(0x8f,0x8e):当WP为1时,不能对Ds1302做任何操作。
4.DS130231字节的RAM寄存器
请添加图片描述
就是断电后仍然存在的数据区域
5.DS1302的工作模式寄存器
请添加图片描述
突发模式就是一次性转输多个字节的的数据到时钟或RAM
6.DS1320的通信时序
(1)从最低位开始
(2)读写数据:都是CE端由低到高,然后前8位,写命令字节,后8位,写数据字节。(上升沿时为写入,下降沿时为读出)
7.BCD码转换
(1)解释
因为我们时间是按一位一位来记录的,例如个位秒,十位秒,个位分…
所以我们用4位2进制就可以表示0-9的数字,(即8421任意选择加)
所以8421为 0000 0000,前四位表示10位,后四位表示个位
(2)BCD转8421码(BCD码)
例如45这个十进制数,先把十位与个位分开得到4与5,4是属于高四位的所以要再乘与16到高四位,所以45 = 416+5= 69 = 0100 0101
(3)8421转BCD码
如69这个8421码,先69/16得到高四位的值为4,再69%16得到低四位的值5,然后4
10+5=45,就是十进制数。

#include <reg52.h> 
#include <intrins.h>
sbit LA=P2^2;
sbit LB=P2^3;
sbit LC=P2^4;
sbit TSCLK = P3^6;     //时钟线
sbit TIO = P3^4;       //数据线
sbit TRST = P3^5;       //CE端,使能
//以下为显示函数
unsigned int miao;
unsigned char smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
					0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
void delay2(unsigned int z)    
{
	unsigned int x,y;
	for(x=z;x>0;x--)
	   for(y=120;y>0;y--);
}
void timefrist()
{
	EA = 1;
	ET0 = 1;
	TR0 = 1;
	TMOD |= 0x01;
	TH0 = 0xED;
	TL0 = 0xFF;
}
void DigDisplay(unsigned int h)
{
	unsigned int a = h % 60 % 10;
	unsigned int b = h % 60 / 10;
	unsigned int c = h / 60 % 10;
	unsigned int d = h / 60 / 10;
	static unsigned char wei=0;
	switch(wei)
	{
		case 0: LA=1;LB=1;LC=1;P0 = smgduan[d];break;
		case 1:	LA=0;LB=1;LC=1;P0 = smgduan[c];break;
		case 2: LA=1;LB=0;LC=1;P0 = smgduan[b];break;
		case 3: LA=0;LB=0;LC=1;P0 = smgduan[a];break;
	}
	wei++;
	if(wei==4)
	{
		wei = 0;
	}
}
void timer0() interrupt 1
{
	 TH0 = 0xED;
	 TL0 = 0xFF;
	 DigDisplay(miao);
}
//以下为时钟函数
//写入数据
unsigned char Write_DS1302_DAT(unsigned char cmd,unsigned char dat)
{
	unsigned  char i;
	TRST = 0;
	TSCLK = 0;
	
	TRST = 1;     //CE端产生上升沿启动读写
	for(i=0;i<8;i++)
	{
		TSCLK = 0;
		TIO = cmd & 0x01;  //由最低位开始
		TSCLK = 1;       //产生上升沿,直接写入数据
		cmd >>= 1;       //数据不断左移,把最低位提上
	}
	for(i=0;i<8;i++)
	{
		TSCLK = 0;
		TIO = dat & 0x01;
		TSCLK = 1;
		dat >>= 1;
	}
	
}
//读数据
char Read_DS1302_DAT(unsigned char cmd)
{
	unsigned char i,dat;
	TRST = 0;
	TSCLK = 0;
	TRST = 1;         //CE端拉高,启动读或写
	for(i=0;i<8;i++)    //写入指命,找位置与功能
	{
		TSCLK = 0;
		TIO = cmd & 0x01;
		TSCLK = 1;
		cmd >>= 1;
	}
	for(i=0;i<8;i++)  
	{
		TSCLK = 0;  //前面TSCLK已经被拉高了,现在拉低,数据读出
		dat >>= 1;  //数据右移动
		if(TIO) dat |= 0x80;  //转出数据为高电平,就最高位加一然后不断右移动到最低位
		TSCLK = 1;  //重新拉高回来
	}
	return dat; //返回数据
}
//10位变BCD
unsigned char Dat_Chg_BCD(unsigned char dat)
{
	unsigned char dat1,dat2;
	dat1 = dat /10;
  dat2 = dat % 10;
	dat2 = dat1*16 + dat2;
  return dat2;	
}
//BCD为10位
unsigned char BCD_Chg_Dat(unsigned char dat)
{
	unsigned char dat1,dat2;
	dat1 = dat / 16;
	dat2 = dat2 %16;
	dat2 = dat2 + dat1*10;
	return dat2;
}
void main()
{
	unsigned char a,b,c;
	timefrist();
	Write_DS1302_DAT(0x8e,0);               //打开0x8e上WE置位为0
	Write_DS1302_DAT(0x80,Dat_Chg_BCD(10)); //写秒0x80指命,后写入数据
	Write_DS1302_DAT(0x82,Dat_Chg_BCD(50)); //写秒0x82指命,后写入数据
	Write_DS1302_DAT(0x84,Dat_Chg_BCD(11)); //写秒0x84指命,后写入数据
	Write_DS1302_DAT(0x8e,0x80);         //打开0x8e上WE置位为1,不可读写
	while(1)
	{
		Write_DS1302_DAT(0x8e,0); //打开0x8e上WE置位为0
		a = BCD_Chg_Dat(Read_DS1302_DAT(0x81));//读取指命0x81,时间秒
		b = BCD_Chg_Dat(Read_DS1302_DAT(0x83));//读取指命0x83,时间秒
		c = BCD_Chg_Dat(Read_DS1302_DAT(0x85));//读取指命0x85,时间秒
		Write_DS1302_DAT(0x8e,0x80); 打开0x8e上WE置位为1,不可读写
		miao = a + b*60;  //这里只用到了秒与分,全部化为秒后给全局变量
		delay2(1000);
	}
}
  • 10
    点赞
  • 110
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值