DS1302时钟芯片单片机控制操作步骤

合集下载

ds1302时钟芯片汇编控制程序

ds1302时钟芯片汇编控制程序
MOV R4,#8 ;----R4
OUTBIT1:MOV C,T_IO
RRC A
SETB T_CLK
CLR T_CLK
DJNZ R4,OUTBIT1
RET
;---------- ----------END DS0302--------------------------------
SETB T_CLK
CLR T_RST
mov R0,#SECOND
MOV R7,#3 ;秒/时/分;-----R7
MOV R1,#80H ;秒写地址;-----R1
S1302:
CLR T_RST
CLR T_CLK
SETB T_RST
MOV B,R1 ;写秒/时/分地址;---R1
LCALL WRITEBYTE
ds1302时钟芯片ds1302时钟电路ds1302时钟不走ds1302芯片功能ds1302ds1302lcd1602时钟ds1302芯片ds1302中文资料ds1302工作原理ds1302程序
DS1302初始化及读写操作汇编程序
;************ DS1302初始化子程序************************************
MOV R0,#SECOND ;------R0
MOV R7,#03H ;-----R7
MOV R2,#81H ;-----R2
G13021:CLR T_RST
CLR T_CLK
SETB T_RST
MOV B,R2
LCALL WRITEBYTE ;写操作时,将一字节的内容由B写至DS1302中
LCALL READBYTE ;读操作时,将一字节的内容读至A中
INBIT1:MOV A,B

DS1302中文手册

DS1302中文手册

DS1302中文手册DS1302 是一款高性能、低功耗的实时时钟芯片,被广泛应用于各种需要准确计时的电子设备中。

一、DS1302 的基本特性1、实时时钟功能能够精确记录年、月、日、时、分、秒等时间信息。

2、低功耗设计在电池供电的情况下,仍能保持长时间的计时准确性。

3、数据存储具备 31 字节的非易失性静态 RAM,可用于存储一些关键数据。

4、简单的接口通过串行接口与微控制器进行通信,易于集成到系统中。

二、DS1302 的引脚功能1、 Vcc1 和 Vcc2Vcc1 是主电源引脚,Vcc2 是备用电源引脚。

当主电源正常供电时,芯片使用 Vcc1 供电;当主电源断电时,自动切换到 Vcc2(通常为电池)以保持时钟运行。

2、 GND接地引脚。

3、 CLK时钟输入引脚,用于同步数据传输。

4、 I/O数据输入/输出引脚。

5、 RST复位引脚,高电平有效。

三、DS1302 的通信协议DS1302 采用串行通信方式,通信数据以字节为单位进行传输。

1、起始位在每个字节传输开始时,RST 引脚被置为高电平,启动通信过程。

2、控制字节首先发送一个控制字节,用于指定后续操作是读操作还是写操作,以及要操作的寄存器地址。

3、数据字节根据控制字节的指示,接着传输数据字节。

4、停止位在传输完一个字节的数据后,将 RST 引脚置为低电平,结束本次通信。

四、DS1302 的寄存器1、时钟/日历寄存器包括年、月、日、时、分、秒等寄存器,用于存储时间信息。

2、控制寄存器用于设置时钟的工作模式,如是否开启振荡器、是否进行写保护等。

3、充电寄存器用于控制备用电源的充电特性。

4、 31 字节的 RAM 寄存器用于用户自定义数据存储。

五、DS1302 的初始化与设置在使用 DS1302 之前,需要进行初始化设置,包括设置初始时间、开启振荡器、关闭写保护等操作。

1、写入初始时间通过串行通信将准确的初始时间写入到相应的时钟/日历寄存器中。

2、开启振荡器将控制寄存器的相应位设置为 1,使振荡器开始工作。

时间控制模块—DS1302芯片的控制编程

时间控制模块—DS1302芯片的控制编程

定时器/计数器1-TCNT1H和TCNT1L
TCNT1H和TCNT1L组成了T/C的数据寄存器TCNT1。
定时器/计数器中断标志寄存器-TIFR
T/C1输 入捕捉 标志位
T/C1输 出比较B 匹配标 志位 T/C1溢出标志 (普通模式和 CTC模式时)
如何写表 达式判断 是否有溢 出 实验板上的主控芯片AVR ATMega128:
有四个定时器/计数器 – 两个具有独立预分频器、比较器功能、PWM输出的 8位定时器/计数器(T/C0, T/C2 ) – 两个具有预分频器、比较器功能、 PWM输出、捕 捉功能的16位定时器/计数器(T/C1, T/C3 )
本堂课主要讨论 定时器/计数器1
4.中断服务函数
//外部中断函数
SIGNAL(SIG_INTERRUPT5) {

}
second=0;//中断发生后需做的事情
三、DS1302模块 1.简单介绍
时钟计数功能,年计数可达2100。
DS1302包括时钟/日历寄存器和31字节的
数据暂存寄存器。
2.如何将年月日写入DS1302中
模块电路功能编程(下)
时间控制模块—DS1302芯片的控制编程
双C工作室
复习
1.实验板的电路图 – 控制编程--针对实验板 – 所有的元器件控制--要查看电路图--确定要 它们是由哪些端口或哪些接口来控制
2.实验板上控制数码管 – 用SPI发送数据到74HC595上,PB端口的高 四位作为数码管选通通道
RST_SET; /*启动DS1302总线*/ /*写入目标地址:addr*/ IO_OUT; addr = addr & 0xFE;/*最低位置零*/ for (i = 0; i < 8; i ++) { if (addr & 0x01) IO_SET; else IO_CLR; SCK_SET; SCK_CLR; addr = addr >> 1; }

采用51单片机控制的DS1302时钟程序

采用51单片机控制的DS1302时钟程序

采用51单片机控制的DS1302时钟程序/*********************************************************************/ /* 实时时钟模块时钟芯片型号:DS1302 *//*//*********************************************************************/ sbit T_CLK = P2^7; /*实时时钟时钟线引脚 */sbit T_IO = P1^4; /*实时时钟数据线引脚 */sbit T_RST = P1^5; /*实时时钟复位线引脚 *//******************************************************************** ** 名称: v_RTInputByte* 说明:* 功能: 往DS1302写入1Byte数据* 调用:* 输入: ucDa 写入的数据* 返回值: 无***********************************************************************/ void v_RTInputByte(uchar ucDa){uchar i;ACC = ucDa;for(i=8; i>0; i--){T_IO = ACC0; /*相当于汇编中的 RRC */T_CLK = 1;T_CLK = 0;ACC = ACC >> 1;}}/******************************************************************** ** 名称: uchar uc_RTOutputByte* 说明:* 功能: 从DS1302读取1Byte数据* 调用:* 输入:* 返回值: ACC***********************************************************************/ uchar uc_RTOutputByte(void){uchar i;for(i=8; i>0; i--){ACC = ACC >>1; /*相当于汇编中的 RRC */ACC7 = T_IO;T_CLK = 1;T_CLK = 0;}return(ACC);}/******************************************************************** ** 名称: v_W1302* 说明: 先写地址,后写命令/数据* 功能: 往DS1302写入数据* 调用: v_RTInputByte()* 输入: ucAddr: DS1302地址, ucDa: 要写的数据* 返回值: 无***********************************************************************/ void v_W1302(uchar ucAddr, uchar ucDa){T_RST = 0;T_CLK = 0;T_RST = 1;v_RTInputByte(ucAddr); /* 地址,命令 */v_RTInputByte(ucDa); /* 写1Byte数据*/T_CLK = 1;T_RST =0;}/******************************************************************** ** 名称: uc_R1302* 说明: 先写地址,后读命令/数据* 功能: 读取DS1302某地址的数据* 调用: v_RTInputByte() , uc_RTOutputByte()* 输入: ucAddr: DS1302地址* 返回值: ucDa :读取的数据***********************************************************************/ uchar uc_R1302(uchar ucAddr){uchar 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);}/******************************************************************** ** 名称: v_BurstW1302T* 说明: 先写地址,后写数据(时钟多字节方式)* 功能: 往DS1302写入时钟数据(多字节方式)* 调用: v_RTInputByte()* 输入: pSecDa: 时钟数据地址格式为: 秒分时日月星期年控制* 8Byte (BCD码) 1B 1B 1B 1B 1B 1B 1B 1B* 返回值: 无***********************************************************************/ void v_BurstW1302T(uchar *pSecDa){uchar 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;}/******************************************************************** ** 名称: v_BurstR1302T* 说明: 先写地址,后读命令/数据(时钟多字节方式)* 功能: 读取DS1302时钟数据* 调用: v_RTInputByte() , uc_RTOutputByte()* 输入: pSecDa: 时钟数据地址格式为: 秒分时日月星期年* 7Byte (BCD码) 1B 1B 1B 1B 1B 1B 1B* 返回值: ucDa :读取的数据***********************************************************************/ void v_BurstR1302T(uchar *pSecDa){uchar 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;}/******************************************************************** ** 名称: v_BurstW1302R* 说明: 先写地址,后写数据(寄存器多字节方式)* 功能: 往DS1302寄存器数写入数据(多字节方式)* 调用: v_RTInputByte()* 输入: pReDa: 寄存器数据地址* 返回值: 无***********************************************************************/ void v_BurstW1302R(uchar *pReDa){uchar 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;}/******************************************************************** ** 名称: uc_BurstR1302R* 说明: 先写地址,后读命令/数据(寄存器多字节方式)* 功能: 读取DS1302寄存器数据* 调用: v_RTInputByte() , uc_RTOutputByte()* 输入: pReDa: 寄存器数据地址* 返回值: 无***********************************************************************/ void v_BurstR1302R(uchar *pReDa){uchar 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;}/******************************************************************** ** 名称: v_Set1302* 说明:* 功能: 设置初始时间* 调用: v_W1302()* 输入: pSecDa: 初始时间地址。

DS1302时钟芯片简单操作及BCD相关注意事项

DS1302时钟芯片简单操作及BCD相关注意事项

DS1302 时钟芯片简单操作及BCD 相关注意事项
ds1302 是具有时钟功能的芯片,一旦启动,可以自动计时,内部含有年月日时分秒寄存器等。

先说下我这几天遇到的问题,其实归结起来满简单的一个问题,针对
ds1302 芯片的读写字节操作满简单的,见附表的datasheet,但这里要强调的是往ds1302 芯片写数据或者是读数据,在程序执行上一般会分别调用先后调用往ds1302 写一个字节或者读一个字节的方法(当然这两个方法得自己写)。

不过记得在调用这两个方法的过程中要保持CE(即芯片的置位端)持续为高电平,切不可写完一个字节就将置位端拉低,接着要写下一个字节又把置位端
拉高。

现在看看下面的代码:
sbit clk = P3;//时钟
sbit io = P3; //数据
sbit reset = P3 ;// DS1302 复位
/写一字节到ds1302
void write_byte(uchar dat)
{。

按键可调ds1302时钟显示

按键可调ds1302时钟显示

按键可调ds1302时钟显示(亲测可用)* 实验说明:本例程为四键控制时钟,k1键按下后进入时钟的调整状态,k2按下时钟上* * k3按下时钟下调,调好设定的时钟后按下k4时钟进入走时状态* *****************************************************************************/ #include<reg52.h>#include <intrins.h>sbit SCK=P3^6; //时钟sbit SDA=P3^4; //数据sbit RST = P3^5;// DS1302复位sbit k1=P1^0; //sbit k2=P1^1;sbit k3=P1^2;sbit k4=P1^3;sbit LS138A=P2^2; //sbit LS138B=P2^3;sbit LS138C=P2^4;bit ReadRTC_Flag;//定义读DS1302标志bit mie;unsigned char x,t1,xuan,shan;unsigned char l_tmpdate[7];unsigned char l_tmpdisplay[8];code unsigned char write_rtc_address[7]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c}; //秒分时日月周年最低位读写位code unsigned char read_rtc_address[7]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};code unsigned char table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40,0x00};//共阴数码管0-9 '-' '熄灭‘表/******************************************************************//* 函数声明*//******************************************************************/void Write_Ds1302_byte(unsigned char temp);void Write_Ds1302( unsigned char address,unsigned char dat );unsigned char Read_Ds1302 ( unsigned char address );void Read_RTC(void);//read RTCvoid Set_RTC(void); //set RTCvoid InitTIMER0(void);//inital timer0void tiao_time(); //时间调整unsigned char key(); //按键函数void shanshuo(); // 闪烁函数/******************************************************************//* 主函数*//******************************************************************/void main(void){InitTIMER0(); //初始化定时器0//Set_RTC(); //写入时钟值,如果使用备用电池时候,不需要没每次上电写入,此程序应该屏蔽while(1){if(ReadRTC_Flag){ReadRTC_Flag=0;tiao_time();if(x==0) Read_RTC(); //l_tmpdisplay[0]=l_tmpdate[2]/16; //数据的转换,因我们采用数码管0~9的显示,将数据分开l_tmpdisplay[1]=l_tmpdate[2]&0x0f;l_tmpdisplay[2]=10; //加入"-"l_tmpdisplay[3]=l_tmpdate[1]/16;l_tmpdisplay[4]=l_tmpdate[1]&0x0f;l_tmpdisplay[5]=10;l_tmpdisplay[6]=l_tmpdate[0]/16;l_tmpdisplay[7]=l_tmpdate[0]&0x0f;if(shan==1) // 进入调整状态后闪烁{shanshuo(); //调用闪烁函数if(mie==1) //闪烁就是亮灭相间switch(xuan) //判断哪位闪烁{case 1:l_tmpdisplay[7]=11,l_tmpdisplay[6]=11;break;case 2:l_tmpdisplay[4]=11,l_tmpdisplay[3]=11;break;case 3:l_tmpdisplay[1]=11,l_tmpdisplay[0]=11;break;}}}}}/******************************************************************//* 时间调整函数*//******************************************************************/void tiao_time(){ unsigned char miao,fen,shi,y;switch(key()) //判断哪个键按下{case 1: x=1;y++;xuan++; //k1按下后进入调整状态并且计数应该调整哪位if(y>2) y=2;if(y==1) Read_RTC();if(xuan>3) xuan=1;miao=l_tmpdate[0];shan=1; break; //调整时该位闪烁case 2: //k2按下为时钟上调switch(xuan) //判断调整哪位{ case 1: //按k1一次调秒miao++;if((miao%16)>=10) miao=miao+6; //由于显示处理时是以十六进制处理而miao++是十进制需要出来才能正常显示if(miao==96) miao=0; //加到59后重为0l_tmpdate[0]=miao; break;case 2: //按k1两次调分fen++;if((fen%16)>=10) fen=fen+6;if(fen==96) fen=0;l_tmpdate[1]=fen; break;case 3: //按k1三次调时shi++;if((shi%16)>=10) shi=shi+6;if(shi==36) shi=0; //加到23重为0l_tmpdate[2]=shi; break;}break;case 3: //按下k3时钟下调switch(xuan){case 1: //调秒miao--;if((miao%16)>=10) miao=miao-6;if(miao==0) miao=89; //减到0后重为59l_tmpdate[0]=miao; break;case 2: //调分fen--;if((fen%16)>=10) fen=fen-6;if(fen==0) fen=89;l_tmpdate[1]=fen; break;case 3: //调时shi--;if((shi%16)>=10) shi=shi-6;if(shi==0) shi=30; //减到0重为23l_tmpdate[2]=shi; break;}break;case 4: //k4键按下时钟进入走时状态miao=miao-miao/16*6; //由于时钟在显示的时候时间经过十六进制处理而时钟的设定是十进制处理所以需要数据转换l_tmpdate[0]=miao;fen=fen-fen/16*6;l_tmpdate[1]=fen;shi=shi-shi/16*6;l_tmpdate[2]=shi;Set_RTC(); //把设置的数据压到ds1302中x=0;y=0;shan=0;xuan=0; break;}}/******************************************************************//* 闪烁函数*//******************************************************************/void shanshuo(){for(t1=0;t1<=200;t1++);mie=~mie;}/******************************************************************//* 按键函数*//******************************************************************/unsigned char key(){unsigned char keyzhi;P1=0xff;if(P1!=0xff) //有键按下{if(k1==0) keyzhi=1; //判断哪个键按下if(k2==0) keyzhi=2;if(k3==0) keyzhi=3;if(k4==0) keyzhi=4;}elsekeyzhi=0; //没键按下返回为0 while(P1!=0xff); //判断按键是否释放return keyzhi; //返回keyzhi的值}/******************************************************************//* 定时器0初始化*//******************************************************************/void InitTIMER0(void){TMOD|=0x01;//定时器设置16位TH0=0xef;TL0=0xf0;ET0=1;TR0=1;EA=1;}/******************************************************************//* 写一个字节*//******************************************************************/void Write_Ds1302_Byte(unsigned char temp){unsigned char i;for (i=0;i<8;i++) //循环8次写入数据{SCK=0;SDA=temp&0x01; //每次传输低字节temp>>=1; //右移一位SCK=1;}}/******************************************************************//* 写入DS1302 *//******************************************************************/void Write_Ds1302( unsigned char address,unsigned char dat ){_nop_();SCK=0;_nop_();RST=1;_nop_(); //启动Write_Ds1302_Byte(address); //发送地址Write_Ds1302_Byte(dat); //发送数据RST=0; //恢复}/******************************************************************/ /* 读出DS1302数据*/ /******************************************************************/ unsigned char Read_Ds1302 ( unsigned char address ){unsigned char i,temp=0x00;RST=0;_nop_();_nop_();SCK=0;_nop_();_nop_();RST=1;_nop_();_nop_();Write_Ds1302_Byte(address);for (i=0;i<8;i++) //循环8次读取数据{if(SDA)temp|=0x80; //每次传输低字节SCK=0;temp>>=1; //右移一位_nop_();_nop_();_nop_();SCK=1;}RST=0;_nop_(); //以下为DS1302复位的稳定时间_nop_();RST=0;SCK=0;_nop_();_nop_();_nop_();SCK=1;_nop_();_nop_();SDA=0;_nop_();_nop_();SDA=1;_nop_();_nop_();return (temp); //返回}/******************************************************************/ /* 读时钟数据*/ /******************************************************************/ void Read_RTC(void) //读取日历{unsigned char i,*p;p=read_rtc_address; //地址传递for(i=0;i<7;i++) //分7次读取秒分时日月周年{l_tmpdate[i]=Read_Ds1302(*p);p++;}}/******************************************************************/ /* 设定时钟数据*/ /******************************************************************/ void Set_RTC(void) //设定日历{unsigned char i,*p,tmp;for(i=0;i<7;i++){ //BCD处理tmp=l_tmpdate[i]/10;l_tmpdate[i]=l_tmpdate[i]%10;l_tmpdate[i]=l_tmpdate[i]+tmp*16;}Write_Ds1302(0x8E,0X00);p=write_rtc_address; //传地址for(i=0;i<7;i++) //7次写入秒分时日月周年{Write_Ds1302(*p,l_tmpdate[i]);p++;}Write_Ds1302(0x8E,0x80);}/******************************************************************/ /* 定时器中断函数*/ /******************************************************************/ void tim(void) interrupt 1 using 1//中断,用于数码管扫描{static unsigned char i,num;TH0=0xf5;TL0=0xe0;P0=table[l_tmpdisplay[i]]; //查表法得到要显示数字的数码段switch(i){case 0:LS138A=0; LS138B=0; LS138C=0; break;case 1:LS138A=1; LS138B=0; LS138C=0; break;case 2:LS138A=0; LS138B=1; LS138C=0; break;case 3:LS138A=1; LS138B=1; LS138C=0; break;case 4:LS138A=0; LS138B=0; LS138C=1; break;case 5:LS138A=1; LS138B=0; LS138C=1; break;case 6:LS138A=0; LS138B=1; LS138C=1; break;case 7:LS138A=1; LS138B=1; LS138C=1; break;}i++;if(i==8){i=0;num++;if(10==num) //隔段时间读取1302的数据。

ds1302与单片机的连接,51单片机操作ds1302流程展示

ds1302与单片机的连接,51单片机操作ds1302流程展示

ds1302 与单片机的连接,51 单片机操作ds1302 流程
展示
在许多单片机系统中常需要一些与时间有关的控制这就有需要使用实时时钟,因为在测控系统中需要做一些特殊数据的记录及其出现时间的记
录。

那幺实时时钟就能够很好的解决这个问题,今天我们就来谈谈ds1302 与单片机之间是如何作用联系的,单片机又是如何对时钟芯片进行操作的,一
起来了解一下。

51 单片机操作ds1302 流程展示
DS1302 通过3 根线与MCU 连接串行数据发送,接收时钟信号由MCU 发送,可外接备用电池以便主电源断电后不丢失数据,并可编程对备用电源充电。

DS1302 的结构如下:。

ds1302时钟程序详解,ds1302程序流程图

ds1302时钟程序详解,ds1302程序流程图

ds1302时钟程序详解,ds1302程序流程图(C程序)ds1302时钟程序详解DS1302 的控制字如图2所示。

控制字节的最高有效位(位7)必须是逻辑1,如果它为0,则不能把数据写入DS1302中,位6如果为0,则表示存取日历时钟数据,为1表示存取RAM数据;位5至位1指示操作单元的地址;最低有效位(位0)如为0表示要进行写操作,为1表示进行读操作,控制字节总是从最低位开始输出。

数据输入输出(I/O)在控制指令字输入后的下一个SCLK时钟的上升沿时,数据被写入DS1302,数据输入从低位即位0开始。

同样,在紧跟8位的控制指令字后的下一个SCLK脉冲的下降沿读出DS1302的数据,读出数据时从低位0位到高位7。

DS1302的寄存器DS1302有12个寄存器,其中有7个寄存器与日历、时钟相关,存放的数据位为BCD码形式,其日历、时间寄存器及其控制字见表1。

此外,DS1302 还有年份寄存器、控制寄存器、充电寄存器、时钟突发寄存器及与RAM相关的寄存器等。

时钟突发寄存器可一次性顺序读写除充电寄存器外的所有寄存器内容。

DS1302与RAM相关的寄存器分为两类:一类是单个RAM单元,共31个,每个单元组态为一个8位的字节,其命令控制字为C0H~FDH,其中奇数为读操作,偶数为写操作;另一类为突发方式下的RAM寄存器,此方式下可一次性读写所有的RAM的31个字节,命令控制字为FEH(写)、FFH(读)。

ds1302程序流程图DS1302实时时间流程图4示出DS1302的实时时间流程。

根据此流程框图,不难采集实时时间。

下面结合流程图对DS1302的基本操作进行编程:根据本人在调试中遇到的问题,特作如下说明:DS1302 与微处理器进行数据交换时,首先由微处理器向电路发送命令字节,命令字节最高位MSB(D7)必须为逻辑1,如果D7=0,则禁止写DS1302,即写保护;D6=0,指定时钟数据,D6=1,指定RAM数据;D5~D1指定输入或输出的特定寄存器;最低位L SB(D0)为逻辑0,指定写操作(输入), D0=1,指定读操作(输出)。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

DS1302 是美国DALLAS公司推出的一种高性能、低功耗、带RAM的实时时钟电路,它可以对年、月、日、周日、时、分、秒进行计时,具有闰年补偿功能,工作电压为2.5V~5.5V。

采用三线接口与CPU进行同步通信,并可采用突发方式一次传送多个字节的时钟信号或RAM数据。

DS1302内部有一个31×8的用于临时性存放数据的RAM寄存器。

DS1302是DS1202的升级产品,与DS1202兼容,但增加了主电源/后备电源双电源引脚,同时提供了对后备电源进行涓细电流充电的能力.
RST是复位/片选线,通过把RST输入驱动置高电平来启动所有的数据传送。

RST输入有两种功能:首先,RST接通控制逻辑,允许地址/命令序列送入移位寄存器;其次,RST提供终止单字节或多字节数据的传送手段。

当RST为高电平时,所有的数据传送被初始化,允许对DS1302进行操作。

如果在传送过程中RST置为低电平,则会终止此次数据传送,I/O引脚变为高阻态。

上电运行时,在Vcc>2.0V之前,RST必须保持低电平。

只有在SCLK 为低电平时,才能将RST置为高电平。

时钟相关寄存器:时钟数据为BCD码格式,秒寄存器的CH位:时钟暂停位,为1是,振荡器停止工作,进入低功耗。

小时寄存器:最高位12/24:为1时表示12小时模式,0表示24小时模式。

第5位A/P,1表示下午,0表示上午。

DS1302命令控制字:
DS1302的RAM共31个,寄存器地址范围:C0H~FDH,其中奇数为读操作,偶数为写操作
DS1302的读写时序:通过控制RST端为高电平启动读写操作,首先发送8位命令控制字,指明读操作还是写操作,及读写的地址。

数据从低到高位顺序传输。

上电时,RST脚必须为低电平,当把RST置为高电平前,SCLK必须为低电平。

写过程:
一、启动准备:RST为低电平,SCLK为低电平--
PORTB&=~(1<<PB2); PORTB&=~(1<<PB0);
二、启动读写开始信号:将RST置为高电平--- PORTB|=(1<<PB2);
三、发送要写入地址的命令字节数据,如写秒寄存器,命令字节为80H,write_byte(0x80);
四、延时10ms,SCLK 置低电平,----delay(10);PORTB&=~(1<<PB0);
五、发送要写入秒寄存器的数据; write_byte(0x02);
六、结束写入过程:SCLK清0,RST置为低电平。

PORTB&=~(1<<PB2); PORTB&=~(1<<PB0);
读过程:
一、启动准备:RST为低电平,SCLK为低电平--
PORTB&=~(1<<PB2); PORTB&=~(1<<PB0);
二、启动读写开始信号:将RST置为高电平--- PORTB|=(1<<PB2);
三、发送要读取数据的地址的命令字节数据,如读秒寄存器,命令字节为81H,write_byte(0x81);
四、延时10ms,SCLK 置低电平,----delay(10);PORTB&=~(1<<PB0);
五、读取秒寄存器的数据; read_byte(0x02);
六、结束读取过程:SCLK清0,RST置为低电平。

PORTB&=~(1<<PB2); PORTB&=~(1<<PB0);
写入一个字节数据的代码:
/********向DS1302写一个字节数据********/
void write_byte(uchar dat)
{
uchar i;
for(i = 0;i < 8;i++) //写8位,低位在前
{
PORTB&=~(1<<PB0);//SCLK置0,产生移位时钟
if(dat & 0x01) //写数据位
{
PORTB|=(1<<PB1); //如果写入字节的第0位为1,则PB1脚置1
}
else
{
PORTB&=~(1<<PB1); // //如果写入字节的第0位为0,则PB1脚置0 }
Delay_us(10); //延时
PORTB|=(1<<PB0); //SCLK置1,产生移位时钟
dat >>= 1; //数据右移1位
}
}
读取一个字节的过程:
/********从DS1302读一个字节数据********/
uchar read_byte(void)
{
uchar i,dat = 0; //dat存放读出的数据,初始化为0
DDRB|=(1<<PB1); //PB1置为输入
PORTB&=~(1<<PB1); //不带上位电阻
for(i= 0;i< 7;i++) //读7位(注意,不是8位
{
PORB|=(1<<PB0); //SCLK 置1
Delay_us(10);
PORTB&=~(1<<PB0); //SCLK 置0
Delay_us(10); //延时
if(PINB&0x02) //读数据端口状态
{dat=dat|0x80;} //如果PB1为1,则将dat 的最高位置1
else
{dat=dat&0x7f;} 如果PB1为0,则将dat 的最高位置0
PORB|=(1<<PB0); //SCLK 置1
dat=dat>>1; //数据右移一位
}
DDRB&=~(1<<PB1); // 恢复为输出
return dat; //返回读出的数据
}
小企鹅diy 科学探究学习网
更多文章转到/wqb_lmkj/blog文章分类单片机。

相关文档
最新文档