DS1302读写程序

合集下载

DS1302使用手册

DS1302使用手册

S ODS1302 涓流充电时钟保持芯片的原理与应用摘要 本文概括介绍了 DS1302 时钟芯片的特点和基本组成 通过实例详细说明了有关功能的应用软件 关于 DS1302 各寄存器的详细位控功能请参考 D ALLAS 达拉斯公司的相应产品资料概述DS 1302 是 D ALLAS 公司推出的涓流充电时钟芯片 内含有一个实时时钟/日历和31 字节静态 R AM 通过简 单的串行接口与单片机进行通信 实时时钟/日历电路提供秒 分 时 日 日期 月 年的信息 每月的天 数和闰年的天数可自动调整 时钟操作可通过 AM/PM 指示决定采用 24 或 12 小时格式 DS1302 与单片机之 间能简单地采用同步串行的方式进行通信 仅需用到三个口线 1 RE 复位 2 I/ 数据线 3 SCLK 串行时钟时钟/RAM 的读/写数据以一个字节或多达 31 个字节的字符组方式通信 DS1302 工作时功耗很 低 保持数据和时钟信息时功率小于 1mW DS1302 是由 DS1202 改进而来 增加了以下的特性 双电源管脚用于主电源和备份电源供应 Vcc1为可 编程涓流充电电源 附加七个字节存储器 它广泛应用于电话 传真 便携式仪器以及电池供电的仪器仪表等 产品领域 下面将主要的性能指标作一综合 z 实时时钟具有能计算 2100 年之前的秒 分 时 日 日期 星期 月 年的能力 还有闰年调整的能力 z 31 8 位暂存数据存储 R AM z 串行I /O 口方式使得管脚数量最少 z 宽范围工作电压 2.0 5.5V z 工作电流 2.0V 时,小于 300nA z读/写时钟或 R AM 数据时 有两种传送方式 单字节传送和多字节传送字符组方式z 8 脚 D IP 封装或可选的 8 脚 S OIC 封装根据表面装配z 简单 3 线接口z 与 T TL 兼容Vcc=5V z 可选工业级温度范围 -40+85 z 与 D S1202 兼容 z在 D S1202 基础上增加的特性 对 V cc1 有可选的涓流充电能力 双电源管用于主电源和备份电源供应 备份电源管脚可由电池或大容量电容输入 附加的 7 字节暂存存储器1 DS1302 的基本组成和工作原理 D S 1302 的管脚排列及描述如下图及表所示管脚描述管脚配置X1 X2 32.768KHz 晶振管脚GND 地RST 复位脚I/O 数据输入/输出引脚SCLK 串行时钟Vcc1,Vcc2 电源供电管脚订单信息部分# 描述DS1302 串行时钟芯片8 脚D IPDS1302S 串行时钟芯片8 脚S OIC200milDS1302Z 串行时钟芯片8 脚S OIC150mil2.DS1302 内部寄存器CH: 时钟停止位寄存器2的第7位12/24 小时标志CH=0 振荡器工作允许bit7=1,12 小时模式CH=1 振荡器停止bit7=0,24 小时模式WP: 写保护位寄存器2的第5位:AM/PM 定义WP=0 寄存器数据能够写入AP=1 下午模式WP=1 寄存器数据不能写入AP=0 上午模式TCS: 涓流充电选择DS: 二极管选择位TCS=1010 使能涓流充电DS=01 选择一个二极管TCS=其它禁止涓流充电DS=10 选择两个二极管DS=00 或11, 即使T CS=1010, 充电功能也被禁止RS 位电阻典型位00没有没有01R12K10R24K11R38KDS1302 与微控制器的接口软件及功能应用举例下面首先给出基本的接口软件然后举例说明各种功能的应用1 写保护寄存器操作当写保护寄存器的最高位为0 时允许数据写入寄存器写保护寄存器可以通过命令字节8E 8F 来规定禁止写入/读出写保护位不能在多字节传送模式下写入Wri te_Ena ble:MO V Com man d,#8Eh;命令字节为8EMO V Byt eCn t,#1;单字节传送模式MO V R0,#Xm tDa t数据地址覆给R0MO V XmtDat,#00h数据内容为0写入允许AC ALL Sen d_B yte调用写入数据子程序RE T返回调用本子程序处当写保护寄存器的最高位为1时禁止数据写入寄存器W rit e_D isa ble:MO V Com man d,#8Eh;命令字节为8EMO V Byt eCn t,#1;单字节传送模式MO V R0,#Xm tDa t数据地址覆给R0MO V XmtDat,#80h数据内容为80h禁止写入AC ALL Sen d_B yte调用写入数据子程序RE T返回调用本子程序处以上程序调用了基本数据发送(Send_By te)模块及一些内存单元定义,其源程序清单在附录中给出下面的程序亦使用了这个模块2 时钟停止位操作当把秒寄存器的第7位时钟停止位设置为0 时起动时钟开始Osc_Ena ble:MOV C omma nd,#80h ; 命令字节为80MOV B yteC nt,#1 ; 单字节传送模式MOV R0,#X mtDa t数据地址覆给R0MOV X mtDa t,#00h 数据内容为0振荡器工作允许ACALL Send_Byte 调用写入数据子程序RET 返回调用本子程序处当把秒寄存器的第7位时钟停止位设置为1时时钟振荡器停止HT1380进入低功耗方式Osc_Dis able:M OV C omma nd,#80h;命令字节为80M OV B yteC nt,#1;单字节传送模式M OV R0,#X mtDa t数据地址覆给R0M OV X mtDa t,#80h数据内容为80h振荡器停止A CALL S end_Byte调用写入数据子程序R ET返回调用本子程序处3. 多字节传送方式当命令字节为B E 或B F 时DS1302 工作在多字节传送模式8 个时钟/日历寄存器从寄存器0 地址开始连续读写从0位开始的数据当命令字节为FE 或FF 时DS1302 工作在多字节RAM 传送模式31 个RAM 寄存器从0地址开始连续读写从0 位开始的数据例如写入00 年 6 月21日星期三13 时59 分59 秒程序设置如下W rit e_M ultipl ebyt e:MOV C omm and,#0BEh;命令字节为B EhMOV B yte Cnt,#8;多字节写入模式此模块为8个MOV R0,#XmtD at数据地址覆给R0MOV X mtD at,#59h秒单元内容为59hMOV X mtD at+1,#59h分单元内容为59hMOV X mtD at+2,#13h时单元内容为13hMOV X mtD at+3,#21h日期单元内容为21hMOV X mtD at+4,#06h月单元内容为06hMOV X mtD at+5,#03h星期单元内容为03hMOV X mtD at+6,#0年单元内容为00hMOV X mtD at+7,#0写保护单元内容为00hACA LL S end_By te调用写入数据子程序RET返回调用本子程序处读出寄存器0-7 的内容程序设置如下Rea d_M ultipl eby te:MOV C omm and,#0BFh;命令字节为B FhMOV B yte Cnt,#8;多字节读出模式此模块为8个MOV R1,#Rcv Dat 数据地址覆给R1ACALL R ece ive_By te调用读出数据子程序RET 返回调用本子程序处以上程序调用了基本数据接收(Recei ve_Byt e)模块及一些内存单元定义,其源程序清单在附录中给出下面的程序亦使用了这个模块4. 单字节传送方式例如写入8时12 小时模式程序设置如下Wri te_Sin gle byt e:M OV Co mma nd,#84h; 命令字节为84hM OV By teC nt,#1; 单字节传送模式M OV R0,#X mtD at数据地址覆给R0M OV Xm tDa t,#88h数据内容为88h A CAL LSend_Byte 调用写入数据子程序RET 返回调用本子程序处上面所列出的程序模块Write_Enab le W rit e_Di sabl e Osc_Enable Osc_D isab le与单字节写入模块Write_Singlebyte 的程序架构完全相同仅只是几个入口参数不同本文是为了强调功能使用的不同才将其分为不同模块另外,与涓流充电相关的设定也是单字节操作方式,这里就不再单独列出, 用户在使用中可灵活简略下面模块举例说明如何单字节读出小时单元的内容.Read_Si ngl eby te:M OV Co mma nd,#85h; 命令字节为85hM OV By teC nt,#1; 单字节传送模式M OV R1,#R cvD at数据地址覆给R1A CAL L Re cei ve_Byt e调用读出数据子程序R ET返回调用本子程序处DS1302 应用电路原理图P87LPC764 单片机选取内部振荡及内部复位电路附录数据发送与接收模块源程序清单; CPU 工作频率最大不超过20MHz;******************************************************************************************** ;P87LPC762/4主控器发送接受数据程序; 说明本程序是利用P hilips公司的P87LPC764 单片机任何具有51内核或其它合适的单片机都可在此作为主控器的普通I/O 口(如P1.2/P1.3/P1.4)实现总线的功能对总线上的器件本程序采用D S1302进行读写操作命令字节在C ommand 传送字节数在B yteCnt 中所发送的数据在X mtDat 中所接收的数据在R cvDat 中;******************************************************************************************** ;P87LPC762/4主控器总线发送接受数据程序头文件;内存数据定义BitCnt data 30h ; 数据位计数器Byt eCn t data 31h ; 数据字节计数器Command data 32h ; 命令字节地址RcvDat D ATA40H; 接收数据缓冲区XmtDat D ATA50H; 发送数据缓冲区;端口位定义IO_DAT A b it P1.3; 数据传送总线SCLK b it P1.4; 时钟控制总线RST bi t P1.2; 复位总线;******************************************************************************************** ;发送数据程序;名称:S end_By te;描述:发送Byte Cnt个字节给被控器D S1302;命令字节地址在C ommand 中;所发送数据的字节数在B yteCnt 中发送的数据在X mtDat 缓冲区中;******************************************************************************************** Send_Byt e:CLR RST ;复位引脚为低电平所有数据传送终止NO PCLR SC LK清时钟总线NO PSETB RST ;复位引脚为高电平逻辑控制有效NO PM OV A,Command 准备发送命令字节M OV Bi tCn t,#08h传送位数为8S_By te0:RRC A将最低位传送给进位位CM OV IO_DA TA,C位传送至数据总线NO PSETB SC LK时钟上升沿发送数据有效NO PCLR SC LK清时钟总线D JNZ Bi tCn t,S_By te0位传送未完毕则继续NO PS_By te1:准备发送数据M OV A,@R0 传送数据过程与传送命令相同M OV Bi tCn t,#08hS_By te2:RRC AM OV IO_DA TA,CNO PS ETB SC LKNO PC LR SC LKD JNZ Bi tCn t,S_By te2I NC R0发送数据的内存地址加1D JNZ By teC nt,S_B yte1字节传送未完毕则继续NO PC LR RST逻辑操作完毕清R STR ET;*************************************************************************************** ;接收数据程序;;名称:Rece ive_By te;描述:从被控器D S1302 接收Byte Cnt个字节数据;命令字节地址在C ommand 中;所接收数据的字节数在B yteCnt 中接收的数据在R cvDat 缓冲区中;*********************************************************************************** Rece ive_By te:CLR RST ;复位引脚为低电平所有数据传送终止NO PCLR SC LK清时钟总线NO PS ETB RST;复位引脚为高电平逻辑控制有效M OV A,Com man d准备发送命令字节R_By te0:M OV Bi tCn t,#08h传送位数为8RRC A将最低位传送给进位位CM OV IO_DA TA,C位传送至数据总线NO PSETB SC LK时钟上升沿发送数据有效NO PCLR SC LK清时钟总线D JNZ BitCnt,R_Byte0 位传送未完毕则继续NO PR_By te1:准备接收数据CLR A清类加器C LRC清进位位CM OV Bi tCn t,#08h接收位数为8R_By te2:NO PM OV C,IO_DAT A数据总线上的数据传送给CRRC A从最低位接收数据SETB SC LK时钟总线置高NO PCLR SC LK时钟下降沿接收数据有效D JNZ BitCnt,R_Byte2 位接收未完毕则继续M OV@R1,A 接收到的完整数据字节放入接收内存缓冲区I NC R1 接收数据的内存地址加1D JNZ By teC nt,R_B yte1字节接收未完毕则继续NO PCLR RST 逻辑操作完毕清R STR ET;============================================================================== =============== E ND。

时钟芯片ds1302程序

时钟芯片ds1302程序

这是对DS1302编程最常见的操作,有很好的参考价值!我们通过本例程可以了解 DS1302时钟芯片的基本原理和使用 ,理解并掌握DS1302时钟芯片,驱动程序的编写以及实现数字字符在数码管中的显示。

#include<reg52.h>#include <intrins.h>sbit SCK=P3^6; //时钟引脚sbit SDA=P3^4; //数据端口sbit RST = P3^5;// DS1302复位sbit LS138A=P2^2;sbit LS138B=P2^3;sbit LS138C=P2^4;bit ReadRTC_Flag;//定义读DS1302标志unsigned char l_tmpdate[7]={0,0,12,15,5,3,8};//秒分时日月周年08-05-15 12:00:00 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 chartable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40};//共阴数码管 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 timer0/******************************************************************/ /* 主函数 *//******************************************************************/ void main(void){InitTIMER0(); //初始化定时器0Set_RTC(); //写入时钟值,如果使用备用电池时候,不需要没每次上电写入,此程序应该屏蔽while(1){if(ReadRTC_Flag){ReadRTC_Flag=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;}}}/******************************************************************/ /* 定时器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 ){RST=0;_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_();_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时钟芯片驱动程序

DS1302时钟芯片驱动程序

DS1302时钟芯片驱动程序//DS1302时钟芯片驱动程序#include <reg51.h>//下面是引脚连接关系sbit clock_dat=P1^0;sbit clock_clk=P1^1;sbit clock_clk=P1^2;sbit a0=ACC^0;sbit a1=ACC^1;sbit a2=ACC^2;sbit a3=ACC^3;sbit a4=ACC^4;sbit a5=ACC^5;sbit a6=ACC^6;sbit a7=ACC^7;void clock_out(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; }unsigned char clock_in(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);}unsigned char read_clock(unsigned char ord) {unsigned char dd=0;clock_clk=0;clock_rst=0;clock_rst=1;clock_out(ord);dd=clock_in();clock_rst=0;clock_clk=1;return(dd);}void write_clock(unsigned char ord,unsigned char dd) {clock_clk=0;clock_rst=0;clock_rst=1;clock_out(ord);clock_out(dd);clock_rst=0;clock_clk=1;}/*注意事项:1.每次上电,必须把秒寄存器高位(第7位)设置为0,时钟才能走时。

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,指定读操作(输出)。

DS1302读写程序

DS1302读写程序

//读 DS1302RAM 字节 unsigned char TimeRamByteRead(unsigned char address) { TimeSpiOpen();//打开 DS1302 TimeSpiReadWrite((address << 1) | 0xc1);//写入 DS1302 命令 address = TimeSpiReadWrite(0xff);//读入 DS1302 数据 TimeSpdress;//返回数据 }
val = TimeByteRead(timereadseg);//读秒数据 val &= 0x7f;//打开晶振 TimeWrieDisbale();//开放 DS1302 写保护 TimeByteWrite(timewriteseg, val);//打开晶振 TimeByteWrite(tricklewrite, 0xa5);//打开充电二极管 TimeWriteEnable();//使能 DS1302 写保护 }
//打开 DS1302 void TimeSpiOpen(void) { TIMECLK = 0; TIMERST = 0;//禁止 DS1302 TIMEIO } //关闭 DS1302 void TimeSpiClose(void) { TIMERST = 0;//禁止 DS1302 TIMEIO } //读写 DS1302 unsigned char TimeSpiReadWrite(unsigned char val) { unsigned char i; ACC = val;//取 8 位数据 for (i = 8;i > 0; i--) { TIMECLK = 0;//时钟下降沿输入数据(DS1302 读) _nop_();//延时 CY = TIMEIO;//接收串行数据到 CY _rrca_();//右移一位数据到 CY(先存后取) TIMEIO = CY;//发送串行数据 TIMECLK = 1;//时钟上升沿打入数据(DS1302 写) TIMEIO } val = ACC; return val; } //读 DS1302 字节 unsigned char TimeByteRead(unsigned char address) { TimeSpiOpen();//打开 DS1302 TimeSpiReadWrite(address);//写入 DS1302 命令 address = TimeSpiReadWrite(0xff);//读入 DS1302 数据 TimeSpiClose();//关闭 DS1302 return address;//返回数据 } = 1;//释放数据总线 = 1;//释放数据总线 TIMECLK = 1; = 1;//释放数据总线 TIMERST = 1;//使能 DS1302

DS1302读写程序IIC总线

DS1302读写程序IIC总线

DS1302读写程序(IIC总线)#include; //包含单片机寄存器的头文件#include; //包含_nop_()函数定义的头文件#define uchar unsigned char#define uint unsigned intsbit SRT=P3^5;sbit IO=P3^4;sbit SCK=P3^6;uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};uchar miao,fen,shi,tian,yue,zhou,nian;uchar read_DS1302(uchar addr)//读DS1302子程序;{uchar dat,i,temp,j;SRT=0;SCK=0;IO=0;//必须先置低,否则易出错;SRT=1;for(i=0;i;>;1;SCK=1;_nop_();}// IO=1;//释放总线,以便接下来的读操作,//否则读出的数据永远都是0x00,//但因addr最高总是1,在传送最高位时,即IO=dat=1, //所以此句可以不要;for(j=0;j;>;=1;if(IO)temp=temp|0x80;SCK=1;_nop_();}SCK=0;//必须严格按时序拉低,不然出错;SRT=0;IO=1;//必须释放总线;return temp;}void write_DS1302(uchar add,uchar date)//写DS1302子程序;{uchar dat1,i,dat2,j;SRT=0;SCK=0;IO=0;SRT=1;_nop_();for(i=0;i;>;1;IO=dat1;SCK=1;_nop_();}for(j=0;j;>;1;IO=dat2;SCK=1;_nop_();}SCK=0;SRT=0;IO=1;}void delay(uint n) {while(n--);}void display(){uchar miao1,miao2,fen1,fen2,shi1,shi2; P0=0xff;P1=0x00;miao1=miao&0x0f;miao2=miao&0xf0;miao2=miao2>;>;4;fen1=fen&0x0f;fen2=fen&0xf0;fen2=fen2>;>;4;shi1=shi&0x0f;shi2=shi&0xf0;shi2=shi2>;>;4;P1=table[miao1];P0=0x7f;delay(200);P1=table[miao2];P0=0xbf;delay(200);P1=0x40;P0=0xdf;delay(200);P1=table[fen1];P0=0xef;delay(200);P1=table[fen2];P0=0xf7;delay(200);P1=0x40;P0=0xfb;delay(200);P1=table[shi1];P0=0xfd;delay(200);P1=table[shi2];P0=0xfe;delay(200);}void main(){//设置日期时间(2013/09/11,21:03:00,星期3);while(1){miao=read_DS1302(0x81);fen=read_DS1302(0x83);shi=read_DS1302(0x85);tian=read_DS1302(0x87);yue=read_DS1302(0x89);zhou=read_DS1302(0x8b);nian=read_DS1302(0x8d);//读取DS18B20数据; P2=miao;display();}}。

DS1302程序

DS1302程序

;1.每次上电,必须把秒寄存器高位(第7位)设置为0,时钟才能走时。

;2.如果需要写入数据和时钟日历信息,必须把“写保护”寄存器设置成为0 ;内存数据定义BitCnt data 30h ; 数据位计数器ByteCnt data 31h ; 数据字节计数器Command data 32h ; 命令字节地址RcvDat DATA 40H ; 接收数据缓冲区XmtDat DATA 50H ; 发送数据缓冲区;端口位定义IO_DATA bit P1.1 ; 数据传送总线SCLK bit P1.0 ; 时钟控制总线RST bit P1.2 ; 复位总线RS EQU P1.3;确定具体硬件的连接方式RW EQU P1.4 ;确定具体硬件的连接方式E EQU P1.5 ;确定具体硬件的连接方式ORG 0000HLJMP START;**************************** ;main programORG 0030HSTART: CLR RSTMOV SP,#2AH;------------------------------------初始化1302-------------------------SET1302:LCALL Write_Multiplebyte;初始化1302,将我们要设定的数据写入CG:LCALL Read_Multiplebyte;将我们设定的数据读出来MOV P3,#10000000BLCALL ENABLEMOV P3,#00011100BLCALL ENABLEMOV P3,#00110000BLCALL ENABLEMOV P3,#01100000BLCALL ENABLEMOV P3,#00000001BLCALL ENABLELCALL STLCDJNB P2.4,SETB_TIMELCALL YSLJMP CGSETB_TIME:LCALL YSMOV P3,#11110000B;显示器开、光标开、光标允许闪烁LCALL ENABLE ;调用写入命令子程序MOV P3,#01110011BLCALL ENABLE;调用写入命令子程序JNB P2.4,SETB_TIME1JB P2.5,LJMP_ADDINC 45HLJMP_ADD:JB P2.6,LJMP_SUBBDEC 45HLJMP_SUBB:MOV A,45HMOV B,#16DIV ABMOV A,BCJNE A,#10,CHULIMOV A,45HADD A,#6MOV 45H,ACHULI:MOV A,45HMOV B,#16DIV ABMOV A,BCJNE A,#15,ZAICHULIMOV A,45HSUBB A,#6MOV 45H,AZAICHULI:LCALL STLCDMOV P3,#01110011BLCALL ENABLE;调用写入命令子程序JNB P2.7,OUTPUTTTTLJMP SETB_TIMEOUTPUTTTT:LJMP OUTPUTSETB_TIME1:LCALL YSMOV P3,#11110000B;显示器开、光标开、光标允许闪烁LCALL ENABLE ;调用写入命令子程序MOV P3,#11010011BLCALL ENABLE;调用写入命令子程序JNB P2.4,SETB_TIME2JB P2.5,LJMP_ADD1INC 43HLJMP_ADD1:JB P2.6,LJMP_SUBB1DEC 43HLJMP_SUBB1:MOV A,43HMOV B,#16DIV ABMOV A,BCJNE A,#10,CHULI1MOV A,43HADD A,#6MOV 43H,ACHULI1:MOV A,43HMOV B,#16DIV ABMOV A,BCJNE A,#15,ZAICHULI1MOV A,43HSUBB A,#6MOV 43H,AZAICHULI1:LCALL STLCDMOV P3,#11010011BLCALL ENABLE;调用写入命令子程序JNB P2.7,OUTPUTLJMP SETB_TIME1SETB_TIME2:LCALL YSMOV P3,#11110000B;显示器开、光标开、光标允许闪烁LCALL ENABLE ;调用写入命令子程序MOV P3,#00010011BLCALL ENABLE;调用写入命令子程序JNB P2.4,SETB_TIME3JB P2.5,LJMP_ADD2INC 44HLJMP_ADD2:JB P2.6,LJMP_SUBB2DEC 44HLJMP_SUBB2:MOV A,44HMOV B,#16DIV ABMOV A,BCJNE A,#10,CHULI2MOV A,44HADD A,#6MOV 44H,ACHULI2:MOV A,44HMOV B,#16DIV ABMOV A,BCJNE A,#15,ZAICHULI2MOV A,44HSUBB A,#6MOV 44H,AZAICHULI2:LCALL STLCDMOV P3,#00010011BLCALL ENABLE;调用写入命令子程序JNB P2.7,OUTPUTLJMP SETB_TIME2OUTPUT:LCALL Write_Enable;写允许MOV Command,#0BEh ;命令字节为BEhMOV ByteCnt,#8 ;多字节写入模式此模块为8 个MOV R0,#XmtDat;数据地址覆给R0MOV XmtDat,40H ;秒单元内容为59hMOV XmtDat+1,41H ;分单元内容为59hMOV XmtDat+2,42H ;时单元内容为13hMOV XmtDat+3,43H ;日期单元内容为21hMOV XmtDat+4,44H ;月单元内容为06hMOV XmtDat+5,45H ;星期单元内容为03hMOV XmtDat+6,46H ;年单元内容为00hMOV XmtDat+7,#0 ;写保护单元内容为00hLCALL Send_Byte ;调用写入数据子程序LJMP CGSETB_TIME3:LCALL YSMOV P3,#11110000B;显示器开、光标开、光标允许闪烁LCALL ENABLE ;调用写入命令子程序MOV P3,#10100011BLCALL ENABLE;调用写入命令子程序JNB P2.4,SETB_TIME4JB P2.5,LJMP_ADD3INC 46HLJMP_ADD3:JB P2.6,LJMP_SUBB3DEC 46HLJMP_SUBB3:MOV A,46HMOV B,#16DIV ABMOV A,BCJNE A,#10,CHULI3MOV A,46HADD A,#6MOV 46H,ACHULI3:MOV A,46HMOV B,#16DIV ABMOV A,BCJNE A,#15,ZAICHULI3MOV A,46HSUBB A,#6MOV 46H,AZAICHULI3:LCALL STLCDMOV P3,#10100011BLCALL ENABLE;调用写入命令子程序JNB P2.7,OUTPUTLJMP SETB_TIME3SETB_TIME4:LCALL YSMOV P3,#11110000B;显示器开、光标开、光标允许闪烁LCALL ENABLE ;调用写入命令子程序MOV P3,#11010001BJNB P2.4,SETB_TIME5JB P2.5,LJMP_ADD4INC 40HLJMP_ADD4:JB P2.6,LJMP_SUBB4DEC 40HLJMP_SUBB4:MOV A,40HMOV B,#16DIV ABMOV A,BCJNE A,#10,CHULI4MOV A,40HADD A,#6MOV 40H,ACHULI4:MOV A,40HMOV B,#16DIV ABMOV A,BCJNE A,#15,ZAICHULI4MOV A,40HSUBB A,#6MOV 40H,AZAICHULI4:LCALL STLCDMOV P3,#11010001BLCALL ENABLE;调用写入命令子程序JNB P2.7,OUTPUTTLJMP SETB_TIME4SETB_TIME5:LCALL YSMOV P3,#11110000B;显示器开、光标开、光标允许闪烁LCALL ENABLE ;调用写入命令子程序MOV P3,#00010001BJNB P2.4,SETB_TIME6JB P2.5,LJMP_ADD5INC 41HLJMP_ADD5:JB P2.6,LJMP_SUBB5DEC 41HLJMP_SUBB5:MOV A,41HMOV B,#16DIV ABMOV A,BCJNE A,#10,CHULI5MOV A,41HADD A,#6MOV 41H,ACHULI5:MOV A,41HMOV B,#16DIV ABMOV A,BCJNE A,#15,ZAICHULI5MOV A,41HSUBB A,#6MOV 41H,AZAICHULI5:LCALL STLCDMOV P3,#00010001BLCALL ENABLE;调用写入命令子程序JNB P2.7,OUTPUTTLJMP SETB_TIME5OUTPUTT:LJMP OUTPUTSETB_TIME6:LCALL YSMOV P3,#11110000B;显示器开、光标开、光标允许闪烁LCALL ENABLE ;调用写入命令子程序MOV P3,#10100001BLCALL ENABLE;调用写入命令子程序JNB P2.4,SETB_TIMEEJB P2.5,LJMP_ADD6INC 42HLJMP_ADD6:JB P2.6,LJMP_SUBB6DEC 42HLJMP_SUBB6:MOV A,42HMOV B,#16DIV ABMOV A,BCJNE A,#10,CHULI6MOV A,42HADD A,#6MOV 42H,ACHULI6:MOV A,42HMOV B,#16DIV ABMOV A,BCJNE A,#15,ZAICHULI6MOV A,42HSUBB A,#6MOV 42H,AZAICHULI6:LCALL STLCDMOV P3,#10100001BLCALL ENABLE;调用写入命令子程序JNB P2.7,OUTPUTTLJMP SETB_TIME6SETB_TIMEE:LJMP SETB_TIMESend_Byte:CLR RST ;复位引脚为低电平所有数据传送终止NOPCLR SCLK; 清时钟总线NOPSETB RST ;复位引脚为高电平逻辑控制有效NOPMOV A,Command; 准备发送命令字节MOV BitCnt,#08hS_Byte0:RRC A ;将最低位传送给进位位CMOV IO_DATA,C ;位传送至数据总线NOPSETB SCLK ;时钟上升沿发送数据有效NOPCLR SCLK ;清时钟总线DJNZ BitCnt,S_Byte0 ;位传送未完毕则继续NOPS_Byte1: ;准备发送数据MOV A,@R0 ;传送数据过程与传送命令相同MOV BitCnt,#08hS_Byte2:RRC AMOV IO_DATA,CNOPSETB SCLKNOPCLR SCLKDJNZ BitCnt,S_Byte2INC R0 ;发送数据的内存地址加1DJNZ ByteCnt,S_Byte1 ;字节传送未完毕则继续NOPCLR RST ;逻辑操作完毕清RSTRETReceive_Byte:CLR RST ;复位引脚为低电平所有数据传送终止NOPCLR SCLK ;清时钟总线NOPSETB RST ;复位引脚为高电平逻辑控制有效MOV A,Command ;准备发送命令字节MOV BitCnt,#08h ;传送位数为8R_Byte0:RRC A ;将最低位传送给进位位CMOV IO_DATA,C ;位传送至数据总线NOPSETB SCLK ;时钟上升沿发送数据有效NOPCLR SCLK ;清时钟总线DJNZ BitCnt,R_Byte0 ;位传送未完毕则继续NOPR_Byte1: ;准备接收数据CLR A ;清类加器CLR C ;清进位位CMOV BitCnt,#08h ;接收位数为8R_Byte2:NOPMOV C,IO_DATA ;数据总线上的数据传送给CRRC A ;从最低位接收数据SETB SCLK ;时钟总线置高NOPCLR SCLK ;时钟下降沿接收数据有效DJNZ BitCnt,R_Byte2 ;位接收未完毕则继续MOV @R1,A ;接收到的完整数据字节放入接收内存缓冲区INC R1 ;接收数据的内存地址加1DJNZ ByteCnt,R_Byte1 ;字节接收未完毕则继续NOPCLR RST ;逻辑操作完毕清RSTRET;--写保护寄存器操作------------------------------------------ Write_Enable:MOV Command,#8Eh ;命令字节为8EMOV ByteCnt,#1 ;单字节传送模式MOV R0,#XmtDat ;数据地址覆给R0MOV XmtDat,#00h ;数据内容为0 写入允许ACALL Send_Byte ;调用写入数据子程序RET;当写保护寄存器的最高位为1 时禁止数据写入寄存器---------------Write_Disable:MOV Command,#8Eh ;命令字节为8EMOV ByteCnt,#1 ;单字节传送模式MOV R0,#XmtDat ;数据地址覆给R0MOV XmtDat,#80h ;数据内容为80h 禁止写入ACALL Send_Byte ;调用写入数据子程序RET ;返回调用本子程序处;当把秒寄存器的第7 位时钟停止位设置为0 时起动时钟开始---------Osc_Enable:MOV Command,#80h ; 命令字节为80MOV ByteCnt,#1 ; 单字节传送模式MOV R0,#XmtDat ;数据地址覆给R0MOV XmtDat,#00h ;数据内容为0 振荡器工作允许ACALL Send_Byte ;调用写入数据子程序RET ;返回调用本子程序处;当把秒寄存器的第7 位时钟停止位设置为1 时时钟振荡器停止HT1380 进入低功耗方式---------------Osc_Disable:MOV Command,#80h ;命令字节为80MOV ByteCnt,#1 ;单字节传送模式MOV R0,#XmtDat ;数据地址覆给R0MOV XmtDat,#80h ;数据内容为80h 振荡器停止ACALL Send_Byte ;调用写入数据子程序RET ;返回调用本子程序处;写入00 年6 月21 日星期三13 时59 分59---------------------Write_Multiplebyte:MOV Command,#0BEh ;命令字节为BEhMOV ByteCnt,#8 ;多字节写入模式此模块为8 个MOV R0,#XmtDat ;数据地址覆给R0MOV XmtDat,#48h ;秒单元内容为59hMOV XmtDat+1,#14h ;分单元内容为59hMOV XmtDat+2,#09h ;时单元内容为13hMOV XmtDat+3,#16h ;日期单元内容为21h MOV XmtDat+4,#15h ;月单元内容为06hMOV XmtDat+5,#05h ;星期单元内容为03h MOV XmtDat+6,#07 ;年单元内容为00hMOV XmtDat+7,#0 ;写保护单元内容为00h ACALL Send_Byte ;调用写入数据子程序RET ;返回调用本子程序处;读出寄存器0-7 的内容程序设置如下Read_Multiplebyte:MOV Command,#0BFh ;命令字节为BFhMOV ByteCnt,#8 ;多字节读出模式此模块为8 个MOV R1,#RcvDat ;数据地址覆给R1ACALL Receive_Byte; 调用读出数据子程序RET; 返回调用本子程序处SSH:MOV B,#16DIV ABMOV 61H,BMOV 62H,AMOV R1,#62HMOV A,@R1MOV DPTR,#TABMOVC A,@A+DPTRMOV P3,ASETB RSCLR RWCLR ELCALL DELAYSETB EMOV A,@R1MOV DPTR,#TABMOVC A,@A+DPTRMOV P3,ASETB RSCLR RWCLR ELCALL DELAYSETB ERETENABLE:CLR RS ;写入控制命令的子程序CLR RWCLR EACALL DELAYSETB ERETDELAY:MOV P3,#0FFH ;判断液晶显示器是否忙的子程序CLR RSSETB RWCLR ENOPSETB EJB P3.0,DELAY ;如果P1.7为高电平表示忙就循环等待RET;写入8 时12 小时模式程序设置如下Write_Singlebyte:MOV Command,#84h ; 命令字节为84hMOV ByteCnt,#1 ; 单字节传送模式MOV R0,#XmtDat ;数据地址覆给R0MOV XmtDat,#88h ;数据内容为88hACALL Send_Byte ;调用写入数据子程序RET ;返回调用本子程序处MOV P3,#00000001B;显示器开、光标开、光标允许闪烁LCALL ENABLE ;调用写入命令子程序MOV A,#0;显示时间字符MOV R7,#0TIME:MOV DPTR,#TAB2MOVC A,@A+DPTRMOV P3,ALCALL CCFF1INC R7MOV A,R7CJNE A,#5,TIMEMOV A,42HLCALL SSHMOV P3,#10110100BLCALL CCFF1MOV A,41HLCALL SSHMOV P3,#10110100BLCALL CCFF1MOV A,40HLCALL SSHMOV P3,#00000011BLCALL ENABLEMOV A,#0;显示日期字符MOV R7,#0DATE:MOV DPTR,#TAB1MOVC A,@A+DPTRMOV P3,ALCALL CCFF1INC R7CJNE A,#5,DATEMOV A,46HLCALL SSHMOV P3,#10110100B LCALL CCFF1MOV A,44HLCALL SSHMOV P3,#10110100B LCALL CCFF1MOV A,43HLCALL SSHMOV P3,#00000100B LCALL CCFF1MOV A,45HLCALL SSHRETYS:MOV R5,#60D2:MOV R6,#50D1: MOV R7,#66DJNZ R7, $DJNZ R6,D1DJNZ R5,D2RETCCFF1:SETB RSCLR RWCLR ELCALL DELAY SETB ERETTAB:DB00001100B,10001100B,01001100B,11001100B,00101100B,10101100B,01101100B,111 01100B,00011100B,10011100B,01110100B,10110100BTAB2:DB 00101010b,10010110b,10110110b,10100110b,01011100bTAB1:DB 00100010b,10000110b,00101110b,10100110b,01011100bEND。

DS1302读写程序详解

DS1302读写程序详解
}
unsignedcharReadSet1302(unsignedcharCmd)
{
unsignedchardat;
RST=0;//拉低RST
SCLK=0;//确保写数居前SCLK被拉低
RST=1;//启动数据传输
Write1302(Cmd);//写入命令字
dat=Read1302();//读出数据
SCLK=1;//将时钟电平置于已知状态
RST=0;//禁止数据传递
returndat;//将读出的数据返回
}
DS1302读写程序详解
voidWrite1302(unsignedchardat)
{
unsignedchari;
SCLK=0;//拉低SCLK,为脉冲上升沿写入数据做好准备
delaynus(2);//稍微等待,使硬件做好准备
for(i=0;i>=1;//将dat的各数据位右移1位,准备写入下一个数据位
Write1302(dat);//写数据
SCLK=1;//将时钟电平置于已知状态
RST=0;//禁止数据传递
}
unsignedcharRead1302(void)
{
unsignedchari,dat;
delaynus(2);//稍微等待,使硬件做好准备
for(i=0;i>=1;//将dat的各数据位右移1位,因为先读出的是字节的最低位
if(Байду номын сангаасATA==1)//如果读出的数据是1
dat|=0x80;//将1取出,写在dat的最高位
SCLK=1;//将SCLK置于高电平,为下降沿读出
delaynus(2);//稍微等待
SCLK=0;//拉低SCLK,形成脉冲下降沿

超详细的ds1302使用说明及其例程

超详细的ds1302使用说明及其例程
允许写保护允许写保护十六进制转十禁止写保秒位初始分钟初始化51单片机综合学习系统之单片机综合学习系统之ds1302时钟应用篇时钟应用篇电子制作电子制作2008年需引用请注明出处需引用请注明出处年10月月站长原创如站长原创如大家好通过以前的学习我们已经对51单片机综合学习系统的使用方法及学习方式有所了解与熟悉学会了使用ad模数转换的基本知识体会到了综合学习系统的易用性与易学性这一期我们将一起学习ds1302时钟的基本原理与应用实例
DS1302时钟芯片简介
DS1302是 DALLAS 公司推出的涓流充电时钟芯片,内含一个实时时钟/日历和31字节静 态 RAM,可以通过串行接口与单片机进行通信。实时时钟/日历电路提供秒、分、时、日、 星期、月、年的信息,每个月的天数和闰年的天数可自动调整,时钟操作可通过 AM/PM 标 志位决定采用24或12小时时间格式。DS1302与单片机之间能简单地采用同步串行的方式进 行通信,仅需三根 I/O 线:复位(RST)、I/O 数据线、串行时钟(SCLK)。时钟/RAM 的读 /写数据以一字节或多达31字节的字符组方式通信。DS1302工作时功耗很低,保持数据和时 钟信息时,功耗小于1mW。
Write1302 (WRITE_PROTECT,0x80); 允许写保护
}
//十六进制转十
//禁止写保 //秒位初始 //分钟初始化
// //
51单片机综合学习系统之 DS1302时钟应用篇 《电子制作》2008年10月 站长原创,如 需引用请注明出处
大家好,通过以前的学习,我们已经对51单片机综合学习系统的使用方法及学习方式有 所了解与熟悉,学会了使用 AD 模数转换的基本知识,体会到了综合学习系统的易用性与易 学性,这一期我们将一起学习 DS1302时钟的基本原理与应用实例。

STM32F103驱动DS1302程序(带注释)

STM32F103驱动DS1302程序(带注释)

1简介主控芯片是STM32F103ZET6,DS1302模块在某宝购买,测试两个小时,发现一个小时大概差1秒钟。

芯片受温度、电压影响较大。

输出结果用串口打印到串口调试助手。

如果要oled或者其他显示需要转换为十进制。

2.代码部分2.1 led部分------------led.h--------------------#ifndef __LED_H#define __LED_H#include "sys.h"void LED_Init(void);//初始化#endif------------led.c--------------------#include "led.h"//LED IO初始化void LED_Init(void){GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);//使能PB端口时钟GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;//LED0-->PB.5 端口配置GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//IO口速度为50MHzGPIO_Init(GPIOB, &GPIO_InitStructure);//根据设定参数初始化GPIOB.5GPIO_SetBits(GPIOB,GPIO_Pin_5); //PB5 输出高}2.2 usart部分---------------usart.h------------------------#ifndef __USART_H#define __USART_H#include "stdio.h"#include "sys.h"void uart_init(u32 bound);void usart1_send_string(u8 *BuffToSend);void usart1_sendbyte(u8 data);#endif---------------usart.c-----------------------#include "sys.h"#include "usart.h"void uart_init(u32 bound){//GPIO端口设置GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Peri ph_GPIOA, ENABLE); //使能USART1,GPIOA时钟//USART1_TX GPIOA.9GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9//USART1_RX GPIOA.10初始化GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10 //Usart1 NVIC 配置NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ; //抢占优先级3NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子优先级3NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//IRQ通道使能NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC 寄存器//USART 初始化设置USART_ART_BaudRate = bound;//串口波特率USART_ART_WordLength = USART_WordLength_8b;//字长为8位数据格式USART_ART_StopBits = USART_StopBits_1;//一个停止位USART_ART_Parity = USART_Parity_No;//无奇偶校验位USART_ART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制USART_ART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式USART_Init(USART1, &USART_InitStructure); //初始化串口1USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断USART_Cmd(USART1, ENABLE); //使能串口1 }//打印字节void usart1_sendbyte(u8 data){USART_SendData(USART1, data);while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!= SET);}//打印字符串void usart1_send_string(u8 *BuffToSend){u8 i=0;while(BuffToSend[i]!='\0'){USART_SendData(USART1, BuffToSend[i]);while( USART_GetFlagStatus(USART1,USART_FLAG_TC)!= SET);i++;}}2.3 ds1302部分---------------ds1302.h-----------------------#ifndef __DS1302_H#define __DS1302_H#include "sys.h"//写年月日时间寄存器#define WriteSecond 0x80#define WriteMinute 0x82#define WriteHour 0x84#define WriteDay 0x86#define WriteMonth 0x88#define writeWeek 0x8a#define writeYear 0x8c//读年月日时间寄存器#define ReadSecond 0x81#define ReadMinute 0x83#define ReadHour 0x85#define ReadDay 0x87#define ReadMonth 0x89#define ReadWeek 0x8b#define ReadYear 0x8d//引脚分配 SDA-PC3 SCL-PC4 RST-PC5#define DS_SDA_IN {GPIOC->CRL&=0XFFFF0FFF;GPIOC->CRL|=(u32)8<<12;}#define DS_SDA_OUT{GPIOC->CRL&=0XFFFF0FFF;GPIOC->CRL|=(u32)3<<12;}#define DS_SDA_DATA GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_3)//SDA#define DS_SDA_HIGH GPIO_SetBits(GPIOC,GPIO_Pin_3)#define DS_SDA_LOW GPIO_ResetBits(GPIOC,GPIO_Pin_3)#define DS_SCK_HIGH GPIO_SetBits(GPIOC,GPIO_Pin_4)//SCL#define DS_SCK_LOW GPIO_ResetBits(GPIOC,GPIO_Pin_4)#define DS_RST_HIGH GPIO_SetBits(GPIOC,GPIO_Pin_5)//CE#define DS_RST_LOW GPIO_ResetBits(GPIOC,GPIO_Pin_5)void ds1302_init(void);void write_one_byte(u8 data);u8 read_one_byte(void);void ds1302_write_data(u8 reg,u8 data);u8 ds1302_read_data(u8 reg);void time_init(void);void time_read(void);u8 hex_to_bcd(u8 hex_data);u8 bcd_to_hex(u8 bcd_data);#endif---------------ds1302.c-----------------------#include "ds1302.h"#include "delay.h"u8 DSsecond,DSminute,DShour,DSweek,DSday,DSmonth,DSyear;u8 time[7]={0x18,0x06,0x10,0x19,0x23,0x59,0x30};//年星期月日时分秒void ds1302_init(){GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOC, &GPIO_InitStructure);GPIO_ResetBits(GPIOC,GPIO_Pin_5);//CE拉低GPIO_SetBits(GPIOC, GPIO_Pin_3|GPIO_Pin_4); //拉高}//写入一个字节void write_one_byte(u8 data){u8 i;DS_SDA_OUT;for(i=0;i<8;i++){DS_SCK_LOW;if(data&0x01) //从低位开始{DS_SDA_HIGH;}else{DS_SDA_LOW;}delay_us(2);DS_SCK_HIGH;data>>=1;delay_us(2);}}//读一个字节u8 read_one_byte(){u8 i,data;DS_SDA_IN ;for(i=0;i<8;i++){data>>=1;DS_SCK_HIGH;if(DS_SDA_DATA==1){data|=0x80;}else{data&=0x7F;}delay_us(2);DS_SCK_LOW;}return data;}//ds1302写寄存器写数据void ds1302_write_data(u8 reg,u8 data) {DS_SCK_LOW;DS_RST_LOW;//初始rst为低delay_us(2);DS_RST_HIGH;//sck为低时rst才可置高 write_one_byte(reg); //sck低到高delay_us(5);DS_SCK_LOW;write_one_byte(data); //sck低到高delay_us(5);//DS_SCK_HIGH;DS_RST_LOW;}//读ds1302寄存器数据u8 ds1302_read_data(u8 reg){u8 temp;DS_SCK_LOW;DS_RST_LOW;//初始rst为低delay_us(2);DS_RST_HIGH;//sck为低时rst才可置高 delay_us(2);write_one_byte(reg); //sck低到高delay_us(5);DS_SCK_LOW;temp=read_one_byte(); //sck由高到低delay_us(5);//DS_SCK_HIGH;DS_RST_LOW;return temp;}u8 hex_to_bcd(u8 hex_data){u8 temp;temp=(hex_data/10*16 + hex_data%10);return temp;}u8 bcd_to_hex(u8 bcd_data){u8 temp;temp=(bcd_data/16*10 + bcd_data%16);return temp;}//time初始化void time_init(){ds1302_write_data(0x8e,0x00);//关闭写保护ds1302_write_data(writeYear ,(time[0]));//写入hex格式数据ds1302_write_data(writeWeek,(time[1]));ds1302_write_data(WriteMonth,(time[2]));ds1302_write_data(WriteDay,(time[3]));ds1302_write_data(WriteHour,(time[4]));ds1302_write_data(WriteMinute,(time[5]));//ds1302_write_data(WriteSecond,(time[6]));//ds1302_write_data(0x8e,0x80);//开启写保护}//读取寄存器时间void time_read(){DSyear=ds1302_read_data(ReadYear);DSweek=ds1302_read_data(ReadWeek);DSmonth=ds1302_read_data(ReadMonth);DSday=ds1302_read_data(ReadDay);DShour=ds1302_read_data(ReadHour);DSminute=ds1302_read_data(ReadMinute);DSsecond=ds1302_read_data(ReadSecond);}2.4主函数---------------main-----------------------#include "sys.h"#include "delay.h"#include "usart.h"#include "led.h"#include "ds1302.h"Extern u8 DSsecond,DSminute,DShour,DSweek,DSday,DSmonth,DSyear;int main(void){delay_init();LED_Init();uart_init(115200);ds1302_init();time_init();while(1){time_read();//更新时间usart1_sendbyte(DSyear);usart1_sendbyte(DSmonth);usart1_sendbyte(DSday);usart1_sendbyte(DShour);usart1_sendbyte(DSminute);usart1_sendbyte(DSsecond);usart1_sendbyte(DSweek);GPIO_ResetBits(GPIOB,GPIO_Pin_5); //LED0闪烁delay_ms(250);GPIO_SetBits(GPIOB,GPIO_Pin_5); //delay_ms(250);}}3.结果串口调试助手hex显示,打印的是十六进制数据。

ds1302读秒程序

ds1302读秒程序
uchar sz[2];
uchar sec,n,n10;
sbit CLK =P3^5;
sbit IO =P3^6;
sbit RST =P3^7;
int qw,bw,sw,gw,a,b,c,i,k,j;
b=12;
void delay()//延时程序
{uchar j;
for(j=250;j>0;j--);
{
wr_com(0x8b);
n10=read1302(0x85);
n=read1302(0x85)&0x0f;//时
n10=n10>>4;
wr_data(n10+48);//注意是映射码,液晶中是写入的内部规定的映射表
wr_data(n+48);
display(":");
n10=read1302(0x83);//分
{
uchar i;
for(i=8;i>0;i--)
{
IO=(bit)(ucda&0x01);
CLK=1;
CLK=0;
ucda>>=1;
}
}
//--------------ReadOneByteData-----------------/
uchar ReadByte(void)
{
uchar i,a;
for(i=8;i>0;i--)
}
del() /*延时0.2秒*/
{
unsigned char i,j,k;
for(i=20;i>0;i--)
for(j=20;j>0;j--)
for(k=248;k>0;k--);
}

ds1302显示在12864的c语言程序

ds1302显示在12864的c语言程序
dat1 = dat / 10;
dat2 = dat % 10;
dat2 = dat2 + dat1 * 16;
return dat2;
}
//BCD码转换为数据
uchar BCD_Chg_Dat(uchar dat)
{
uchar dat1, dat2;
dat1 = dat / 16;
dat2 = dat % 16;
TSCLK = 1;//拉高时钟总线,产生上升沿数据被DS1302读走
cmd >>=1;//右移一位
}
for(i = 0; i < 8; i++)//每次写1位,写8次
{
TSCLK = 0;//拉低时钟总线
TIO = dat & 0x01; //写1位数据,从最低位开始写
TSCLK = 1;//拉高时钟总线,产生上升沿数据被DS1302读走
{
uchar i;
TRST = 0; //拉低使能端
TSCLK = 0;//拉低数据总线
TRST = 1; //拉高使能端,产生上升沿开始写数据
for(i = 0; i < 8; i++)//每次写1位,写8次
{
TSCLK = 0;//拉低时钟总线
TIO = cmd & 0x01; //写1位数据,从最低位开始写
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define MAIN_Fosc11059200UL//宏定义主时钟HZ

DS1302 的管脚排列及描述

DS1302 的管脚排列及描述

DS1302 的管脚排列及描述管脚描述:(管脚排列如图2-4所示)图2-4 DS1302管脚配置图Vcc1:主电源;Vcc2:备份电源。

当Vcc2>Vcc1+0.2V时,由Vcc2向DS1302供电,当Vcc2< Vcc1时,由Vcc1向DS1302供电;SCLK:串行时钟输入;I/O:双向数据线;RST:复位信号,在读、写数据期间,必须为高;X1,X2:晶振输入端。

一、DS1302编程原理1.DS1302内部寄存器组织DS1302有关日历、时间的寄存器共有12个,其中有7个寄存器(读时81h~8Dh,写时80h~8Ch),存放的数据格式为BCD码形式,如表3-1所示。

表 3-1 DS1302有关日历、时间的寄存器DS1302的工作模式寄存器所谓突发模式是指一次传送多个字节的时钟信号和RAM数据。

突发模式寄存器如表3-3所示。

表3-3 突发模式寄存器此外,DS1302还有充电寄存器等。

2.读写时序说明DS1302是SPI总线驱动方式。

它不仅要向寄存器写入控制字,还需要读取相应寄存器的数据。

要想与DS1302通信,首先要了解DS1302的控制字。

DS1302的控制字如图 3-3所示。

图 3-3 控制字(即地址及命令字节)控制字的最高有效位(位7)必须是逻辑1,如果它为0,则不能把数据写入到DS1302中;位6:如果为0,则表示存取日历时钟数据,为1表示存取RAM数据;位5至位1(A4~A0):指示操作单元的地址;位0(最低有效位):如为0,表示要进行写操作,为1表示进行读操作。

控制字总是从最低位开始输出。

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

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

数据读写时序如图 3-4所示,数据可分为单字节传送和多字节传送。

图 3-4 数据读写时序[1]二、DS1302软件设计模块图DS1302软件设计模块图如图3-5所示,具体可以包括三个模块:写入数据模块、读出数据模块、初始化时间模块,每个模块又可以包含几个子函数,具体DS1302程序可见附录六。

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,指定读操作(输出)。

DS1302程序代码

DS1302程序代码

DS1302程序代码#include <reg51.h>#include <string.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned intsbit SDA=P1^0; //DS1302数据线sbit CLK=P1^1; //DS1302时钟线sbit RST=P1^2; // DS1302 复位线char Adjust_Index=-1; //当前调节的时间对象:秒,分,时,日,月,年(0,1,2,3,4,6)uchar MonthsDays[]={0,31,0,31,30,31,30,31,31,30,31,30,31}; // 一年中每个月的天数,二月的天数由年份决定uchar DateTime[7];//所读取的日期时间//函数声明void Write_Byte_TO_DS1302(uchar X); // 向DS1302写入一个字节uchar Read_Byte_FROM_DS1302(); //从DS1302中读取一个字节uchar Read_Data_FROM_DS1302(uchar addr); //从DS1302指定位置读取数据, 读数据void Write_Data_TO_DS1302(uchar addr,uchar dat); // 向DS1302指定位置写入数据, 写数据void SET_DS1302(); // 设置时间void GetTime(); // 读取当前时间uchar Is_Leapyear(uint year);// 判断是否为闰年//*--------写字节函数,向DS1302写入一个字节--------*//void Write_Byte_TO_DS1302(uchar X) // 向DS1302写入一个字节{uchar i;for(i=0;i<8;i++){SDA=X&1;CLK=1;CLK=0;X>>=1;}}//*--------读字节函数,从DS1302读取一个字节--------*//uchar Read_Byte_FROM_DS1302() //从DS1302中读取一个字节{uchar i,byte,t;for(i=0;i<8;i++){byte>>=1;t=SDA;byte|=t<<7;CLK=1;CLK=0;}//BCD码转换return byte/16*10+byte%16;}//-------------------------------------------------------------//从DS1302指定位置读取数据 , 读数据//---------------------------------------------------------------uchar Read_Data_FROM_DS1302(uchar addr) //从DS1302指定位置读取数据 , 读数据{uchar dat;RST=0;CLK=0;RST=1;Write_Byte_TO_DS1302(addr); //向DS1302写入一个地址dat=Read_Byte_FROM_DS1302(); //在上面写入的地址中读取数据CLK=1;RST=0;return dat;}//-------------------------------------------------------------//向DS1302指定位置写入数据, 写数据//---------------------------------------------------------------void Write_Data_TO_DS1302(uchar addr,uchar dat) // 向DS1302指定位置写入数据, 写数据{CLK=0;RST=1;Write_Byte_TO_DS1302(addr);Write_Byte_TO_DS1302(dat);CLK=1;RST=0;}//-----------------------------------------------------------// 设置时间//---------------------------------------------------------void SET_DS1302() // 设置时间{uchar i;Write_Data_TO_DS1302(0x8E,0x00); //写控制字,取消写保护// 分,时,日,月,年依次写入for(i=1;i<7;i++){// 分的起始地址是10000010(0x82),后面依次是时,日,月,周,年,写入地址每次递增2Write_Data_TO_DS1302(0x80+2*i,(DateTime[i]/10<<4)|(DateTime[i]%10));}Write_Data_TO_DS1302(0x8E,0x80); //写控制字,加写保护}//--------------------------------------------------------// 读取当前时间//-------------------------------------------------------void GetTime() // 读取当前时间{uchar i;for(i=0;i<7;i++){DateTime[i]=Read_Data_FROM_DS1302(0x81+2*i);}}//-------------------------------------------------------------------// 判断是否为闰年//-------------------------------------------------------------------uchar Is_Leapyear(uint year){return (year%4==0&&year%100!=0)||(year%400==0) ;}//------------------------------------------------------------------// 求自2000.1.1开始的任何一天是星期几?//----------------------------------------------------------------------void Refresh_Week_Day(){uint i,d,w=5; //已知1999年12.31是星期五for(i=2000;i<2000+DateTime[6];i++){d=Is_Leapyear(i)?366:365;w=(w+d)%7;}d=0;for (i=1;i<DateTime[4];i++){d+=MonthsDays[i];}d+=DateTime[3];//保存星期,0-6表示星期日,星期一至星期六,为了与DS1302的星期格式匹配,返回值需要加1DateTime[5]=(w+d)%7+1;}//-------------------------------------------------//年,月,日和时,分++/--//----------------------------------------------------void Datetime_Adjust(char X){switch(Adjust_Index){case 6: //年调整,00-99if(X==1&&DateTime[6]<99){DateTime[6]++;}if(X==-1&&DateTime[6]>0){DateTime[6]--;}//获取2月天数MonthsDays[2]=Is_Leapyear(2000+DateTime[6])?29:28;//如果年份变化后当前月份的天数大于上限则设为上限if(DateTime[3]>MonthsDays[DateTime[4]]){DateTime[3]=MonthsDays[DateTime[4]];}Refresh_Week_Day(); //刷新星期break;case 4: //月调整01-12if(X==1&&DateTime[4]<12){DateTime[4]++;}if(X==-1&&DateTime[4]>1){DateTime[4]--;}//获取2月天数MonthsDays[2]=Is_Leapyear(2000+DateTime[6])?29:28;//如果年份变化后当前月份的天数大于上限则设为上限if(DateTime[3]>MonthsDays[DateTime[4]]){DateTime[3]=MonthsDays[DateTime[4]];}Refresh_Week_Day(); //刷新星期break;case 3: // 日调整00-28或00-29或00-30或00-31//调节之前首先根据当前年份得出该年中2月的天数MonthsDays[2]=Is_Leapyear(2000+DateTime[6])?29:28;//根据当前月份决定调节日期的上限if(X==1&&DateTime[3]<MonthsDays[DateTime[4]]){DateTime[3]++;}if(X==-1&&DateTime[3]>0){DateTime[3]--;}Refresh_Week_Day(); //刷新星期break;case 2: // 时调整if(X==1&&DateTime[2]<23){DateTime[2]++;}if(X==-1&&DateTime[4]>0){DateTime[2]--;}break;case 1: // 分调整if(X==1&&DateTime[1]<59){DateTime[1]++;}if(X==-1&&DateTime[4]>0){DateTime[1]--;}break;case 0: // 秒调整if(X==1&&DateTime[1]<59){DateTime[0]++;}if(X==-1&&DateTime[4]>0){DateTime[0]--;}break;}}。

DS1302 时钟芯片 C程序

DS1302 时钟芯片 C程序
/*DS1302操作的引脚定义*/
sbit ds_sclk=P1^6;//串行时钟,输入,控制数据的输入输出
sbit ds_io =P3^5;//三线接口时的双向数据线
sbit ds_ce =P1^7;//输入信号,在读写数据期间,必须为高。该引脚有两个功能:
//第一,CE开始控制字访问移位寄存器的控制逻辑:其次,CE提供结束单字节或多字节数据传输的方法。
年份寄存器 8CH 8DH 00-99
更新时间:2012年07月17日
更新版本:无
更新日志:
2012年07月17日 文件大小:256字节
2012年07月17日 开始优化代码 将相同的代码写成函数以便调用
2012年07月17日 文件大小:276字节
2012年07月17日 除了突发功能没有编写其他的均已写出
/*DS1302年份寄存器地址*/
#define Read_years 0x8d //读取的年地址
#define Write_years 0x8c //写入的年地址
/*DS1302写保护寄存器地址*/
#define Read_wp 0x8f //读取的写保护地址
20ndef __DS_1302_H__
#define __DS_1302_H__
#include<stc89.h> //包含单片机寄存器的头文件
#define uchar unsigned char
#define uint unsigned int
ds1302_write(Write_years ,Decimal_bcd(12));//写入时间年
ds1302_write(Write_charging,ds_cr6 ); //写入是否涓流充电 不充电

DS1302程序代码

DS1302程序代码
while(temp!=0xf0)
{
temp=P1;
switch(temp)
{
case 0x7e:num=0;
break;
case 0xbe:num=1;
break;
case 0xde:num=2;
}
}
/**************时钟显示函数************************/
void display_led()
{
unsigned char led[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
{
unsigned char i;
unsigned char m_rd_byte;
unsigned char m_tmpByte; //定义中介字节,暂时存放读取的一位数值
m_rd_byte = 0x00; //读取字节地址清零
TIMERIO = 1;
unsigned char read(unsigned char ds1302addr);
void DS1302Initial(void);
void read_time();
uchar time[3]={0,0,0};
uchar ds[7]={0x00,0x59,0x20,0x15,0x03,0x03,0x06};//时钟数组,依次是秒分时日月星期年
time[1]=read(0x83); //读取分
time[2]=read(0x85); //读取钟
display_led(); //显示时间
}
}
/***********************置位reset******************************/

ds1302程序-stm

ds1302程序-stm

/****************************************************************************** * File name --> <strong><font color="#FF0000">ds1302</font></strong>.c* Author--> By Sam Chan* Version--> V1.0* Date--> 08 - 23 - 2012* Brief--> 时钟芯片DS1302驱动** Copyright (C) 20*** All rights reserved******************************************************************************* **File Update* Version--> V1.0.1* Author--> By Sam Chan* Date--> 10 - 20 - 2013* Revise--> A、增加对STM32控制的移植支持* --> B、增加对置的RAM操作相关函数* --> C、增加检测DS1302是否存在,是否第一次上电检测函数* --> D、增加对DS1302置的锂电池充电寄存器参数设置函数和结构体*******************************************************************************/ #include "ds1302.h"/****************************************************************************** 定义变量******************************************************************************/ #define Date TimeValue.date#define Min TimeValue.minute#define Sec TimeValue.second#define Hour TimeValue.hour#define Week TimeValue.week#define Month TimeValue.month#define Year TimeValue.yearTime_Typedef TimeValue;//定义时间数据指针void Time_Init(){TimeValue.date=24;TimeValue.hour=6;TimeValue.minute=12;TimeValue.month=5;TimeValue.second=0;TimeValue.week=2;TimeValue.year=16;}Charge_Typedef ChargeValue;//定义充电寄存器/****************************************************************************** * Function Name --> GPIO初始化* Description--> none* Input--> none* Output--> none* Reaturn--> none******************************************************************************/void DS1302_GPIOInit(void){GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);//开启GPIOC外设时钟/*初始化GPIOC*/GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;GPIO_Init(GPIOC, &GPIO_InitStructure);}/****************************************************************************** * Function Name --> DS1302写入一个字节数据* Description--> none* Input--> dat:要写入的数据* Output--> none* Reaturn--> none******************************************************************************/ void DS1302_Write_Byte(u8 dat){u8 i;DS1302_SDA_OUT();//设置为输出口for(i=0;i<8;i++){DS1302_SCL = 0;//时钟线拉低if(dat & 0x01)DS1302_SDA = 1;//数据线放上数据,先发低位else DS1302_SDA = 0;dat >>= 1;//数据右移一位DS1302_SCL = 1;//发送数据,上升沿有效}}/****************************************************************************** * Function Name --> DS1302读出一个字节数据* Description--> none* Input--> none* Output--> none* Reaturn--> 读到的数据******************************************************************************/ unsigned DS1302_Read_Byte(){u8 ReData=0x00;u8 i;DS1302_SDA_IN();//设置为输入口for(i=0;i<8;i++){if(DS1302_IN_SDA == 1){ReData |= 0x80;}//读出一位数据是“1”DS1302_SCL = 0;//时钟线拉低ReData >>= 1;//数据右移一位,先读取低位,数据补“0”DS1302_SCL = 1;//上升沿读取数据}return(ReData);//返回读取到的数据}/****************************************************************************** * Function Name --> 向DS1302某地址写入数据* Description--> none* Input--> add:要操作的地址*dat:要写入的数据* Output--> none* Reaturn--> none******************************************************************************/ void DS1302_Write_Data(u8 add,u8 dat){DS1302_RST = 0;//复位脚拉低DS1302_SCL = 0;//时钟线拉低DS1302_RST = 1;//复位脚拉高DS1302_Write_Byte(add);//写入要操作地址DS1302_Write_Byte(dat);//写入数据//delay_us(5);DS1302_RST = 0;DS1302_SCL = 0;}/****************************************************************************** * Function Name --> 从DS1302某地址读取数据* Description--> none* Input--> add:要操作的地址* Output--> none* Reaturn--> 要读取的寄存器的数值******************************************************************************/unsigned DS1302_Read_Data(u8 add){u8 Temp;DS1302_RST = 1;DS1302_Write_Byte(add);//写入要操作地址Temp = DS1302_Read_Byte();//开始读取数据DS1302_RST = 0;return(Temp);//返回读取到的数据}/****************************************************************************** * Function Name --> 主电源对备用电池充电设置* Description--> 如果备用电池接的是可充电的锂电池或者其他可充电电池的时候,*可以打开DS1302的充电电路,利用主供电对电池进行充电,免的换电池的麻烦* Input--> *CHG_dat:寄存器控制指针* Output--> none* Reaturn--> none******************************************************************************/ void DS1302_Charge_Manage(Charge_Typedef* CHG_dat){u8 CHG_Value;CHG_Value = (CHG_dat->TCSx << 4) | (CHG_dat->DSx << 2) | CHG_dat->RSx;DS1302_WP_Disable();//取消写保护DS1302_Write_Data(Trickle_Charger_Address,CHG_Value);DS1302_WP_Enable();//打开写保护}/****************************************************************************** * Function Name --> DS1302置的RAM读写操作* Description--> none* Input--> *pBuff:读写数据存放区*WRadd:读写起始地址,围在RAM_Address0 ~ RAM_Address28之间,最后一位地址有其他用途*num:读写字节数据的数量,围在1 ~ 28之间*RW:读写判断位。

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

随笔/mcu51 发表于2007-06-17, 21:53
/*----------------------------------------------
DS1302读写一体化C51源程序
HotPower@
------------------------------------------------*/
//打开DS1302
void TimeSpiOpen(void)
{
TIMECLK = 0;
TIMERST = 0;//禁止DS1302
TIMEIO = 1;//释放数据总线
TIMERST = 1;//使能DS1302
}
//关闭DS1302
void TimeSpiClose(void)
{
TIMERST = 0;//禁止DS1302
TIMEIO = 1;//释放数据总线
TIMECLK = 1;
}
//读写DS1302
unsigned char TimeSpiReadWrite(unsigned char val)
{
unsigned char i;
ACC = val;//取8位数据
for (i = 8;i > 0; i--)
{
TIMECLK = 0;//时钟下降沿输入数据(DS1302读)
_nop_();//延时
CY = TIMEIO;//接收串行数据到CY
_rrca_();//右移一位数据到CY(先存后取)
TIMEIO = CY;//发送串行数据
TIMECLK = 1;//时钟上升沿打入数据(DS1302写)
TIMEIO = 1;//释放数据总线
}
val = ACC;
return val;
}
//读DS1302字节
unsigned char TimeByteRead(unsigned char address)
{
TimeSpiOpen();//打开DS1302
TimeSpiReadWrite(address);//写入DS1302命令 address = TimeSpiReadWrite(0xff);//读入DS1302数据
TimeSpiClose();//关闭DS1302
return address;//返回数据
}
//读DS1302RAM字节
unsigned char TimeRamByteRead(unsigned char address)
{
TimeSpiOpen();//打开DS1302
TimeSpiReadWrite((address << 1) | 0xc1);//写入DS1302命令 address = TimeSpiReadWrite(0xff);//读入DS1302数据
TimeSpiClose();//关闭DS1302
return address;//返回数据
}
//写DS1302字节
void TimeByteWrite(unsigned char address, unsigned char val)
{
TimeSpiOpen();//打开DS1302
TimeSpiReadWrite(address);//写地址
TimeSpiReadWrite(val);//写数据
TimeSpiClose();//关闭DS1302
}
//写DS1302字节
void TimeRamByteWrite(unsigned char address, unsigned char val)
{
TimeSpiOpen();//打开DS1302
TimeSpiReadWrite((address << 1) | 0xc0);//写地址
TimeSpiReadWrite(val);//写数据
TimeSpiClose();//关闭DS1302
}
//使能DS1302写保护
void TimeWriteEnable(void)
{
TimeByteWrite(timewriteregall, timewriteseg);//使能DS1302写保护
}
//开放DS1302写保护
void TimeWrieDisbale(void)
{
TimeByteWrite(timewriteregall, 0);//开放DS1302写保护
}
//DS1302工作开始
void TimeWorkStart(void)
{
unsigned char val;
val = TimeByteRead(timereadseg);//读秒数据
val &= 0x7f;//打开晶振
TimeWrieDisbale();//开放DS1302写保护
TimeByteWrite(timewriteseg, val);//打开晶振
TimeByteWrite(tricklewrite, 0xa5);//打开充电二极管 TimeWriteEnable();//使能DS1302写保护
}。

相关文档
最新文档