• 回复
  • 收藏
  • 点赞
  • 分享
  • 发新帖

利人利己,做关于ds1302全面深入探讨,欢迎踊跃参与

比较多的人在研究ds1302这款时钟芯片,平时也会用到这个,并且过程当中也遇到些问题,所以萌生开贴大家来讨论的想法,集思广益,这样讨论出来的内容利人利己,自己学到知识的同时也帮助了别人,把问题集中起来

也希望高手们过来一起补充,一起讨论遇到的问题...更希望曾经研究过这款芯片的同学来分享学习ds1302遇到的问题和解决方法

我先说一些

DS1302编程注意事项:

通信:

1、单片机通过三线与ds1302芯片进行数据通信:reset, data, sclk,但并非I2C通信方式。

2、reset其实质相当于片选CE,两个作用:

a、选中芯片,开启ds1302移位寄存器,以进行数据传输,且整个数据传输过程中,需要保持为 高电平;

b、突发访问(多字节传输)模式下,通过拉低reset来结束本次突发访问模式。

需要注意必须保证在sclk拉低的前提前才能拉高reset(换言之,每次开始数据通信之前,必须sclk必须为低电平,那么sclk第一个边缘则一定为上升沿)。

3、data引脚应配置成可以双向通信的模式(例如:开漏输出,外接上拉电阻),在程序中应注意在单片机从接收ds1302数据之前,应拉高data,避免影响ds1302输出数据;

4、sclk 与 reset引脚,配置为普通输出模式即可。

5、ds1302时序:ds1302在sclk上升沿读取data数据,下降沿发布数据到data上。应注意在ds1302有数据输出时,输出数据开始位是紧接着命令发送字节的末尾的下降沿输出的。

全部回复(30)
正序查看
倒序查看
pirate
LV.4
2
2014-02-08 15:44

确实弄一个集中讨论帖比较好,问题比较集中也比较全面

DS1302操作上的问题我写了一些大家可以看看,指导一下啊

1、任何写操作之前应先清除写保护bit(特别重要)。

2、ds1302应外接32768Hz晶振,但并非直接就能起振的 ,需要软件清除 秒寄存器的bit7 即CH Bit,晶振才能正常工作,从而驱动ds1302内部计数器,达到准确计时 的目的,若正常起振,则此时可以用示波器在晶振引脚处测出波形。

3、对于突发访问模式:即是在sclk的驱动下,可以一次对多个寄存器进行读写,但是均是从(ram或者时间/日历寄存器)地址0开始访问的。应注意若是突发模式下写 时钟/日历寄存器 ,则必须要求传输8字节数据,若是突发访问ram数据,则不需要限定字节数,可以通过拉低reset来结束本次突发访问。

4、ds1302的ram区域,掉电丢失,可以利用这种特性来检测ds1302是否为第一次上电,从而确定是否需要配置ds1302。

0
回复
daylight
LV.4
3
2014-02-22 16:35

以下是我编写的DS1302芯片驱动代码,已测试,可以正常操作芯片,但是我用到的是stm32单片机,估计会有同学不习惯使用库的风格,但是不重要,感兴趣的同学可以参考程序的步骤就可以了,比如要看时序,就只看那一个 函数就可以了。。。。。更希望用51单片机开发的同学要是方便的话,能上传你宝贵的代码,让更多的人简单清楚的明白驱动步骤,更好的帮助他们

 

#include "stm32f10x_gpio.h"

#include "stm32f10x_rcc.h"

#include "ds1302.h"

#define DS1302_RESET_PORT GPIOC

#define DS1302_RESET_BIT GPIO_Pin_10

#define DS1302_SCLK_PORT GPIOC

#define DS1302_SCLK_BIT GPIO_Pin_11

#define DS1302_DATA_PORT GPIOC

#define DS1302_DATA_BIT GPIO_Pin_12

void DS1302Init(void)

{

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);//打开时钟模块

GPIO_InitTypeDef GPIO_InitStructure;

GPIO_InitStructure.GPIO_Pin = DS1302_RESET_BIT;//reset

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

GPIO_Init(DS1302_RESET_PORT, &GPIO_InitStructure);//复位引脚

GPIO_InitStructure.GPIO_Pin = DS1302_SCLK_BIT;

GPIO_Init(DS1302_SCLK_PORT, &GPIO_InitStructure);//SCLK

GPIO_WriteBit(DS1302_SCLK_PORT, DS1302_SCLK_BIT, Bit_RESET);

GPIO_InitStructure.GPIO_Pin = DS1302_DATA_BIT;//data

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;//开漏输出,通过外接上拉电阻,达到双向通信

GPIO_Init(DS1302_DATA_PORT, &GPIO_InitStructure);

DS1302TimeConfig();

}

unsigned char CommunicationByte(unsigned char value)

{

unsigned char i, temp;

GPIO_WriteBit(DS1302_SCLK_PORT, DS1302_SCLK_BIT, Bit_RESET);//sclk = 0;

temp = 0;

i = 0;

for(i = 0; i < 8; i++)

{

//接收数据,数据是紧接着控制字最后一位输出的

asm("NOP");asm("NOP");asm("NOP");asm("NOP");

temp >>= 1;//低位在前

if (GPIO_ReadInputDataBit(DS1302_DATA_PORT, DS1302_DATA_BIT) == 1)

{

temp |= 0x80;

}

//发送数据

if ((value & 0x01) != 0)

{

GPIO_WriteBit(DS1302_DATA_PORT, DS1302_DATA_BIT, Bit_SET);

}

else

{

GPIO_WriteBit(DS1302_DATA_PORT, DS1302_DATA_BIT, Bit_RESET);

}

GPIO_WriteBit(DS1302_SCLK_PORT, DS1302_SCLK_BIT, Bit_SET);//sclk = 1, 上升沿

value >>= 1;//低位在前

asm("NOP");asm("NOP");asm("NOP");asm("NOP");

GPIO_WriteBit(DS1302_DATA_PORT, DS1302_DATA_BIT, Bit_SET);//拉高DATA IO,避免影响芯片输出

GPIO_WriteBit(DS1302_SCLK_PORT, DS1302_SCLK_BIT, Bit_RESET);//sclk = 0,下降沿

}

return temp;

}

void DS1302WriteRegister(unsigned char reg, unsigned char value)

{

GPIO_WriteBit(DS1302_SCLK_PORT, DS1302_SCLK_BIT, Bit_RESET);//sclk = 0;

GPIO_WriteBit(DS1302_RESET_PORT, DS1302_RESET_BIT, Bit_SET);//只有在SCLK为低电平时候,才允许将rst置位高电平

CommunicationByte(reg);

CommunicationByte(value);

GPIO_WriteBit(DS1302_RESET_PORT, DS1302_RESET_BIT, Bit_RESET);//reset = 0;

}

unsigned char DS1302ReadRegister(unsigned char reg)

{

unsigned char temp;

GPIO_WriteBit(DS1302_SCLK_PORT, DS1302_SCLK_BIT, Bit_RESET);//sclk = 0;

GPIO_WriteBit(DS1302_RESET_PORT, DS1302_RESET_BIT, Bit_SET);//只有在SCLK为低电平时候,才允许将rst置位高电平

CommunicationByte(reg);

temp = CommunicationByte(0xff);

GPIO_WriteBit(DS1302_SCLK_PORT, DS1302_SCLK_BIT, Bit_SET);//sclk = 0;

GPIO_WriteBit(DS1302_RESET_PORT, DS1302_RESET_BIT, Bit_RESET);//reset = 0;

return temp;

}

void DS1302WriteTime(unsigned char *data)

{

unsigned char i;

GPIO_WriteBit(DS1302_SCLK_PORT, DS1302_SCLK_BIT, Bit_RESET);//sclk = 0;

GPIO_WriteBit(DS1302_RESET_PORT, DS1302_RESET_BIT, Bit_SET);//reset = 1;

CommunicationByte(0xbe);//连续写 日历/时钟寄存器

for (i = 0; i < 8; i++)

{

CommunicationByte(data[i]);

}

GPIO_WriteBit(DS1302_SCLK_PORT, DS1302_SCLK_BIT, Bit_RESET);//sclk = 0;

GPIO_WriteBit(DS1302_RESET_PORT, DS1302_RESET_BIT, Bit_RESET);//reset = 0;

}

void DS1302ReadTime(unsigned char *buffer)

{

unsigned char i;

GPIO_WriteBit(DS1302_SCLK_PORT, DS1302_SCLK_BIT, Bit_RESET);//sclk = 0;

GPIO_WriteBit(DS1302_RESET_PORT, DS1302_RESET_BIT, Bit_SET);//reset = 1;

CommunicationByte(0xbf);//连续读 日历/时钟寄存器

for (i = 0; i < 8; i++)

{

buffer[i] = CommunicationByte(0xff);

}

GPIO_WriteBit(DS1302_SCLK_PORT, DS1302_SCLK_BIT, Bit_SET);//sclk = 0;

GPIO_WriteBit(DS1302_RESET_PORT, DS1302_RESET_BIT, Bit_RESET);//reset = 0;

}

void DS1302TimeConfig(void)

{

unsigned char temp;

unsigned char data[8] = {0x01,0x10,0x11,0x30,0x11,0x05,0x12};//for test

temp = DS1302ReadRegister(0xc1);//读取ds1302ram 数据

if (temp != 0xaa)//第一次上电

{

DS1302WriteRegister(0x8e, 0x00);//允许写操作

DS1302WriteRegister(0xc0, 0xaa);//置标志位

DS1302WriteTime(data);

DS1302WriteRegister(0x8e, 0x80);//禁止写操作

/*

DS1302WriteRegister(0x80,0x01);//设置秒

DS1302WriteRegister(0x82,0x18);//设置分

DS1302WriteRegister(0x84,0x17);//设置时

DS1302WriteRegister(0x86,0x29);//设置日

DS1302WriteRegister(0x88,0x11);//设置月

DS1302WriteRegister(0x8a,0x04);//设置星期

DS1302WriteRegister(0x8c,0x12);//设置年

*/

}

}

void DS1302TimeUpdate(unsigned char *data)

{

//data 数据应为压缩bcd码

DS1302WriteRegister(0x8e, 0x00);//允许写操作

DS1302WriteRegister(0xc0, 0xaa);//置标志位

DS1302WriteTime(data);//连续写入 时钟/日历 寄存器数据

DS1302WriteRegister(0x8e, 0x80);//禁止写操作

}

 

0
回复
daylight
LV.4
4
2014-02-22 16:39
@daylight
以下是我编写的DS1302芯片驱动代码,已测试,可以正常操作芯片,但是我用到的是stm32单片机,估计会有同学不习惯使用库的风格,但是不重要,感兴趣的同学可以参考程序的步骤就可以了,比如要看时序,就只看那一个函数就可以了。。。。。更希望用51单片机开发的同学要是方便的话,能上传你宝贵的代码,让更多的人简单清楚的明白驱动步骤,更好的帮助他们 #include"stm32f10x_gpio.h"#include"stm32f10x_rcc.h"#include"ds1302.h"#defineDS1302_RESET_PORTGPIOC#defineDS1302_RESET_BITGPIO_Pin_10#defineDS1302_SCLK_PORTGPIOC#defineDS1302_SCLK_BITGPIO_Pin_11#defineDS1302_DATA_PORTGPIOC#defineDS1302_DATA_BITGPIO_Pin_12voidDS1302Init(void){RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);//打开时钟模块GPIO_InitTypeDefGPIO_InitStructure;GPIO_InitStructure.GPIO_Pin=DS1302_RESET_BIT;//resetGPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;GPIO_Init(DS1302_RESET_PORT,&GPIO_InitStructure);//复位引脚GPIO_InitStructure.GPIO_Pin=DS1302_SCLK_BIT;GPIO_Init(DS1302_SCLK_PORT,&GPIO_InitStructure);//SCLKGPIO_WriteBit(DS1302_SCLK_PORT,DS1302_SCLK_BIT,Bit_RESET);GPIO_InitStructure.GPIO_Pin=DS1302_DATA_BIT;//dataGPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_OD;//开漏输出,通过外接上拉电阻,达到双向通信GPIO_Init(DS1302_DATA_PORT,&GPIO_InitStructure);DS1302TimeConfig();}unsignedcharCommunicationByte(unsignedcharvalue){unsignedchari,temp;GPIO_WriteBit(DS1302_SCLK_PORT,DS1302_SCLK_BIT,Bit_RESET);//sclk=0;temp=0;i=0;for(i=0;i<8;i++){//接收数据,数据是紧接着控制字最后一位输出的asm("NOP");asm("NOP");asm("NOP");asm("NOP");temp>>=1;//低位在前if(GPIO_ReadInputDataBit(DS1302_DATA_PORT,DS1302_DATA_BIT)==1){temp|=0x80;}//发送数据if((value&0x01)!=0){GPIO_WriteBit(DS1302_DATA_PORT,DS1302_DATA_BIT,Bit_SET);}else{GPIO_WriteBit(DS1302_DATA_PORT,DS1302_DATA_BIT,Bit_RESET);}GPIO_WriteBit(DS1302_SCLK_PORT,DS1302_SCLK_BIT,Bit_SET);//sclk=1,上升沿value>>=1;//低位在前asm("NOP");asm("NOP");asm("NOP");asm("NOP");GPIO_WriteBit(DS1302_DATA_PORT,DS1302_DATA_BIT,Bit_SET);//拉高DATAIO,避免影响芯片输出GPIO_WriteBit(DS1302_SCLK_PORT,DS1302_SCLK_BIT,Bit_RESET);//sclk=0,下降沿}returntemp;}voidDS1302WriteRegister(unsignedcharreg,unsignedcharvalue){GPIO_WriteBit(DS1302_SCLK_PORT,DS1302_SCLK_BIT,Bit_RESET);//sclk=0;GPIO_WriteBit(DS1302_RESET_PORT,DS1302_RESET_BIT,Bit_SET);//只有在SCLK为低电平时候,才允许将rst置位高电平CommunicationByte(reg);CommunicationByte(value);GPIO_WriteBit(DS1302_RESET_PORT,DS1302_RESET_BIT,Bit_RESET);//reset=0;}unsignedcharDS1302ReadRegister(unsignedcharreg){unsignedchartemp;GPIO_WriteBit(DS1302_SCLK_PORT,DS1302_SCLK_BIT,Bit_RESET);//sclk=0;GPIO_WriteBit(DS1302_RESET_PORT,DS1302_RESET_BIT,Bit_SET);//只有在SCLK为低电平时候,才允许将rst置位高电平CommunicationByte(reg);temp=CommunicationByte(0xff);GPIO_WriteBit(DS1302_SCLK_PORT,DS1302_SCLK_BIT,Bit_SET);//sclk=0;GPIO_WriteBit(DS1302_RESET_PORT,DS1302_RESET_BIT,Bit_RESET);//reset=0;returntemp;}voidDS1302WriteTime(unsignedchar*data){unsignedchari;GPIO_WriteBit(DS1302_SCLK_PORT,DS1302_SCLK_BIT,Bit_RESET);//sclk=0;GPIO_WriteBit(DS1302_RESET_PORT,DS1302_RESET_BIT,Bit_SET);//reset=1;CommunicationByte(0xbe);//连续写日历/时钟寄存器for(i=0;i<8;i++){CommunicationByte(data[i]);}GPIO_WriteBit(DS1302_SCLK_PORT,DS1302_SCLK_BIT,Bit_RESET);//sclk=0;GPIO_WriteBit(DS1302_RESET_PORT,DS1302_RESET_BIT,Bit_RESET);//reset=0;}voidDS1302ReadTime(unsignedchar*buffer){unsignedchari;GPIO_WriteBit(DS1302_SCLK_PORT,DS1302_SCLK_BIT,Bit_RESET);//sclk=0;GPIO_WriteBit(DS1302_RESET_PORT,DS1302_RESET_BIT,Bit_SET);//reset=1;CommunicationByte(0xbf);//连续读日历/时钟寄存器for(i=0;i<8;i++){buffer[i]=CommunicationByte(0xff);}GPIO_WriteBit(DS1302_SCLK_PORT,DS1302_SCLK_BIT,Bit_SET);//sclk=0;GPIO_WriteBit(DS1302_RESET_PORT,DS1302_RESET_BIT,Bit_RESET);//reset=0;}voidDS1302TimeConfig(void){unsignedchartemp;unsignedchardata[8]={0x01,0x10,0x11,0x30,0x11,0x05,0x12};//fortesttemp=DS1302ReadRegister(0xc1);//读取ds1302ram数据if(temp!=0xaa)//第一次上电{DS1302WriteRegister(0x8e,0x00);//允许写操作DS1302WriteRegister(0xc0,0xaa);//置标志位DS1302WriteTime(data);DS1302WriteRegister(0x8e,0x80);//禁止写操作/*DS1302WriteRegister(0x80,0x01);//设置秒DS1302WriteRegister(0x82,0x18);//设置分DS1302WriteRegister(0x84,0x17);//设置时DS1302WriteRegister(0x86,0x29);//设置日DS1302WriteRegister(0x88,0x11);//设置月DS1302WriteRegister(0x8a,0x04);//设置星期DS1302WriteRegister(0x8c,0x12);//设置年*/}}voidDS1302TimeUpdate(unsignedchar*data){//data数据应为压缩bcd码DS1302WriteRegister(0x8e,0x00);//允许写操作DS1302WriteRegister(0xc0,0xaa);//置标志位DS1302WriteTime(data);//连续写入时钟/日历寄存器数据DS1302WriteRegister(0x8e,0x80);//禁止写操作} 

学习过程中用到的关于ds1302的两份参考资料

ds1302中文资料.pdf

DS1302中文资料_带源代码.pdf

0
回复
金鱼1
LV.3
5
2014-02-22 16:42
下一步打算搞搞个这个片子。谢谢资料。
0
回复
2014-02-22 16:45
1302好芯片,不过,残次品太多,我就遇见个,必须在IO口加上拉电阻才能工作的片子,不加就乱码
0
回复
daylight
LV.4
7
2014-02-22 16:46
@soap泡泡
1302好芯片,不过,残次品太多,我就遇见个,必须在IO口加上拉电阻才能工作的片子,不加就乱码
这个情况可能和单片机 io端口配置有关, 要达到双向通信的话,单片机io端口必须可以输出和输入,且单片机的输出不能影响到DS1302的输出(说的有点绕口,要表达的意思就是,同一时刻IO data只能分配给cpu或者 DS1302有效使用,而另一个则要配置为不影响IO data状态),有的模式下就必须要外接上拉电阻才能正常通信。就stm32F10x单片机而言,要达到双向通信的功能,io端口必须要配置成开漏输出,那么则必须要外接上拉电阻才能实现  输出高电平.。。。。。。。。具体的话,你可以详细了解下 开漏输出, 我说的肯定也不是多么 准确哈
0
回复
backin
LV.4
8
2014-02-22 16:47
@daylight
这个情况可能和单片机io端口配置有关,要达到双向通信的话,单片机io端口必须可以输出和输入,且单片机的输出不能影响到DS1302的输出(说的有点绕口,要表达的意思就是,同一时刻IOdata只能分配给cpu或者DS1302有效使用,而另一个则要配置为不影响IOdata状态),有的模式下就必须要外接上拉电阻才能正常通信。就stm32F10x单片机而言,要达到双向通信的功能,io端口必须要配置成开漏输出,那么则必须要外接上拉电阻才能实现  输出高电平.。。。。。。。。具体的话,你可以详细了解下开漏输出,我说的肯定也不是多么准确哈
什么叫开漏输出啊?
0
回复
backin
LV.4
9
2014-02-22 16:49

ds1302有两个vcc分别是1和8引脚,在应用是1号引脚为备用电源端,但不知对电源电压大小有无要求啊?又是多少呢?

这是我在制作时钟时使用DS1302的操作代码和对应时序图:

void WriteDs1302Byte(uchar temp)

{

uchar i;

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

{

DS1302_IO=temp&0x01;

DS1302_CLK=0;

DS1302_CLK=1;

temp>>=1;

}

}

void WriteDs1302( uchar address,uchar dat )

{

DS1302_RST=0;

DS1302_CLK=0;

DS1302_RST=1;

delay(1);

WriteDs1302Byte(address);

WriteDs1302Byte(dat);

DS1302_RST=0;

}

uchar read_byte()

{

uchar i;

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

{

if(DS1302_IO)

temp0=temp0|0x80;

DS1302_CLK=1;

DS1302_CLK=0;

temp0=temp0>>1;

}

return temp0;

}

uchar ReadDs1302(uchar address)

{

uchar temp;

DS1302_RST=0;

DS1302_CLK=0;

DS1302_RST=1;

WriteDs1302Byte(address);

temp=read_byte();

DS1302_RST=0;

DS1302_CLK=1;

return temp;

}

 

0
回复
daylight
LV.4
10
2014-02-22 16:53
@backin
ds1302有两个vcc分别是1和8引脚,在应用是1号引脚为备用电源端,但不知对电源电压大小有无要求啊?又是多少呢?这是我在制作时钟时使用DS1302的操作代码和对应时序图:voidWriteDs1302Byte(uchartemp){uchari;for(i=8;i>0;i--){DS1302_IO=temp&0x01;DS1302_CLK=0;DS1302_CLK=1;temp>>=1;}}voidWriteDs1302(ucharaddress,uchardat){DS1302_RST=0;DS1302_CLK=0;DS1302_RST=1;delay(1);WriteDs1302Byte(address);WriteDs1302Byte(dat);DS1302_RST=0;}ucharread_byte(){uchari;for(i=8;i>0;i--){if(DS1302_IO)temp0=temp0|0x80;DS1302_CLK=1;DS1302_CLK=0;temp0=temp0>>1;}returntemp0;}ucharReadDs1302(ucharaddress){uchartemp;DS1302_RST=0;DS1302_CLK=0;DS1302_RST=1;WriteDs1302Byte(address);temp=read_byte();DS1302_RST=0;DS1302_CLK=1;returntemp;}[图片] 

我也是最近才发现 这个问题:还没有说 两个电源的关系......主要是还没有吃透透这个地方..。。。用过ds1302备用电源的同学一起来讨论下...........首先,vcc1电压范围 2.0-5.5v, 那么vcc2 也应该是这个范围....两个电源切换条件如下:

可以这么理解, vcc1 和vcc2 哪个电压高些,就由那个电源向芯片供电。。。。。。。。然后,ds1302手册里面 涓流充电有如下图:

 ds1302内部具有充电电路,只要配置相应的寄存器即可启用..............根据图中二极管方向,则可以发现,电流只能有1脚vcc 流向 8脚vcc, 所以,只能由1脚的电源给8脚的电源充电,那么,8脚应该接超级电容或者可充电电池,但是 用户手册上则说,1脚为备用电源,8脚为主电压...有点不理解这个地方.................现在怀疑是不是用户手册翻译的时候出错了

 

 

0
回复
daylight
LV.4
11
2014-02-22 16:54
@backin
什么叫开漏输出啊?
我也是 在stm32单片机时候,才晓得这个概念的!!百度一下吧,貌似51的p0端口就是 开漏输出
0
回复
elio
LV.2
12
2014-02-22 16:56
开漏输出应该就是内部没有上拉电阻或者管子的,意思是只能靠外部接上拉电阻来灌电流的引脚。
0
回复
vidas
LV.2
13
2014-02-22 17:03
我用的是DS1302N,如果第8脚接电池的话,芯片发热很厉害,所以,第8脚不能接电池,只有想别的办法让他不断电了.
0
回复
daylight
LV.4
14
2014-02-22 17:04
@vidas
我用的是DS1302N,如果第8脚接电池的话,芯片发热很厉害,所以,第8脚不能接电池,只有想别的办法让他不断电了.
芯片发烫,很有可能是电流过大,这个样子的话,不能通过ds1302来给电池充电了么?
0
回复
一木01
LV.3
15
2014-02-22 17:05
@daylight
我也是最近才发现这个问题:还没有说两个电源的关系......主要是还没有吃透透这个地方..。。。用过ds1302备用电源的同学一起来讨论下...........首先,vcc1电压范围2.0-5.5v,那么vcc2也应该是这个范围....两个电源切换条件如下:[图片]可以这么理解,vcc1和vcc2哪个电压高些,就由那个电源向芯片供电。。。。。。。。然后,ds1302手册里面涓流充电有如下图:[图片] ds1302内部具有充电电路,只要配置相应的寄存器即可启用..............根据图中二极管方向,则可以发现,电流只能有1脚vcc流向8脚vcc,所以,只能由1脚的电源给8脚的电源充电,那么,8脚应该接超级电容或者可充电电池,但是用户手册上则说,1脚为备用电源,8脚为主电压...有点不理解这个地方.................现在怀疑是不是用户手册翻译的时候出错了  
英文手册上说1脚VCC2是主电源接口,8脚VCC1是备用电源接口。
0
回复
matou
LV.3
16
2014-02-22 17:06
我做的实时时钟DS18B20,电源断电为什么不能保持呢
0
回复
cloud7890
LV.2
17
2014-02-22 17:08
@matou
我做的实时时钟DS18B20,电源断电为什么不能保持呢
没有备用电池?
0
回复
stony_s
LV.3
18
2014-02-22 17:09
DS1302使用比较方便,不用I2C。同样地时钟芯片DS1307就很麻烦,I2C搞来搞去的。
0
回复
close3
LV.5
19
2014-02-22 17:10
我有一个问题,想请教一下大家,我用ds1302,在设置时间时,让芯片暂停,可是开始后为什么芯片就不运行了?
0
回复
for_real
LV.3
20
2014-02-22 17:13
@backin
ds1302有两个vcc分别是1和8引脚,在应用是1号引脚为备用电源端,但不知对电源电压大小有无要求啊?又是多少呢?这是我在制作时钟时使用DS1302的操作代码和对应时序图:voidWriteDs1302Byte(uchartemp){uchari;for(i=8;i>0;i--){DS1302_IO=temp&0x01;DS1302_CLK=0;DS1302_CLK=1;temp>>=1;}}voidWriteDs1302(ucharaddress,uchardat){DS1302_RST=0;DS1302_CLK=0;DS1302_RST=1;delay(1);WriteDs1302Byte(address);WriteDs1302Byte(dat);DS1302_RST=0;}ucharread_byte(){uchari;for(i=8;i>0;i--){if(DS1302_IO)temp0=temp0|0x80;DS1302_CLK=1;DS1302_CLK=0;temp0=temp0>>1;}returntemp0;}ucharReadDs1302(ucharaddress){uchartemp;DS1302_RST=0;DS1302_CLK=0;DS1302_RST=1;WriteDs1302Byte(address);temp=read_byte();DS1302_RST=0;DS1302_CLK=1;returntemp;}[图片] 
相差0.2V以上,脚可以随便接,默认低电压端为备用,另里面可选充电电阻二极管
0
回复
god_father
LV.3
21
2014-02-22 17:14
自己用ds1302和1602做了一个时钟,但51不能从ds1302中读取数据,1602一直在那闪。
0
回复
一木01
LV.3
22
2014-02-22 17:31
@daylight
我也是最近才发现这个问题:还没有说两个电源的关系......主要是还没有吃透透这个地方..。。。用过ds1302备用电源的同学一起来讨论下...........首先,vcc1电压范围2.0-5.5v,那么vcc2也应该是这个范围....两个电源切换条件如下:[图片]可以这么理解,vcc1和vcc2哪个电压高些,就由那个电源向芯片供电。。。。。。。。然后,ds1302手册里面涓流充电有如下图:[图片] ds1302内部具有充电电路,只要配置相应的寄存器即可启用..............根据图中二极管方向,则可以发现,电流只能有1脚vcc流向8脚vcc,所以,只能由1脚的电源给8脚的电源充电,那么,8脚应该接超级电容或者可充电电池,但是用户手册上则说,1脚为备用电源,8脚为主电压...有点不理解这个地方.................现在怀疑是不是用户手册翻译的时候出错了  

vcc2才是主电压,上面的是datasheet上的引脚说明

0
回复
cloud7890
LV.2
23
2014-02-22 17:32

搞了一晚上的ds1302,连开发板的程序都觉得怪怪的。

开发板的程序这样的:

sbit SCK=P2^7; //时钟

sbit SDA=P2^6; //数据

sbit RST = P2^5;// DS1302复位

好的,上面给出了开发板的硬件连接。我随后在另一个最小系统上写入这样的代码:

sbit SCK=P2^6; //时钟

sbit SDA=P2^5; //数据

sbit RST = P2^4;// DS1302复位

然后分别把开发板的p27接另一个板的P26,P26-P25,P25-P24.

这样的目的是为了让另一块板子上的单片机读出开发板上DS1302的数据,并将时分秒的十进制通过串口送出去这样我就会看见数据了。然后,上电,出错。

无论IO口怎么改就是读不出,只有一种设定可以正常:另一个板子的P27,P26,P25和开发板的程序对应,硬件连接一模一样就可以。

0
回复
cloud7890
LV.2
24
2014-02-22 17:35
@cloud7890
搞了一晚上的ds1302,连开发板的程序都觉得怪怪的。开发板的程序这样的:sbitSCK=P2^7;//时钟sbitSDA=P2^6;//数据sbitRST=P2^5;//DS1302复位好的,上面给出了开发板的硬件连接。我随后在另一个最小系统上写入这样的代码:sbitSCK=P2^6;//时钟sbitSDA=P2^5;//数据sbitRST=P2^4;//DS1302复位然后分别把开发板的p27接另一个板的P26,P26-P25,P25-P24.这样的目的是为了让另一块板子上的单片机读出开发板上DS1302的数据,并将时分秒的十进制通过串口送出去这样我就会看见数据了。然后,上电,出错。无论IO口怎么改就是读不出,只有一种设定可以正常:另一个板子的P27,P26,P25和开发板的程序对应,硬件连接一模一样就可以。
我发现我的DS1302三根线只能和单片机P2口连着才能工作,任何一根线和上拉电阻的P0口连接就会出错。为什么会这么奇怪呢
0
回复
pirate
LV.4
25
2014-02-22 17:37
前段时间终于搞定了,我买的是淘宝上的模块(店家说接不接电阻没关系,事实上一定得接10k上拉),我用的是AT51
0
回复
001a
LV.3
26
2014-02-22 17:42
好帖子呀。能这么细心回复的还是少见。我在做一个18B20+1302的板子,温度正常,就是时间怎么都不走,也调不了。一直都是显示2000-01-01好是头疼
0
回复
001a
LV.3
27
2014-02-22 17:45
@001a
好帖子呀。能这么细心回复的还是少见。我在做一个18B20+1302的板子,温度正常,就是时间怎么都不走,也调不了。一直都是显示2000-01-01好是头疼
我的1302接在了i/oP1.1口,SCLK--P1.0,RST---P1.2。就是无法正常工作.其他资料说是1接VCC,8接电容。DS1302_IO = ACC0;                       是不是应该把这句写到前面去呀?(   DS1302_CLK = 1;)
0
回复
2014-02-22 17:48
刚好用到这个芯片,搞得我头都大了
0
回复
pirate
LV.4
29
2014-02-22 17:52
前一段时间也用这个做了一个显示屏
0
回复
heal
LV.3
30
2014-02-22 17:54

楼主你好 请教个问题 我做的12864万年历 液晶显示了 就是时钟不走 不知道是什么原因 附上原理图和驱动程序 知道的大神帮帮看看 感激不尽 ,,,,//DS1302时钟芯片驱动程序

/*****************************************************************************/

//常用时钟数据读取

void Read1302S(void){

ss = Read1302(0x81);//读取秒数据

mm = Read1302(0x83);//读取分钟数据

hh = Read1302(0x85);//小时

dd = Read1302(0x87);//日

mo = Read1302(0x89);//月

xq = Read1302(0x8b);//星期

yy = Read1302(0x8d);//年

}

/*****************************************************************************/

//调时用加1程序

void Set_time(unsigned char sel){ //根据选择调整的相应项目加1并写入DS1302

signed char address,item;

signed char max,mini;

LCM_WriteDatOrCom(0,0x9a);

LCM_WriteString("调整");

//if(sel==6) {LCM_WriteString("秒钟");address=0x80; max=0;mini=0;} //秒7

if(sel==5) {LCM_WriteString("分钟");address=0x82; max=59;mini=0;} //分钟6

if(sel==4) {LCM_WriteString("小时");address=0x84; max=23;mini=0;} //小时5

if(sel==3) {LCM_WriteString("星期");address=0x8a; max=7;mini=1;} //星期4

if(sel==2) {LCM_WriteString("日期");address=0x86; max=31;mini=1;} //日3

if(sel==1) {LCM_WriteString("月份");address=0x88; max=12;mini=1;} //月2

if(sel==0) {LCM_WriteString("年份");address=0x8c; max=99; mini=0;} //年1

//读取1302某地址上的数值转换成10进制赋给item

item=((Read1302(address+1))/16)*10 + (Read1302(address+1))%16;

if(KEY_2 == 0){

item++;//数加 1

}

if(KEY_4 == 0){

item--;//数减 1

}

if(item>max) item=mini;//查看数值有效范围

if(item

Write1302(0x8e,0x00);//允许写操作

Write1302(address,(item/10)*16+item%10);//转换成16进制写入1302

Write1302(0x8e,0x80);//写保护,禁止写操作

updata (); //刷新数据

lcm_w_mm();//刷新 分

}

/*****************************************************************************/

//设置1302的初始时间(自动初始化)

void Init_1302(void){//-设置1302的初始时间(2007年1月1日00时00分00秒星期一)

unsigned char f;

if(Read1302(0xc1) != 0xaa){

Write1302(0x8e,0x00);//允许写操作

Write1302(0x8c,0x10);//年

Write1302(0x8a,0x01);//星期

Write1302(0x88,0x01);//月

Write1302(0x86,0x01);//日

Write1302(0x84,0x00);//小时

Write1302(0x82,0x00);//分钟

Write1302(0x80,0x00);//秒

Write1302(0x90,0xa5);//充电

Write1302(0xc0,0xaa);//写入初始化标志RAM(第00个RAM位置)

for(f=0;f<60;f=f+2){//清除闹钟RAM位为0

Write1302(0xc2+f,0x00);

}

Write1302(0x8e,0x80);//禁止写操作

}

}

/*****************************************************************************/

//DS1302写数据(底层协议)

void Write1302(unsigned char ord, unsigned char dd){

clock_clk=0;

clock_Rst=0;

clock_Rst=1;

DS1302OutputByte(ord);

DS1302OutputByte(dd);

clock_Rst=0;

clock_clk=1;

}

/*****************************************************************************/

//1302驱动程序(底层协议)

void DS1302OutputByte(unsigned char dd){

ACC=dd;

clock_dat=a0; clock_clk=1; clock_clk=0;

clock_dat=a1; clock_clk=1; clock_clk=0;

clock_dat=a2; clock_clk=1; clock_clk=0;

clock_dat=a3; clock_clk=1; clock_clk=0;

clock_dat=a4; clock_clk=1; clock_clk=0;

clock_dat=a5; clock_clk=1; clock_clk=0;

clock_dat=a6; clock_clk=1; clock_clk=0;

clock_dat=a7; clock_clk=1; clock_clk=0;

}

/*****************************************************************************/

//DS1302写入字节(底层协议)

unsigned char DS1302InputByte(void){

clock_dat=1;

a0=clock_dat;

clock_clk=1; clock_clk=0; a1=clock_dat;

clock_clk=1; clock_clk=0; a2=clock_dat;

clock_clk=1; clock_clk=0; a3=clock_dat;

clock_clk=1; clock_clk=0; a4=clock_dat;

clock_clk=1; clock_clk=0; a5=clock_dat;

clock_clk=1; clock_clk=0; a6=clock_dat;

clock_clk=1; clock_clk=0; a7=clock_dat;

return(ACC);

}

/*****************************************************************************/

//DS1302读数据(底层协议)

unsigned char Read1302(unsigned char ord){

unsigned char dd=0;

clock_clk=0;

clock_Rst=0;

clock_Rst=1;

DS1302OutputByte(ord);

dd=DS1302InputByte();

clock_Rst=0;

clock_clk=1;

return(dd);

}

 

 

0
回复
金鱼1
LV.3
31
2014-02-22 17:55
我的DS1302无论怎样 用1602显示的时候都是乱码
0
回复