ds1302时钟芯片工作原理

ds1302时钟芯片工作原理,第1张

ds1302时钟芯片工作原理:用单片机从DS1302中读取时间,将复位脚(RST)置为高电平且将8位地址和命令信息装入移位寄存器。

DS1302是美国DALLAS公司推出的一种高性能、低功耗、带RAM的实时时钟,有计时的作用,和日常接触的电子表,万年历差不多,可以对年月日、时分秒、星期计时。

可以用单片机往DS1302里面写入时间进行时间设置,也可以用单片机从DS1302中读取时间,读出来的时间也可以放在液晶上显示。这样就可以实现一块电子表的功能了。

DS1302工作时为了对任何数据传送进行初始化,需要将复位脚(RST)置为高电平且将8位地址和命令信息装入移位寄存器。数据在时钟(SCLK)的上升沿串行输入,前8位指定访问地址,命令字装入移位寄存器后,在之后的时钟周期,读 *** 作时输出数据,写 *** 作时输出数据。

时钟脉冲的个数在单字节方式下为8+8(8位地址+8位数据),在多字节方式下为8加最多可达248的数据。

ds1302芯片介绍

DS1302是美国DALLAS公司推出的一种高性能、低功耗的实时时钟芯片,附加31字节静态RAM,采用SPI三线接口与CPU进行同步通信,并可采用突发方式一次传送多个字节的时钟信号和RAM数据。

实时时钟可提供秒、分、时、日、星期、月和年,一个月小与31天时可以自动调整,且具有闰年补偿功能。

工作电压宽达25~55V。采用双电源供电,可设置备用电源充电方式,提供了对后背电源进行涓细电流充电的能力。DS1302用于数据记录,特别是对某些具有特殊意义的数据点的记录上,能实现数据与出现该数据的时间同时记录,因此广泛应用于测量系统中。

#include <reg52h>sbit T_CLK = P2^4; /实时时钟时钟线引脚 /

sbit T_IO = P2^3; /实时时钟数据线引脚 /

sbit T_RST = P2^2; /实时时钟复位线引脚 /

sbit ACC0=ACC^0;

sbit ACC7=ACC^7;

sbit rs=P2^0;

sbit rw=P2^1;

sbit e=P2^7;

sbit setd=P3^2;

sbit sett=P3^3;

sbit add=P2^5;

sbit enter=P2^6;

sbit speaker=P3^7;

unsigned char code tab[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};

void v_RTInputByte(unsigned char ucDa)

{

unsigned char i;

ACC = ucDa;

for(i=8; i>0; i--)

{

T_IO = ACC0; /相当于汇编中的 RRC /

T_CLK = 1;

T_CLK = 0;

ACC = ACC >> 1;

}

}

unsigned char uc_RTOutputByte(void)

{

unsigned char i;

for(i=8; i>0; i--)

{

ACC = ACC >>1; /相当于汇编中的 RRC /

ACC7 = T_IO;

T_CLK = 1;

T_CLK = 0;

}

return(ACC);

}

void v_W1302(unsigned char ucAddr, unsigned char ucDa)

{

T_RST = 0;

T_CLK = 0;

T_RST = 1;

v_RTInputByte(ucAddr); / 地址,命令 /

v_RTInputByte(ucDa); / 写1Byte数据/

T_CLK = 1;

T_RST =0;

}

unsigned char uc_R1302(unsigned char ucAddr)

{

unsigned char ucDa;

T_RST = 0;

T_CLK = 0;

T_RST = 1;

v_RTInputByte(ucAddr); / 地址,命令 /

ucDa = uc_RTOutputByte(); / 读1Byte数据 /

T_CLK = 1;

T_RST =0;

return(ucDa);

}

void v_BurstW1302T(unsigned char pSecDa)

{

unsigned char i;

v_W1302(0x8e,0x00); / 控制命令,WP=0,写 *** 作/

T_RST = 0;

T_CLK = 0;

T_RST = 1;

v_RTInputByte(0xbe); / 0xbe:时钟多字节写命令 /

for (i=8;i>0;i--) /8Byte = 7Byte 时钟数据 + 1Byte 控制/

{

v_RTInputByte(pSecDa);/ 写1Byte数据/

pSecDa++;

}

T_CLK = 1;

T_RST =0;

}

void v_BurstR1302T(unsigned char pSecDa)

{

unsigned char i;

T_RST = 0;

T_CLK = 0;

T_RST = 1;

v_RTInputByte(0xbf); / 0xbf:时钟多字节读命令 /

for (i=8; i>0; i--)

{

pSecDa = uc_RTOutputByte(); / 读1Byte数据 /

pSecDa++;

}

T_CLK = 1;

T_RST =0;

}

void v_BurstW1302R(unsigned char pReDa)

{

unsigned char i;

v_W1302(0x8e,0x00); / 控制命令,WP=0,写 *** 作/

T_RST = 0;

T_CLK = 0;

T_RST = 1;

v_RTInputByte(0xfe); / 0xbe:时钟多字节写命令 /

for (i=31;i>0;i--) /31Byte 寄存器数据 /

{

v_RTInputByte(pReDa); / 写1Byte数据/

pReDa++;

}

T_CLK = 1;

T_RST =0;

}

void v_BurstR1302R(unsigned char pReDa)

{

unsigned char i;

T_RST = 0;

T_CLK = 0;

T_RST = 1;

v_RTInputByte(0xff); / 0xbf:时钟多字节读命令 /

for (i=31; i>0; i--) /31Byte 寄存器数据 /

{

pReDa = uc_RTOutputByte(); / 读1Byte数据 /

pReDa++;

}

T_CLK = 1;

T_RST =0;

}

void v_setd1302(unsigned char pSecDa)

{

unsigned char i;

unsigned char ucAddr = 0x80;

v_W1302(0x8e,0x00); / 控制命令,WP=0,写 *** 作/

for(i =7;i>0;i--)

{

v_W1302(ucAddr,pSecDa); / 秒 分 时 日 月 星期 年 /pSecDa++;

ucAddr +=2;

}

v_W1302(0x8e,0x80); / 控制命令,WP=1,写保护/

}

void delay()

{ unsigned char x,y ;

for(y=0;y<0xff;y++)

for(x=0;x<2;x++)

{;}

}// void wc51r(unsigned char j)//写命令

{

e=0;rs=0;rw=0;

e=1;

P1=j;

e=0;

delay();

}void init()//初始化

{

wc51r(0x01);

wc51r(0x38);

wc51r(0x38);

wc51r(0x0e);

wc51r(0x06);

wc51r(0x0c);

}

void wc51ddr(unsigned char j)//写数据

{

e=0;rs=1;rw=0;

e=1;

P1=j;

e=0;

delay();

}void write1602(unsigned char add,unsigned char da)//写入显示数据

{wc51r(add);wc51ddr(da);}

void main(void)

{

unsigned char ucCurtime[7];

unsigned char i,yearh,yearl,monh,monl,dah,dal,hoh,hol,mih,mil,seh,sel;

unsigned char ucAddr;

unsigned int c;EA=1;init();

write1602(0x85,0x35);

for(c=0;c<30000;c++);

write1602(0x86,0x32);

for(c=0;c<30000;c++);

write1602(0x87,0x4D);

for(c=0;c<30000;c++);

write1602(0x88,0x43);

for(c=0;c<30000;c++);

write1602(0x89,0x55);

for(c=0;c<30000;c++);

/write1602(0xC2,0x51);

write1602(0xC3,0x51);

write1602(0xC4,0x3A);

write1602(0xC5,0x35);

write1602(0xC6,0x39);

write1602(0xC7,0x37);

write1602(0xC8,0x33);

write1602(0xC9,0x38);

write1602(0xCA,0x35);

write1602(0xCB,0x33);

write1602(0xCC,0x36);

write1602(0xCD,0x39);

for(c=0;c<50000;c++);

init();//LCD初始化 / TMOD=0X20;

TH1=0XF3;

TL1=0XF3;

SCON=0X50;

PCON=0X00;

IT0=1;

EX0=1;

IT1=1;

EX1=1;

TR1=1;

// EA=1;

ES=1;

while(1)

{ucAddr = 0x81;<br>for (i=0;i<7;i++)<br>{<br>ucCurtime[i] = uc_R1302(ucAddr);/格式为: 秒 分 时 日 月 星期 年 /<br>ucAddr += 2;<br>}

yearh=ucCurtime[6]/16;

yearl=ucCurtime[6]%16;

monh=ucCurtime[4]/16;

monl=ucCurtime[4]%16;

dah=ucCurtime[3]/16;

dal=ucCurtime[3]%16;hoh=ucCurtime[2]/16;

hol=ucCurtime[2]%16;

mih=ucCurtime[1]/16;

mil=ucCurtime[1]%16;

seh=ucCurtime[0]/16;

sel=ucCurtime[0]%16;//EA=1;write1602(0x80,0x44);

write1602(0x81,0x61);

write1602(0x82,0x74);

write1602(0x83,0x65);

write1602(0x84,0x3a);//显示date:write1602(0x85,tab[yearh]);

write1602(0x86,tab[yearl]);

write1602(0x87,0x2d);//显示年

write1602(0x88,tab[monh]);

write1602(0x89,tab[monl]);

write1602(0x8a,0x2d);//显示月

write1602(0x8b,tab[dah]);

write1602(0x8c,tab[dal]);write1602(0xc0,0x54);

write1602(0xc1,0x69);

write1602(0xc2,0x6d);

write1602(0xc3,0x65);

write1602(0xc4,0x3a);//显示time:write1602(0xc5,tab[hoh]);

write1602(0xc6,tab[hol]);

write1602(0xc7,0x3a);//显示小时

write1602(0xc8,tab[mih]);

write1602(0xc9,tab[mil]);

write1602(0xca,0x3a);//显示小时

write1602(0xcb,tab[seh]);

write1602(0xcc,tab[sel]);EA=0;

/if((ucCurtime[1]==0)&(ucCurtime[0]==0|ucCurtime[0]==1|ucCurtime[0]==2))//3秒整点报时

speaker=0;

else speaker=1; /}

}//

serint() interrupt 4

{// EA=0;

static unsigned char k;

unsigned char temp,year,month,date,hour,min,sec,week;

unsigned char stemp[7]={0};

RI=1;

temp=SBUF;

RI=0;

k++;

switch (k)

{ case 1:sec=temp;

break;

case 2:min=temp;

break;

case 3:hour=temp;

break;

case 4:date=temp;

break;

case 5:month=temp;

break;

case 6:week=temp;

break;

case 7:year=temp; k=0;

break;

stemp[0]=(sec/10)16+sec%10;

stemp[1]=(min/10)16+min%10;

stemp[2]=(hour/10)16+hour%10;

stemp[3]=(date/10)16+date%10;

stemp[4]=(month/10)16+month%10;

stemp[5]=(week/10)16+week%10;

stemp[6]=(year/10)16+year%10;

v_setd1302(stemp);//设定值

}

}

#include"DS1302h"

#include <at89x52h>

/DS1302

寄存器命令字(读,写)取值范围各位内容(7~0)

读写

秒80H81H00~59CH(7)10SEC(6~4)SEC(3~0)

分82H83H00~590(7)10MIN(6~4)MIN(3~0)

时84H85H 00~12 00~2412/24(7)0(6)10/AP(5~4) HR(3~0)

日86H87H01~28,29,39,310(7),0(6),10DATE(5~4)DATE(3~0)

月88H89H01~120(7),0(6),0(5),10M(4),MONTH(3~0)

星期8AH8BH01~070(7),0(6),0(5),0(4),DAY(3~0)

年8CH8DH01~9919YEAE(7~4)YEAR(3~0)

写保护8EH8FHWP(7),0(6),0(5),0(4),0(3~0)

慢充电90H91HTCS(7),TCS(6),TCS(5),TCS(4),DS(3),DS(2),RS(1),RS(0)

时钟突发BEHBFH//读写秒,分,时,日,月,周,年,写保护,8字节一个

RAM突发FEHFFH//读写31B的RAM,可以不以8字节为单位

CH时钟开关,0开1关

12/241先12小时,2选24小时,12小时下,位5为AM/PM选择位,此位1表PM,24小时下,位5是第二个小时位(20~23)

WP写保护位,0,允许,1,禁止

TCS1010才允许充电

DS二极管选择位 01 一个10两个00,11禁止

RS选择连接在VCC1,VCC2之间的电阻,00禁止01 2K104K118K

/

uchar DateTime[8]={0x05,0x02,0x04,0x13,0x06,0x02,0x99,0x00};

//分别为 秒,分,时,日,月,周,年,写保护

//uchar DateTime[8]={0x05,0x03,0x04,0x

/

函数名称:DS1302写入命令函数

功能描述:将命令写入DS1302

全局变量:无

参数说明:Command为要写入的命令

返回说明:

版本:10

说明:

/

void WriteCommand(uchar Command)

{

uchar i;

RST=0;CLK=0;RST=1;

for(i=8;i>0;i--)//发送命令字

{

CLK=0;

DP=Command&0x01;//取一位送数据口

CLK=1;//产生一个上升沿

Command>>=1;

}

}

/

函数名称:DS1302写入数据函数

功能描述:将数据写入DS1302

全局变量:无

参数说明:SendDat为要写入的命令

返回说明:

版本:10

说明:

/

void WriteData(uchar SendDat)

{

uchar i;

for(i=8;i>0;i--)//发送数值

{

CLK=0;

DP=SendDat&0x01;

CLK=1;

SendDat>>=1;

}

}

/

函数名称:DS1302读取数据函数

功能描述:从DS1302读取数据

全局变量:无

参数说明:

返回说明:返回读取的一个字节数据

版本:10

说明:

/

uchar ReadData(void)

{

uchar i,RecDat=0;

for(i=0;i<8;i++)//读入数值

{

CLK=1;CLK=0;//产生一个下降沿

if(DP)RecDat|=0x01<<i;//读入数据

}

return RecDat;

}

/

函数名称:DS1302向某地址单字写函数

功能描述:向某地址写入数据

全局变量:无

参数说明:Command为地址变量,SendDat为所送的数据

返回说明:

版本:10

说明:

/

void WriteByte(uchar Command,uchar SendDat)

{

WriteCommand(Command);

WriteCommand(SendDat);

RST=0;

}

/

函数名称:DS1302单字节读取某地址数据函数

功能描述:读取某一地址的数据

全局变量:无

参数说明:Command为地址变量

返回说明:返回读取的指定地址数据

版本:10

说明:

/

uchar ReadByte(uchar Command)//读字节子程序,入口参数,命令字

{

uchar RecDat=0;

WriteCommand(Command);

RecDat=ReadData();

RST=0;

return RecDat;

}

/

读写保护 *** 作,不能在多字节写模式下写入

SendByte(0x8EH,0x80)//向8EH地址写入0x80H数据,实现禁止写入 *** 作

SendByte(0x8EH,0x00)//向8EH地址写入0x00H数据,实现允许写入 *** 作

/

//允许时钟启动,CH变为0

void OscCtrl(bit CtrlDat)//振荡起动和停止控制,入口参数1起动或0停止

{

if(CtrlDat)WriteByte(0x80,0x00);

elseWriteByte(0x80,0x80);

}

/

//单字节传送

SendByte(0x80H,0x85);//启动时钟,秒为5

SendByte(0x81H);//读取时间中的秒数据

SendByte(0x82H,0x06);//写入分钟数据为6

SendByte(0x83H);//读取分钟数据

/

/

函数名称:DS1302连续写入数据函数

功能描述:

全局变量:无

参数说明:Command为命令,p发送的数据,longth为字节数据

返回说明:

版本:10

说明:当写入时间数据时,长度必须为8才可以,当写入RAM数据时数据长度为0~31

/

void DS1302_BustWrite(uchar Command,uchar longth,uchar p)

{

uchar i;

WriteCommand(Command);

for(i=longth;i>0;i--)

{

WriteData(p);

p++;

}

RST=0;

}

/

函数名称:DS1302连续读数据函数

功能描述:

全局变量:无

参数说明:Command为命令,longth为读取的数据长度,p读出后写入的数组指针

返回说明:

版本:10

说明:当读取RAM数据的时候数据长度为0~31

/

void DS1302_BustReadByte(uchar Command,uchar longth,uchar p)

{

uchar i;

WriteCommand(Command);

for(i=longth;i>0;i--)

{

//p=0;

p=ReadData();

p++;

}

RST=0;

}

由于有忙检测,可能是DS1302的电源全都没有以后,程序因为访问DS1302时,得到DS1302总处于忙的状态,而导致进入死循环造成的。

如果在主程序中加入DS1302的电源检测或者不检测忙,可以不导致死循环。

就是十进制和十六进制的转换

写的时候十进制转换成十六进制

十进制 34

0x34 = (34/10)16 + 34%10;

读的时候十六进制转换成十进制

十六进制 0x34

34 = (0x34/16)10 + 0x34%16;

以上就是关于ds1302时钟芯片工作原理全部的内容,包括:ds1302时钟芯片工作原理、将DS1302时钟芯片的时期显示在LCD上的代码 要是C语言的 单片机用51的,急急急!!!、利用字符型LCD1602和时钟芯片DS1302,显示年月日星期时分秒信息。求解啊。求解。大家多多帮忙啊。。等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zz/10051705.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-04
下一篇2023-05-04

发表评论

登录后才能评论

评论列表(0条)

    保存