DS1302时钟芯片单片机控制操作步骤
ds1302时钟芯片汇编控制程序
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 的基本特性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芯片的控制编程
定时器/计数器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时钟程序/*********************************************************************/ /* 实时时钟模块时钟芯片型号: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 是具有时钟功能的芯片,一旦启动,可以自动计时,内部含有年月日时分秒寄存器等。
先说下我这几天遇到的问题,其实归结起来满简单的一个问题,针对
ds1302 芯片的读写字节操作满简单的,见附表的datasheet,但这里要强调的是往ds1302 芯片写数据或者是读数据,在程序执行上一般会分别调用先后调用往ds1302 写一个字节或者读一个字节的方法(当然这两个方法得自己写)。
不过记得在调用这两个方法的过程中要保持CE(即芯片的置位端)持续为高电平,切不可写完一个字节就将置位端拉低,接着要写下一个字节又把置位端
拉高。
现在看看下面的代码:
sbit clk = P3;//时钟
sbit io = P3; //数据
sbit reset = P3 ;// DS1302 复位
/写一字节到ds1302
void write_byte(uchar dat)
{。
按键可调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 通过3 根线与MCU 连接串行数据发送,接收时钟信号由MCU 发送,可外接备用电池以便主电源断电后不丢失数据,并可编程对备用电源充电。
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,指定读操作(输出)。
ds1302实时时钟程序说明
DS1302实时时钟在数码管上进行实时显示的程序
#include<reg52.h>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
sbit rst=P2^4;
sbit io=P2^0;
}
write_ds1302(0x8e,0x80); //进行写保护
}
void read_rtc()
{
uchar i;
for(i=0;i<7;i++)
{
time_data[i]=read_ds1302(read_add[i]);
}
}
void time_pros()
{
disp[0]=time_data[6]%16;//将BCD码(这里与十六进制没有区别)进行十位个位的分离
{
j=time_data[i]/10;//十位5
time_data[i]%=10;//各位8
time_data[i]=time_data[i]+j*16;
}
write_ds1302(0x8e,0x00);//去除写保护
for(i=0;i<7;i++)
{
write_ds1302(write_add[i],time_data[i]);
disp[1]=time_data[6]/16;
disp[2]=17;
disp[3]=time_data[5]%16;
disp[4]=time_data[5]/16;
disp[5]=17;
51单片机 ds1302万年历 时钟显示
//DS1302时钟芯片程序#include <reg52.h>#define uchar unsigned char#define uint unsigned intsbit CLK=P2^3; //定义口sbit IO=P2^4;sbit RST=P2^5;sbit ACC7=ACC^7;sbit ACC0=ACC^0;uchar a[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}, //定义数码管显示码b[8]={0x00,0x00,0x12,0x23,0x11,0x07,0x08,0xbe},//写入时钟数据,最后be突发访问c[7],s,s1,ml1,mh1,ml2,mh2,ml3,mh3; //c存放读.出时钟数据void delay(uint z) // 延时{uint i;uchar j;for(i=z;i>0;i--)for(j=200;j>0;j++);}// 显示子程序void display(uchar mh1,uchar ml1,uchar mh2,uchar ml2,uchar mh3,uchar ml3){uchar x,k,r;for(k=0;k<80;k++){for(r=0;r<8;r++){x=P2&0XF8;P2=x+r ;if(r==2||r==5){ P0=0XBF;delay(3);}//------秒-------if(r==0){P0=a[ml1] ;delay(3) ;}if(r==1){P0=a[mh1] ;delay(3) ;}//------fen---------if(r==3){P0=a[ml2] ;delay(3) ;}if(r==4){P0=a[mh2] ;delay(3) ;}//-----shi---------if(r==6){P0=a[ml3] ;delay(3) ;}if(r==7){P0=a[mh3] ;delay(3) ;}delay(3);}}}//********DS1302读写程序************void w(uchar u) //写入1位字节{uchar i;ACC = u;for(i=8; i>0; i--){IO = ACC0;CLK = 1;CLK = 0;ACC = ACC >> 1;}}uchar r(void) //读出1位字节{uchar i;for(i=8; i>0; i--){ACC = ACC >>1;ACC7 = IO;CLK = 1;CLK = 0;}return(ACC);}void W1302(uchar ucAddr, uchar ucDa){RST = 0;CLK = 0;RST = 1;w(ucAddr); // 地址,命令w(ucDa); //写1Byte数据CLK = 1;RST = 0;}void wclock(uchar *p) //写入时钟多字节数据{uchar i;// W1302(0x80,0x00); //停止时钟W1302(0x8e,0x00); // 允许写RST=0;CLK=0;RST=1;w(0xbe); //写多字节命令for(i=8;i>0;i--){w(*p); //按数组指针逐个写入,写入数据在主函数调用时指向b数组p++;}W1302(0x00,0x50); //启动定时器CLK=1;RST=0;}void rclock(uchar *p) //读出时钟多字节数据{uchar i;RST=0;CLK=0;RST=1;w(0xbf);for(i=7;i>0;i--){*p=r();p++;}CLK=1;RST=0;}void main(void){uchar mh,ml,fh,fl,sh,sl,z,v,q,e,y,t,k;wclock(b);while(1){rclock(c);mh=(c[0]&0xf0)>>4;ml=c[0]&0x0f;fh=(c[1]&0xf0)>>4;fl=c[1]&0x0f;sh=(c[2]&0xf0)>>4;sl=c[2]&0x0f;display(mh,ml,fh,fl,sh,sl);if(mh==3&&ml==0){ for(k=0;k<3;k++){z=(c[3]&0xf0)>>4;v=c[3]&0x0f;q=(c[4]&0xf0)>>4;e=c[4]&0x0f;y=(c[6]&0xf0)>>4;t=c[6]&0x0f;display(z,v,q,e,y,t);}}}}。
DS1302原理及程序说明
DS1302原理及程序说明DS1302 是DALLAS 公司推出的涓流充电时钟芯片,内含有一个实时时钟/日历和31字节静态RAM ,通过简单的串行接口与单片机进行通信。
实时时钟/日历电路提供秒、分、时、日、日期、月、年的信息,每月的天数和闰年的天数可自动调整,时钟操作可通过AM/PM 指示决定采用24 或12 小时格式。
DS1302 与单片机之间能简单地采用同步串行的方式进行,DS1302的引脚命名如图1-1所示。
通信仅需用到三根信号线:(1)CE 片选,(2)I/O 数据线,(3)SCLK 串行时钟,DS1302与CPU 的连接如图1-2所示。
时钟/RAM 的读/写数据以一个字节或多字节的字符组方式通信,DS1302工作时功耗很低,保持数据和时钟信息时功率小于1mW 。
DS1302具有双电源管脚,用于主电源和备份电源供应Vcc1,为可编程涓流充电电源附加七个字节存储器,它广泛应用于电话传真便携式仪器以及电池供电的仪器仪表等产品领域。
DS1302主要的性能指标如下:实时时钟具有能计算2100 年之前的秒、分、时、日、日期、星期、月、年的能力,还有闰年调整的能力31× 8 位暂存数据存储RAM 串行I/O 口方式,使得管脚数量最少宽范围工作电压2.0~ 5.5V工作电流2.0V 时,小于300nA读/写时钟或RAM 数据时有两种传送方式:单字节传送和多字节传送字符组方式8 脚DIP 封装或可选的8 脚SOIC 封装根据表面装配简单3 线接口与TTL 兼容Vcc=5V 。
DS1302的读写模式工作时序如图1-3和图1-4所示。
图1-3 单字节读模式图1-4 单字节写模式注:在多字节模式下,SCLK 发出同步脉冲,CS 须持续保持高电平直到多字节操作结束,图1-1 DS1302引脚图1-2 DS1302与CPU 接口DS1302内部寄存器的地址定义如表1-1所示。
表1-1 寄存器的地址及定义实验说明1. DS1302与51单片机的连接IO ——P2.7:串行数据输入/输出引脚SCLK ——P2.6:串行时钟引脚CE ——P2.4:片选CE2. LCD 与单片机连接;************************************************************************* ; LCD Module LMB1602 与单片机连接:;************************************************************************* ; 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ;Vss Vdd V o RS R/W E D0 D1 D2 D3 D4 D5 D6 D7 BLA BLK ; 0V +5V 0V P32 P33 P34 ---------------- P1[0..7] ---------------- +5V 0V;*************************************************************************3. LCD 显示功能说明LCD1602显示格式如图1-5所示。
SPI总线的DS1302实时钟控制
SPI总线的DS1302实时钟控制实验四SPI总线的DS1302实时钟控制一、实验目的1、了解电子电路PROTEUS软件的在单片机方面的仿真应用2、掌握具有SPI总线DS1302、MAX7219芯片的应用及编程二、实验要求在PROTEUS环境下,利用DS1302实时钟芯片实现时间、日期的显示,并且具有调节时间、日期的功能,显示用共阴极LED显示。
用串行芯片MAX7219驱动LED显示.实现此功能的电路原理图如下所示:1、显示“星期”的共阳极二极管接到单片机的P0口,P0口数据线接上拉电阻;2、显示“时间”或“日期”,是采用MAX7219控制共阴极LED来实现3、DS1302的IO脚接单片机的P1.1,时钟信号SCLK接单片机P1.0,复位信号/RST 接单片机P1.2。
DS1302的晶振在这里可以不接,电源、地线都省略。
4、MAX7219是用来驱动“时间”或“日期”的LED显示的。
MAX7219的DIN信号脚接单片机的P2.0,/LOAD接单片机的P2.1,CLK接单片机的P2.2;5、时间/日期的调整:按下调整键,再分别按相应的“星期”、“年”、“月”、“日”,“时”、“分”、“秒“键,即可以调整时间/日期;6、在正常显示时,按下“时间/日期“切换键,即可以在显示时间或日期来回切换。
三、PROTEUS环境下的硬件设计1、打开PROTEUS ISIS,在PROTEUS ISIS编辑窗口中单击列表上的“P”按钮,在PROTEUS编辑窗口添加完元器件,连线。
如附图1。
四、软件设计在KEIL环境下编辑、编译程序,生成*.HEX文件后,装入单片机即可。
五、实验程序源程序:#include<reg51.h> //包含特殊功能寄存器库#include <DS1302.h>#include <7219.h> //该汉字库要求在你要显示的位置装入你要的汉字模(16*16)。
void main(){ Init7219(); //初始化7219Set1302(time); //设置初始时间Get1302(Curtime); //读回DS1302中的数据P0=CODE1[Curtime[5]-1];//显示星期Display1(num); //默认显示时间delay(255); //延时delay(255);while(1){ Get1302(Curtime); //取数据if(TICK==0) //判断是否更改{ t=~t;while(TICK==0){}}while (t==1){ if(WEEK==0) //更改星期{ w++;while (WEEK==0){};Get1302(Curtime);Curtime[5]=Curtime[5]+w;if(Curtime[5]==8)Curtime[5]=1;w=0;Set1302(Curtime);}else if(YEAR==0) //更改年份{ while (YEAR==0){};Get1302(Curtime);Curtime[6]=add5(Curtime[6]);Set1302(Curtime);}else if(MONTH==0) //更改月份{ while (MONTH==0){};Get1302(Curtime);Curtime[4]=add4(Curtime[4]);Set1302(Curtime);}else if(DAY==0) //更改号数{ while (DAY==0){};Get1302(Curtime);Curtime[3]=add3(Curtime[3]); Set1302(Curtime);}else if(HOUR==0) //更改时{ while (HOUR==0){};Get1302(Curtime);Curtime[2]=add2(Curtime[2]); Set1302(Curtime);}else if(MIN==0) //更改分{ while (MIN==0){};Get1302(Curtime);Curtime[1]=add1(Curtime[1]); Set1302(Curtime);}else if(SEC==0) //更改秒{ while (SEC==0){};Get1302(Curtime);Curtime[0]=0;Set1302(Curtime);}if(CHAN==0) //是否有显示切换{ n=~n;while(CHAN==0) {}}Get1302(Curtime);if(n==1) Display2(num);else Display1(num);P0=CODE1[Curtime[5]-1];if(TICK==0){ t=~t;while(TICK==0){}}}if(CHAN==0) //是否有显示切换{ n=~n;while(CHAN==0) {}}if(n==1) Display2(num);else Display1(num);}}头文件“DS1302”#ifndef __DS1302_H__#define __DS1302_H__/****/#include <7219.h>void InputByte(unsigned char Da)//把数据Da写入DS1302 的IO口,先送低位{ unsigned char i;ACC=Da;for(i=8;i>0;i--) //开始传输8个字节的数据{ IO=ACC0; //取最低位,注意DS1302的数据和地址都是从最低位开始传输的SCLK=1; //时钟线拉高,制造上升沿,SDA 的数据被传输SCLK=0; //时钟线拉低,为下一个上升沿做准备ACC=ACC>>1;}}unsigned char OutputByte(void)//读出DS1302的数据并保存在Da中{ unsigned char i;for(i=8;i>0;i--){ ACC=ACC>>1;ACC7=IO;SCLK=1;SCLK=0;}return(ACC);}void Write1302(unsigned char Addr, unsigned char Da)//写入DS1302地址和数据{ RST=0; //初始CE线置为0SCLK=0; //初始时钟线置为0RST=1; //初始CE置为1,传输开始InputByte(Addr); //地址,命令传输命令字,要写入的时间/日期地址InputByte(Da); //*写1Byte数据 //写入要修改的时间/日期SCLK =1; //时钟线拉高RST=0; //读取结束,CE置为0,结束数据的传输}unsigned char Read1302(unsigned char Addr)//根据寄存器地址读出DS1302的相应数据{ unsigned char DD;RST=0; //初始CE线置为0SCLK=0;//初始时钟线置为0RST=1; //初始CE置为1,传输开始InputByte(Addr); //地址,命令传输命令字,要读取的时间/日历地址DD=OutputByte(); //读1Byte数据读取要得到的时间/日期SCLK=1; //时钟线拉高RST =0; //读取结束,CE置为0,结束数据的传输return(DD);//得到的时间/日期}void Set1302(unsigned char *pSDa)//设置时间{ unsigned char i;unsigned char Addr=0x80;Write1302(0x8e,0x00); //控制命令,WP=0,写操作for(i =7;i>0;i--){ Write1302(Addr,*pSDa); //格式为:秒分时日月星期年pSDa++;Addr+=2;}Write1302(0x8e,0x80); //控制命令,WP=1,写保护}void Get1302(unsigned char *pSDa) { unsigned char i;unsigned char Addr=0x81;for(i=0;i<7;i++){*(pSDa+i)=Read1302(Addr);//格式为: 秒分时日月星期年Addr+=2;}}#endif头文件“7219”#ifndef __7219_H__#define __7219_H__/****/#define DECODE_MODE 0x09#define INTESITY 0x0a#define SCAN_LIMIT 0x0b#define SHUT_DOWN 0x0c#define DEISPLAY_TEST 0x0funsigned char time[]={0x00,0x00,0x08,0x28,0x05,0x 06,0x11};//初始值,秒分时日月星期年unsigned char Curtime[7],num[8]; unsigned char CODE1[]={0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8};//星期,共阳极字段unsigned char CODE2[]={0x7e,0x30,0x6d,0x79,0x33,0x5b,0x5f,0x70,0x7f,0x7b};sbit RST=P1^2;sbit IO =P1^1;sbit SCLK=P1^0;sbit DIN=P2^0;sbit LOAD=P2^1;sbit CLK=P2^2;sbit WEEK=P3^0;sbit YEAR=P3^1;sbit MONTH=P3^2;sbit DAY=P3^3;sbit HOUR=P3^4;sbit MIN=P3^5;sbit SEC=P3^6;sbit TICK=P3^7;sbit CHAN=P1^7;sbit ACC0=ACC^0;sbit ACC7=ACC^7;bit n=0;bit t=0;unsigned char w=0;void Write_7219(unsigned char DATA) //MAX7219写数据函数{ unsigned char i;ACC=DATA;for(i=8;i>=1;i--){ CLK=0;DIN=ACC7;ACC=ACC<<1;CLK=1;}}void Write7219(unsigned char addr,unsigned char dat){ LOAD=0;Write_7219(addr);Write_7219(dat);LOAD=1;}void Init7219(void){ Write7219(DECODE_MODE,0x00);//译码寄存器,写入00H,对0至7位均不译码Write7219(INTESITY,0x04);//亮度调节寄存器,写入04H,实现一般的亮度显示Write7219(SCAN_LIMIT,0x07);//扫描界限寄存器,写入07H,实现0到7位数码管的显示Write7219(SHUT_DOWN,0x01);//停机寄存器,写入01H,实现正常工作Write7219(DEISPLAY_TEST,0x00);//显示测试寄存器,写入00H,实现正常工作}void delay(unsigned char m)//延时程序{ unsigned char x,y;for(x=m;x>0;x--)for(y=255;y>0;y--);}unsigned char add1(unsigned char DATA)//分、秒调整子程序{ unsigned char i,j;i=DATA&0x0f;j=DATA>>4;i++;if(i==0x0a){ i=0x00;j++;}if((j==0x06)&&(i==0x00)) //超过59就变成0 i低位,j高位{ i=0;j=0;}DATA=(j<<4)+i;return(DATA);}unsigned char add2(unsigned char DATA)//小时调整子程序{ unsigned char i,j;i=DATA%16;j=DATA>>4;i++;if(i==10) {i=0;j++;}if((j==2)&&(i==4)) //超过23就变成0,i低位,j高位{ i=0;j=0;}DATA=(j<<4)+i;return(DATA);}unsigned char add3(unsigned char DATA)//号数调整子程序{ unsigned char i,j;i=DATA%16;j=DATA>>4;i++;if(i==10) {i=0;j++;}if(((Curtime[6]/16*10+Curtime[6]%1 6)%4==0)&&(Curtime[4]==0x02)&&(j==0 x03)&&(i==0x00)){ i=1;j=0;}Elseif(((Curtime[6]/16*10+Curtime[6]%16 )%4!=0)&&(Curtime[4]==0x02)&&(j==0x 02)&&(i==0x09)){ i=1;j=0;}elseif(((Curtime[4]==0x01)||(Curtime[4] ==0x03)||(Curtime[4]==0x05)||(Curti me[4]==0x07)||(Curtime[4]==0x08)||( Curtime[4]==0x10)||(Curtime[4]==0x1 2))&&(j==0x03)&&(i==0x02)){ i=1;j=0;}elseif(((Curtime[4]==0x04)||(Curtime[4] ==0x06)||(Curtime[4]==0x09)||(Curti me[4]==0x11))&&(j==0x03)&&(i==0x01) ){ i=1;j=0;}DATA=(j<<4)+i;return(DATA);}unsigned char add4(unsigned char DATA)//月份调整子程序{ unsigned char i,j;i=DATA%16;j=DATA>>4;i++;if(i==0x0a){ i=0;j++;}if((j==0x01)&&(i==0x03))//超过12就变成0,i低位,j高位{ i=1;j=0;}DATA=(j<<4)+i;return(DATA);}unsigned char add5(unsigned char Data)//年份调整子程序{ unsigned char i,j;i=Data%16;j=Data/16;i++;if(i==0x0a){ i=0;j++;}if((j==0x0a)&&(i==0x00)){ i=0;j=0;}Data=(j<<=4)+i;return(Data);}void Display1(unsigned char *num)//显示时间{ unsigned char i,j,m=0x08;for(i=0;i<3;i++){ *num=CODE2[Curtime[i]&0x0f];Write7219(m,*num);j=Curtime[i]>>4;num++;m--;*num=CODE2[j&0x0f];Write7219(m,*num);num++;m--;if(num!=8){ *num=0x01;Write7219(m,0x01);num++;m--;}}}void Display2(unsigned char *num)//显示日期{ unsigned char i,j,m=0x08;for(i=3;i<5;i++){ *num=CODE2[Curtime[i]&0x0f];Write7219(m,*num);j=Curtime[i]>>4;num++;m--;*num=CODE2[j&0x0f];Write7219(m,*num);num++;m--;if(num!=5){ *num=0x01;Write7219(m,0x01);num++;m--;}}*num=CODE2[Curtime[6]&0x0f];W rite7219(m,*num);j=Curtime[6]>>4;n um++;m--;*num=CODE2[j&0x0f];W rite7219(m,*num);num++;m--;}#endif六、实验小结这次实验让我掌握具有SPI总线DS1302、MAX7219芯片的应用及编程,在实验中体会乐趣并掌握新知识是我一直梦寐以求的。
DS1302中文手册
DS1302中文手册一、简介DS1302是一种实时时钟芯片,主要用于计算机系统、通信设备、智能家居等领域。
本手册旨在提供DS1302的详细说明和操作方法,帮助用户正确使用该芯片。
二、芯片特性1. 基本特性:- 日期格式:年-月-日- 时间格式:时:分:秒- 温度测量范围:-55℃至+125℃- 时钟频率:32768Hz2. 时钟控制:- 时钟源选择:外部或内部- 时钟暂停功能- 时钟调制功能三、引脚定义DS1302具有8个引脚,分别为:1. X1:外部时钟输入端2. X2:外部时钟输出端3. Vcc:供电正极4. GND:地5. SDA:串行数据输入/输出端6. SCLK:串行数据时钟输入端7. RST:复位控制端8. BAT:电池输入端四、工作原理DS1302基于Bipolar CMOS技术,通过外部提供的时钟信号进行时间计数和存储。
芯片内部包含时钟控制电路、RAM存储器、温度计和时钟计数器等功能模块,通过串行通信协议与外部设备进行数据传输。
五、使用方法1. 芯片初始化:- 将X1和X2连接外部时钟源- Vcc与电源正极相连- GND与地相连2. 设定时间:- 通过串行数据输入将年、月、日、时、分、秒信息写入相应寄存器- 通过串行数据输入将温度信息写入相应寄存器(可选)3. 读取时间:- 通过串行数据输出获取年、月、日、时、分、秒信息- 通过串行数据输出获取温度信息(可选)4. 设置时钟暂停:- 通过串行数据输入将时钟控制字节写入相应寄存器控制位,实现时钟暂停功能5. 时钟调制:- 通过串行数据输入将时钟调制字节写入相应寄存器控制位,实现时钟调制功能六、注意事项1. 确保正确接线,避免短路或浮空引脚2. 使用合适的外部时钟源,确保时钟的准确性3. 避免频繁的读写操作,以延长芯片的使用寿命4. 根据实际需求进行合理设置,避免不必要的功能开启5. 定期校准芯片时间,确保准确性七、总结本手册介绍了DS1302的特性、引脚定义、工作原理以及使用方法,并提供了一些注意事项供用户参考。
DS1302时钟程序详解
DS1302 时钟程序详解ds1302 时钟程序详解:DS1302 的控制字如图2 所示。
控制字节的最高有效位(位7)必须是逻辑1,如果它为0,则不能把数据写入DS1302 中,位6 如果为0,则表示存取日历时钟数据,为1 表示存取RAM 数据;位5 至位1 指示操作单元的地址;最低有效位(位0)如为0 表示要进行写操作,为1 表示进行读操作,控制字节总是从最低位开始输出。
2.3 数据输入输出(I/O)在控制指令字输入后的下一个SCLK 时钟的上升沿时,数据被写入DS1302,数据输入从低位即位0 开始。
同样,在紧跟8 位的控制指令字后的下一个SCLK 脉冲的下降沿读出DS1302 的数据,读出数据时从低位0 位到高位7。
2.4 DS1302 的寄存器DS1302 有12 个寄存器,其中有7 个寄存器与日历、时钟相关,存放的数据位为BCD 码形式,其日历、时间寄存器及其控制字见表1。
此外,DS1302 还有年份寄存器、控制寄存器、充电寄存器、时钟突发寄存器及与RAM 相关的寄存器等。
时钟突发寄存器可一次性顺序读写除充电寄存器外的所有寄存器内容。
DS1302 与RAM 相关的寄存器分为两类:一类是单个RAM 单元,共31 个,每个单元组态为一个8 位的字节,其命令控制字为C0H~FDH,其中奇数为读操作,偶数为写操作;另一类为突发方式下的RAM 寄存器,此方式下可一次性读写所有的RAM 的31 个字节,命令控制字为FEH(写)、FFH(读)。
ds1302 程序流程图3.2 DS1302 实时时间流程图4 示出DS1302 的实时时间流程。
根据此流程框图,不难采集实时时间。
下面结合流程图对DS1302 的基本操作进行编程:根据本人在调试中遇到的问题,特作如下说明:DS1302 与微处理器进行数据交换时,首先由微处理器向电路发送命令字节,命令字节最高位MSB(D7)必须为逻辑1,如果D7=0,则禁止写DS1302,即写保护;D6=0,指定时钟数据,D6=1,指定RAM 数据;D5~D1 指定输入或输出的特定寄存器; 最低位LSB(D0)为逻辑0,指定写操作(输入),D0=1,指定读操作(输出)。
9.1.3 单片机控制DS1302编程
9.1.3 单片机控制DS1302编程/******************************************************功能:通过A VR单片机写时间信息到DS1302,然后读取DS1302的时间信息,并显示到数码管上。
有后备电池的情况下,单片机复位或断电,不影响DS1302的时钟,即DS1302仍能正常计时。
文件名称:main.c修改时间:2012-09-19作者:YLH*****************************************************/unsigned char rec_time[7]={0x00,0x00,0x00,0x00,0x00,0x00,0x00}; //定义一个数组存储秒,分,时,日,月,周,年unsigned char seg[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//定义共阳极数码管的0~9的段码unsigned char pos[8]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01}; //数码管位置信息unsigned char time[13];/*对DS1320三个管脚和单片机的接口进行字符常量定义*/#define SCLK PORTA1_bit#define IO PORTA2_bit#define RST PORTA3_bit/*对74HC595三个管脚和单片机的接口进行字符常量定义*/#define DS PORTB5_bit#define SHCP PORTB7_bit#define STCP PORTB4_bit/*************************************************函数名:ds1302_disp_init()函数功能:初始化连接DS1302、74HC595的端口入口参数:无返回值:无************************************************/void ds1302_disp_init(){DDRA|=0x0e; //设置PA1,2,3端口方向为输出DDRB|=0xb0; //设置PB4,5,7端口方向为输出PORTA&=0xf1; //将PA1,2,3端口初始值初始化为0;PORTB&=0x4f; //将PB4,5,7端口初始值初始化为0;}/*************************************************函数名:write_byte( )函数功能:向DS1302发送一个字节入口参数:dat--要写入的地址或者数据返回值:无************************************************/void write_byte(unsigned char dat){unsigned char i;for(i=0;i<8;i++){SCLK=0; //时钟信号拉低if(dat&0x01)IO=1; //判断地址字节的最低位,1位为1则拉高IO else IO=0; //1位为0,则输入数据为0,拉低IOdelay_us(1);SCLK=1; //时钟信号拉高,产生上升沿delay_us(1);dat>>=1; //字节右移一位}}/*************************************************函数名:read_byte( )函数功能:从DS1302读出一个字节入口参数:无返回值:dat************************************************/ unsigned char read_byte(){unsigned char i, dat=0;DDA2_bit=0; //设置IO的方向为输入IO=0; //设置IO为高阻态,无上拉电阻for(i=0;i<8;i++){dat>>=1; //数据右移一位SCLK=1; //设置SCLK为高电平delay_us(1);SCLK=0; //设置SCLK为低电平,产生下降沿delay_us(1);if(PINA2_bit==1) //如果读出的数据为1dat|=0x80; //数据位1,则写入1}DDA2_bit=1; //将IO口的方向改为输出return dat; //返回读取到的数据}/*************************************************函数名:ds1302_write_byte( )函数功能:向DS1302对应地址发送一个字节入口参数:add--要写入数据的地址;dat--要写入的数据返回值:无************************************************/void ds1302_write_byte(unsigned char add,unsigned char dat){RST=0; //将RST拉低SCLK=0; //将SCLK拉低RST=1; //将RST拉高write_byte(add); //写入地址字节write_byte(dat); //写入数据SCLK=1; //将SCLK拉高RST=0; //将RST拉低}/*************************************************函数名:ds1302_read_byte( )函数功能:从DS1302对应地址读取一个字节入口参数:add--要读出数据所在的地址返回值:shuju************************************************/ unsigned char ds1302_read_byte(unsigned char add){unsigned char shuju; //定义一个变量,存储返回的数据RST=0; //将RST拉低SCLK=0; //将SCLK拉低RST=1; //将RST拉高write_byte(add); //写入地址字节shuju=read_byte(); //读取该地址字节的数据SCLK=1; //将SCLK拉高RST=0; //将RST拉低return shuju; //返回读到的数据}/*************************************************函数名:process_dat( )函数功能:处理单片机读取DS1302得到的时间信息,提取数值入口参数:无返回值:无************************************************/void process_dat()time[0]=rec_time[0]&0x0f; //提取秒的个位time[1]=(rec_time[0]&0x70)>>4; //提取秒的十位time[2]=rec_time[1]&0x0f; //提取分的个位time[3]=(rec_time[1]&0x70)>>4; //提取分的十位time[4]=rec_time[2]&0x0f; //提取小时的个位time[5]=(rec_time[2]&0x30)>>4; //提取小时的十位time[6]=rec_time[3]&0x0f; //提取日的个位time[7]=(rec_time[3]&0x30)>>4; //提取日的十位time[8]=rec_time[4]&0x0f; //提取月的个位time[9]=(rec_time[4]&0x10)>>4; //提取月的十位time[10]=rec_time[5]&0x07; //提取周time[11]=rec_time[6]&0x0f; //提取年的个位time[12]=(rec_time[6]&0xf0)>>4; //提取年的十位}/*************************************************函数名:send_595_byte( )函数功能:单片机向74HC595发送一个字节入口参数:dat返回值:无************************************************/void send_595_byte(unsigned char dat){unsigned char i;for(i=0;i<8;i++){SHCP=0; //移位时钟拉低delay_us(5); //延时if(dat&0x80)DS=1; //如果提取到的最高位为1,则数据线输出1elseDS=0;SHCP=1; //移位时钟拉高,产生上升沿,写入数据delay_us(5);dat<<=1; //数据向左移一位}}/*************************************************函数名:send_595_fram( )函数功能:单片机向74HC595发送一帧数据(一个数据字节,一个位选字节)入口参数:dat--数码管显示的数据;position--数码管位置返回值:无************************************************/void send_595_fram(unsigned char position,unsigned char dat){STCP=0; //锁存时钟拉低send_595_byte(position); //串行写入数码管位置信息send_595_byte(dat); //串行写入数据信息STCP=1; //锁存时钟拉高,产生上升沿,将锁存的数据输出到管脚上}/*************************************************函数名:ds1302_595_display( )函数功能:将处理完的时间信息显示到数码管上入口参数:无返回值:无************************************************/void ds1302_595_display(){unsigned char j;for(j=0;j<8;j++){send_595_fram(pos[j],seg[time[j]]); //显示一帧函数delay_ms(2); //延时2ms}}/*************************************************函数名:main( )函数功能:主程序入口参数:无返回值:无************************************************/void main(){unsigned char i;unsigned char flag; //设置标志位,存放在RAM的0xc0地址内ds1302_disp_init(); //初始化单片机和ds1302及74HC595的接口delay_ms(100); //等待初始化完毕flag=ds1302_read_byte(0xc1); //上电后读取RAM的0xc0地址的字节// if(flag!=0x01) //判断读出的数据是否是上次写入的值,如果是,就说明ds1302没断电。
DS1302时钟基础使用(含代码)
DS1302时钟基础使⽤(含代码)了解其管脚X1 X2 32.768KHz 晶振管脚GND 地RST 复位脚I/O 数据输⼊/输出引脚,具有三态SCLK 串⾏时钟Vcc1,Vcc2(备⽤电源供电)电源供电管脚DS1302 的寄存器及⽚内RAM控制寄存器⽤于存放DS1302的控制命令字,DS1302的RST引脚回到⾼电平后写⼊的第⼀个字就为控制命令。
它⽤于对DS1302读写过程进⾏控制,它的格式如下:D7:固定为1D6:RAM/CK位,=1⽚内RAM,=0⽇历、时钟寄存器选择位。
D5~D1:地址位,⽤于选择进⾏读写的⽇历、时钟寄存器或⽚内RAM。
对⽇历、时钟寄存器或⽚内RAM的选择见表。
D0:读写选择,=0写,=1读⽇历时钟寄存器写保护寄存器⽤于初始化时钟void Ds1302Init(){uchar n;Ds1302Write(0x8E,0X00); //禁⽌写保护,就是关闭写保护功能for (n=0; n<7; n++)//写⼊7个字节的时钟信号:分秒时⽇⽉周年{Ds1302Write(WRITE_RTC_ADDR[n],TIME[n]);}Ds1302Write(0x8E,0x80); //打开写保护功能}寄存器说明数据输出输⼊在控制指令字输⼊后的下⼀个SCLK时钟的上升沿时,数据被写⼊DS1302,数据输⼊从低位即位0开始。
同样,在紧跟8位的控制指令字后的下⼀个SCLK脉冲的下降沿读出DS1302的数据,读出数据时从低位0位到⾼位7。
单字节读和写DS1302是通过SPI串⾏总线跟单⽚机通信的,当进⾏⼀次读写操作时最少得读写两个字节,第⼀个字节是控制字节,就是⼀个命令,告诉DS1302是读还是写操作,是对RAM还是对CLOK寄存器操作。
第⼆个字节就是要读或写的数据了。
单字节读写:只有在SCLK为低电平时,才能将CE置为⾼电平。
所以在进⾏操作之前先将SCLK置低电平,然后将CE置为⾼电平,接着开始在IO上⾯放⼊要传送的电平信号,然后跳变SCLK。
DS1302时钟芯片单片机控制操作步骤
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置为低电平。
DS1302的使用
数字电路笔记一、时钟芯片DS1302DS1302是一款不带内部晶振和掉电蓄电电池的实时时钟芯片,使用时需要外接晶振。
引脚连接:VCC2接超级电容(0.1F以上);VCC1接主电源;X1、X2外接晶振;4脚接地;5、6、7脚接微处理器的三个GPIO口(通用输入/输出)。
2、DS1302的初始化使用DS1302之前,我们需要对DS1302内部的关于时钟信息的寄存器进行初始化,DS1302仅有一个通讯口,即6脚(I/O),所以要想把数据写到DS1302内部,需要在写数据之前发送一段带有信息的指令,指令的某一位总是在SCLK的上升沿被读进去的。
之后移位寄存器会自动移位,等待下一位数据的传输。
下面是用C语言写的,并在51微处理器上运行的初始化程序。
程序很简单,我们只需要将DS1302内部的关于CLOCK的七个寄存器写进数据就行了,下面是一个程序函数,仅供参考。
void Write_Data(Unsigned char Addr1, Unsigned char Dat1){Unsigned char In_bit1,temp1;RESET = 0;/* 写地址指令字节*/for(In_bit1 = 0,SCLK = 0,RESET = 1;In_bit1 < 8;In_bit1++){SCLK = 0;temp1 = Addr1;I_O = (bit)(temp1 & 0X01);准备好数据准备传输Addr1 = Addr1 >> 1;SCLK = 1;}/* 写数据字节*/for(In_bit1 = 0;In_bit1 < 8;In_bit1++){SCLK = 0;temp1 = Dat1;I_O = (bit)(Dat1 & 0X01);Dat1 = Dat1 >> 1;SCLK = 1;}RESET = 0;}注意:SCLK可以不是有规律的方波,只要满足数据手册要求的上降沿即可。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 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文章分类单片机。