首页 > 编程知识 正文

ds1302时钟芯片读写详解,ds1302时钟模块原理图

时间:2023-05-06 03:24:52 阅读:125018 作者:3590

我刚学了一种叫ds1302的时钟芯片的使用方法,现在我正在分享学习的过程。 我觉得整个过程并不太难,但还有令人费解的地方,至今尚不清楚。 因为没有实际验证,所以不确定是什么原因。

1 .首先,查找ds1302手册。 可以在名为21ic的网站上下载。 如果自己不喜欢翻译英文版的话()我建议你在这里硬着头皮读英文版。 毕竟有好处,你怎么说? 你可以在网上找中文版。

2 .通过手册,我们需要知道这个芯片能做什么。 心里有大概的事。

这是ds1302的主要特征。 通过时钟计数功能,可以进行秒、分、小时、月、周、年的计数。 年数达到2100年。 包括31*8位追加数据临时保存寄存器(RAM、断电)等。

这是详细的说明。 ds1302充电计时器芯片包括实时时钟/日历和31字节静态RAW。 通过简单的串行接口与微处理器进行通信。 实时时钟/日历提供秒、分钟、小时、天、日期、月和年的信息。 月末的日期会自动调整,不到31天,包括闰年的修正。 时钟以24小时或12小时的形式工作,带有am/pm指示灯等。

通过以上内容,大致知道了ds1302这个芯片能做什么。 接下来,我会弄清楚怎么使用那个。 首先,你需要知道每个管脚是为了什么

在这里,主要操作5 CE、6 I/O、7 SCLK这3个引脚来驱动名为ds1302的芯片。

CE:输入。 在读取或写入过程中,必须将CE信号设为高电平。 该导线上接地有内部40k(标准值)的下拉电阻。 注:以前数据表修订的简称CE是RST。 针脚功能未改变;

I/O:输入/推挽输出。 I/O端子为3线双向数据端子连接器。 该导线上接地有内部40k(标准值)的下拉电阻;

SCLK:输入。 SCLK用于同步串行接口上的数据移动。 该导线上接地有内部40k(标准值)的下拉电阻。

知道了各引脚的功能后,我们看时序图,通过时序图制作驱动程序。 对于刚学习单片机的学生来说,一开始可能不知道。 那样的话,应该可以找几个时序图,对应别人写的司机仔细看、总结、理解。 然后,我自己试着写一下。 毕竟我们不是庖丁。 要实现庖丁这样的神技,2个字,3358ww.SST

多练

这是一个1字节的读写时序图,可以看到前8位读写地址,表示不同的功能,后8位读写数据。 读写操作的明显区别在于后面8位数据位的操作不同。 读取操作在SCLK的下降沿锁存数据。 也就是说,要从I/O端口读取1位数据,必须先将SCLK引脚从高到低,然后进行从高到低的跳转,从而读取数据。 写入时,在SCLK的上升沿锁存数据。 道理是一样的。 另一个是读写数据从低位到高位。 是D0-D7

接下来,需要知道寄存器的操作方法。 我的理解是真值表,根据值有什么样的功能。

制作ds1302的驱动程序,在实践中加深理解吧。

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

/*1字节写入1字节*

void write _ ds 1302 _ byte (unsignedchardat ) )。

{

无符号char I;

SCLK=0;

for(I=0; i8; I )

{

if(dat0x01 ) /或if ) ) ) dat0x01 )==1)等价

{

IO_SET; //#将define io _ set io=1/* io端口设置为高电平*

}

else

{

IO_CLR; //#define IO_CLR IO=0 /*IO使io端口处于低电平*

}

SCLK_SET; //同上,由于最初SCLK被置零为低电平,所以现在被置高,是上升沿

SCLK_CLR; //准备下一位的传输,完成后降低SCLK

dat=dat 1;

}

}

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

************************/ 
/*单字节读出一字节数据*/
unsigned char Read_Ds1302_Byte(void) 
{
unsigned char i, dat=0;
for (i=0;i<8;i++)
{
dat = dat >> 1;
if (IO)   //等价于if(IO==1)     /*读取IO口电平*/
{
dat |= 0x80;
}
else 
{
dat &= 0x7F;
}
SCLK_SET;            //时钟线SCLK置高,再置低,就是一个下降沿,锁存数据
SCLK_CLR;            //                    置低,而且数据传输完成后时钟线SCLK拉低
}
return dat;
}


/********************************************************************/ 
/*单字节写入一字节数据*/
void Ds1302_Single_Byte_Write(unsigned char addr, unsigned char dat)



CE_CLR; /*初始时CE置低电平*/
SCLK_CLR; /*初始时SCLK置低电平*/


CE_SET; /*启动DS1302总线,CE置高电平 */
addr = addr & 0xFE;  
Write_Ds1302_Byte(addr); /*写入目标地址:addr,保证是写操作,写之前将最低位置低*/
Write_Ds1302_Byte(dat); /*写入数据dat*/
CE_CLR; /*停止DS1302总线*/
}


/********************************************************************/ 
/*从DS1302单字节读出一字节数据*/
unsigned char Ds1302_Single_Byte_Read(unsigned char addr) 

unsigned char temp;
CE_CLR; /*CE置低电平,初始化*/
SCLK_CLR;         /*SCLK置低电平,初始化*/


CE_SET; /*启动DS1302总线,CE拉高 */
addr = addr | 0x01;  
Write_Ds1302_Byte(addr);         /*写入目标地址:addr,保证是读操作,写之前将最低位置高*/
temp=Read_Ds1302_Byte();     /*从DS1302中读出一字节数据*/
CE_CLR;     /*停止DS1302总线*/
IO_CLR;        //不太明白为什么要将IO口拉低,少了这句不行,会出错
return temp;
}

针对上面读数据时将IO口拉低网上的解释有:

1.数据线拉低,告诉器件,释放总线(个人认为这个解释站不住脚,因为时序图上没有画最后要拉低,逻辑问题)

2.显示异常可能是读取太快,也可能是传输线过长(有人通过缩短传输线使显示恢复正常)

最后的应用比较简单,比如我们想做一个电子表,显示时、分、秒

void ds1302_init()
{
Ds1302_Single_Byte_Write(0x8e, 0x00);                        //关闭写保护
Ds1302_Single_Byte_Write(ds1302_sec_addr, 0x40);    //写秒地址0x80
Ds1302_Single_Byte_Write(ds1302_min_addr, 0x20);   //写分地址0x82
Ds1302_Single_Byte_Write(ds1302_hr_addr, 0x10);      //写时地址0x84    初始时间为10时20分40秒
Ds1302_Single_Byte_Write(0x8e, 0x80);                        //开写保护
}


void read_ds1302()
{
time[0]=Ds1302_Single_Byte_Read(0x81);                    //读秒地址0x81
time[1]=Ds1302_Single_Byte_Read(0x83);                    //读分地址0x83
time[2]=Ds1302_Single_Byte_Read(0x85);                    //读时地址0x85
}
void main()
{
ds1302_init();
while(1)
{
read_ds1302();
display();

}

}


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

/*显示函数,用数码管显示,不同的单片机数码管操作大同小异,比较简单,自己写吧*/

void display()

{
uchar i=0;
for(i=0;i<8;i++)
{
clock(0xc0,wei[i]);
switch(i)
{
case 0:clock(0xe0,duan[time[2]/16]);break; 
case 1:clock(0xe0,duan[time[2]&0x0f]);break; 
case 2:clock(0xe0,0xbf);break; 
case 3:clock(0xe0,duan[time[1]/16]);break; 
case 4:clock(0xe0,duan[time[1]&0x0f]);break; 
case 5:clock(0xe0,0xbf);break; 
case 6:clock(0xe0,duan[time[0]/16]);break; 
case 7:clock(0xe0,duan[time[0]&0x0f]);break; 
default:break;
}
Delay2ms();
}

}

总结:一点一点积累,一点一点进步,做想做的事,乐在其中......




    

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。