
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,显示年月日星期时分秒信息。求解啊。求解。大家多多帮忙啊。。等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)