ds1302时钟程序详解,ds1302程序流程图(C程序)

合集下载

ds1302程序及原理图

ds1302程序及原理图

/**************************************************;文件名:DS1302.c;功能:设置时间,然后将时间读出显示在数码管上;硬件描述:PORTD口接数码管的8个笔段; PORTA 0~2及PORTE 0~2分别接6位数码管的位;RC3接SCK,RC4接SDA,RC2接RST*/#include "pic.h"#define uchar unsigned char#define uint unsigned int#define Hidden 16__CONFIG(HS&WDTDIS&LVPDIS); //配置文件,设置为HS方式振荡,禁止看门狗,低压编程关闭ucharDispTab[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x8 6,0x8E,0xFF};uchar BitTab[]={0xfb,0xfd,0xfe};uchar DispBuf[6];#define LSB 0x01#define WrEnDisCmd 0x8e //写允许/禁止指令代码#define WrEnDat 0x00 //写允许数据#define WrDisDat 0x80 //写禁止数据#define OscEnDisCmd 0x80 //振荡器允许/禁止指令代码#define OscEnDat 0x00 //振荡器允许数据#define OscDisDat 0x80 //振荡器禁止数据#define WrMulti 0xbe //写入多个字节的指令代码#define WrSingle 0x84 //写入单个字节的指令代码#define RdMulti 0xbf //读出多个字节的指令代码#define cClk RC3 //与时钟线相连的PIC16F877A芯片的管脚#define cDat RC4 //与数据线相连的PIC16F877A芯片的管脚#define cRst RC2 //与复位端相连的PIC16F877A芯片的管脚#define SCL_CNT TRISC3 //SCL管脚控制位#define SDA_CNT TRISC4 //SDA管脚控制位#define RST_CNT TRISC2 //RST管脚控制位void mDelay(uint DelayTime){ uint temp;for(;DelayTime>0;DelayTime--){ for(temp=0;temp<270;temp++){;}}}void interrupt Disp(){ static uchar dCount; //用作显示的计数器if(TMR1IF==1&&TMR1IE==1)//Timer 1 inetrrupt{TMR1H=-(8000/256);TMR1L=-(8000%256); //重置定时初值}PORTA|=0x07; //关前面的显示PORTE|=0X07; //关前面的显示PORTD=DispTab[DispBuf[dCount]]; //显示第i位显示缓冲区中的内容if(dCount<3)PORTE&=BitTab[dCount]; //第1~3位是由PORTE控制的elsePORTA&=BitTab[dCount-3]; //第4~6位是由PORTA的低3位控制的dCount++;if(dCount==6)dCount=0;TMR1IF=0; //清中断标志}//数码管位 1 2 3 4 5 6//引脚RE0 RE1 RE2 RA2 RA1 RA0//根据这个表,只要改变PORTA&=0xfe,即可点亮任意一个数码管//例:PORTA&=0xfd //点亮第5位数码管// PORTE&=0xfe //点亮第3位数码管void uDelay(uchar i){ for(;i>0;i--){;}}void SendDat(uchar Dat){ uchar i;for(i=0;i<8;i++){cDat=Dat&LSB; //数据端等于tmp数据的末位值Dat>>=1;cClk=1;uDelay(1);cClk=0;}}/*写入1个或者多个字节,第1个参数是相关命令#define WrMulti 0xbe //写入多个字节的指令代码#define WrSingle 0x84 //写入单个字节的指令代码第2个参数是待写入的值第3个参数是待写入数组的指针*/void WriteByte(uchar CmdDat,uchar Num,uchar *pSend){uchar i=0;SDA_CNT=0; //数据端设为输出cRst=0;uDelay(1);cRst=1;SendDat(CmdDat);for(i=0;i<Num;i++){ SendDat(*(pSend+i));}cRst=0;}/*读出字节,第一个参数是命令#define RdMulti 0xbf //读出多个字节的指令代码第2个参数是读出的字节数,第3个是指收数据数组指针*/void RecByte(uchar CmdDat,uchar Num,uchar *pRec){uchar i,j,tmp;SDA_CNT=0; //数据端设为输出cRst=0; //复位引脚为低电平uDelay(1);cClk=0;uDelay(1);cRst=1;SendDat(CmdDat); //发送命令SDA_CNT=1; //数据端设为输入for(i=0;i<Num;i++){ for(j=0;j<8;j++){ tmp>>=1;if(cDat)tmp|=0x80;cClk=1;uDelay(1);cClk=0;}*(pRec+i)=tmp;}uDelay(1);cRst=0;}/*当写保护寄存器的最高位为0时,允许数据写入寄存器。

DS1302显示时钟的C程序

DS1302显示时钟的C程序

#include&lt;reg52.h&gt; //包含单片机寄存器的头文件#include&lt;intrins.h&gt; //包含_nop_()函数定义的头文件#define uint unsigned int#define uchar unsigned charunsigned char code digit[10]={&quot;0123456789&quot;}; //定义字符数组显示数字sbit SCLK=P1^0; //位定义1302芯片的接口,时钟输出端口定义在P1.0引脚 sbit DATA=P1^1; //位定义1302芯片的接口,数据输出端定义在P1.1引脚sbit RST=P1^2; //位定义1302芯片的接口,复位端口定义在P1.2引脚/*****************************************************函数功能:延时若干微秒入口参数:n***************************************************/void delay(uint i){ unsigned char j;while(i--){for(j=110;j&gt;0;j--){;}}}/*****************************************************函数功能:向1302写一个字节数据入口参数:x***************************************************/void Write1302(unsigned char dat){unsigned char i;SCLK=0; //拉低SCLK,为脉冲上升沿写入数据做好准备 delay(2); //稍微等待,使硬件做好准备for(i=0;i&lt;8;i++) //连续写8个二进制位数据{DATA=dat&amp;0x01; //取出dat的第0位数据写入1302 低位在前,高位在后 delay(2); //稍微等待,使硬件做好准备SCLK=1; //上升沿写入数据delay(2); //稍微等待,使硬件做好准备SCLK=0; //重新拉低SCLK,形成脉冲dat&gt;&gt;=1; //将dat的各数据位右移1位,准备写入下一个数据位 }}/*****************************************************函数功能:根据命令字,向1302写一个字节数据入口参数:Cmd,储存命令字;dat,储存待写的数据。

DS1302时钟芯片 C语言程序设计

DS1302时钟芯片 C语言程序设计

unsigned char i,tmp; time_buf[1]=ds1302_read_byte(ds1302_year_add); //年 time_buf[2]=ds1302_read_byte(ds1302_month_add); //月 time_buf[3]=ds1302_read_byte(ds1302_date_add); //日 time_buf[4]=ds1302_read_byte(ds1302_hr_add); //时 time_buf[5]=ds1302_read_byte(ds1302_min_add); //分 time_buf[6]=(ds1302_read_byte(ds1302_sec_add))&0x7F;//秒 time_buf[7]=ds1302_read_byte(ds1302_day_add); //周 for(i=0;i<8;i++){ //BCD处理 tmp=time_buf[i]/16; time_buf1[i]=time_buf[i]%16; time_buf1[i]=time_buf1[i]+tmp*10; } } /*DS302初始化函数*/ void ds1302_init(void) { RST_CLR; /*RST脚置低*/ SCK_CLR; /*SCK脚置低*/ }
} else { temp &= 0x7F; } SCK_SET; SCK_CLR; } RST_CLR; /*停止DS1302总线*/ return temp; } /*向DS302写入时钟数据*/ void ds1302_write_time(void) { unsigned char i,tmp; for(i=0;i<8;i++){ //BCD处理 tmp=time_buf1[i]/10; time_buf[i]=time_buf1[i]%10; time_buf[i]=time_buf[i]+tmp*16; } ds1302_write_byte(ds1302_control_add,0x00); //关闭写保护 ds1302_write_byte(ds1302_sec_add,0x80); //暂停 ds1302_write_byte(ds1302_charger_add,0xa9); //涓流充电 ds1302_write_byte(ds1302_year_add,time_buf[1]); //年 ds1302_write_byte(ds1302_month_add,time_buf[2]); //月 ds1302_write_byte(ds1302_date_add,time_buf[3]); //日 ds1302_write_byte(ds1302_day_add,time_buf[7]); //周 ds1302_write_byte(ds1302_hr_add,time_buf[4]); //时 ds1302_write_byte(ds1302_min_add,time_buf[5]); //分 ds1302_write_byte(ds1302_sec_add,time_buf[6]); //秒 ds1302_write_byte(ds1302_day_add,time_buf[7]); //周 ds1302_write_byte(ds1302_control_add,0x80); //打开写保护 } /*从DS302读出时钟数据*/ void ds1302_read_time(void) {

DS1302数码管电子闹钟程序

DS1302数码管电子闹钟程序

/*****************************************************///DS1302+数码管+3个独立按键//// 精确定时/////*****************************************************/ /****************************************************************/// 利用ds1302精确定时,同时按键可调时间。

//// 每操作一次时钟,都会有蜂鸣器响大约200ms,以提示操作。

///***************************************************************/#include<reg52.h>#include"ds1302.h"uchar code tab[]={ 0x3F,/*0*/0x06,/*1*/0x5B,/*2*/0x4F,/*3*/0x66,/*4*/0x6D,/*5*/0x7D,/*6*/0x07,/*7*/0x7F,/*8*/0x6F,/*9*/} ;//共阴码char clock1[3]={0};int i,j=0,flag1=0;void delay(uint xms){uint x,y;for(x=xms;x>0;x--)for(y=110;y>0;y--);}void init()//初始化{//RST=0;//SCLK=0;//write_1302(0x80,0x00);//写控制字,允许写//write_1302(0x90,0x00);//禁止涡流充电TMOD=0x01;TH0=(65536-50000)/256;TL0=(65536-50000)%256;EA=1;ET0=1;TR0=1;}void display(uchar miaog,uchar miaos,uchar feng,uchar fens,uchar shig,uchar shis)//数码管动态显示{P2=0x7f;P0=tab[miaog];delay(5);P2=0xbf;P0=tab[miaos];delay(5);P2=0xdf;P0=0xc0;delay(5);P2=0xef;P0=tab[feng];delay(5);P2=0xf7;P0=tab[fens];delay(5);P2=0xfb;P0=0xc0;delay(5);P2=0xfd;P0=tab[shig];delay(5);P2=0xfe;P0=tab[shis];delay(5);}write_sfm(uchar miao,uchar fen,uchar shi) //写入到数码管{uchar miaog,miaos,feng,fens,shig,shis;miaog=miao%10;miaos=miao/10;feng=fen%10;fens=fen/10;shig=shi%10;shis=shi/10;display(miaog,miaos,feng,fens,shig,shis);}void didi() //发声程序{buzzer=0;delay(50);buzzer=1;}void keyscan()//按键扫描程序{uchar temp;if(key1==0) //功能键{if(key1==0){while(!key1);key1n=key1n++;if(key1n==5)key1n=1;switch(key1n){case 1://didi();temp=(miao)/10*16+(miao)%10;//将秒转化成bcd码,没这句秒就变化,不知为什么write_1302 (0x8e,0x00); //禁止写保护write_1302 (0x80,0x80|temp); //时钟暂停write_1302 (0x8e,0x80); //允许写保护break;case 2 ://didi();break;case 3 ://didi();break;case 4 ://didi();temp=miao/10*16+miao%10;write_1302 (0x8e,0x00); //禁止写保护write_1302 (0x80,0x00|temp);//时钟开始write_1302 (0x8e,0x80); //允许写保护break;}}}if(key4==0) //闹钟键{if(key4==0){while(!key4);keyn++;if(keyn==4)keyn=0;while(keyn){EA=0; //闹钟键if(key4==0)if(key4==0){while(!key4);keyn++;if(keyn==4)keyn=0;}write_sfm(clock1[2],clock1[1],clock1[0]);if(keyn==1) //时修改{if(key3==0) //减键{//delay(3);if(key3==0){while(!key3);clock1[0]--;if(clock1[0]<0)clock1[0]=24;}}if(key2==0) //加键{//delay(3);if(key2==0){while(!key2);clock1[0]++;if(clock1[0]>24)clock1[0]=0;}}}if(keyn==2) //分修改{if(key3==0) //减键{//delay(3);if(key3==0){while(!key3);clock1[1]--;if(clock1[1]<0)clock1[1]=59;}}if(key2==0) //加键{//delay(3);if(key2==0){while(!key2);clock1[1]++;if(clock1[1]>59)clock1[1]=0;}}}if(keyn==3) //秒修改{if(key3==0) //减键{//delay(3);if(key3==0){while(!key3);clock1[2]--;if(clock1[2]<0)clock1[2]=59;}}if(key2==0) //加键{//delay(3);if(key2==0){while(!key2);clock1[2]++;if(clock1[2]>59)clock1[2]=0;}}}}} EA=1;}if(key1n!=0) //当按下功能键key1,按以下才有用{if(key2==0) //加键{delay(3);if(key2==0){while(!key2);switch(key1n){case 1 : //didi(); //秒temp=(miao+1)/10*16+(miao+1)%10;if(miao==59)temp=0;write_1302 (0x8e,0x00); //禁止写保护write_1302 (0x80,0x80|temp);write_1302 (0x8e,0x80); //允许写保护break;case 2 : // didi(); //分temp=(fen+1)/10*16+(fen+1)%10;if(fen==59)temp=0;write_1302 (0x8e,0x00); //禁止写保护write_1302 (0x82,temp);write_1302 (0x8e,0x80); //允许写保护break;case 3 :// didi();temp=(shi+1)/10*16+(shi+1)%10; //时if(shi==23)temp=0;write_1302 (0x8e,0x00); //禁止写保护write_1302 (0x84,temp);write_1302 (0x8e,0x80); //允许写保护break;}}}if(key3==0) //减键{delay(3);if(key3==0){while(!key3);switch(key1n){case 1 ://didi();temp=(miao-1)/10*16+(miao-1)%10; //秒if(miao==0)temp=89;write_1302 (0x8e,0x00); //禁止写保护write_1302 (0x80,0x80|temp);write_1302 (0x8e,0x80); //允许写保护break;case 2 ://didi();temp=(fen-1)/10*16+(fen-1)%10; //分if(fen==0)temp=89;write_1302 (0x8e,0x00); //禁止写保护write_1302 (0x82,temp);write_1302 (0x8e,0x80); //允许写保护break;case 3 ://didi();temp=(shi-1)/10*16+(shi-1)%10; //时if(shi==0)temp=35;write_1302 (0x8e,0x00); //禁止写保护write_1302 (0x84,temp);write_1302 (0x8e,0x80); //允许写保护break;}}}}//write_1302(0x80,miao|0x80);//miao++;/* if(key2==0){if(key2==0){while(!key2);write_1302(0x80,miao|0x00);//打开1302振荡器}}*/}void main(){init();//buzzer=0;//miao=20;//fen=10;//shi=23;while(1){miao = BCD_Decimal(read_1302(0x81));fen = BCD_Decimal(read_1302(0x83));shi = BCD_Decimal(read_1302(0x85));keyscan();if((miao==clock1[2])&&(fen==clock1[1])&&(shi==clock1[0])) {flag1=1;for(i=0;i<10;i++)didi();}if(j==100) for(i=0;i<10;i++) didi();if(j==200) {for(i=0;i<10;i++)didi();flag1=0;j=0;}}}void tiemr0() interrupt 1{if(flag1) j++;TH0=(65536-50000)/256;TL0=(65536-50000)%256;write_sfm(miao,fen,shi); }。

DS1302时钟C语言编程完整实例

DS1302时钟C语言编程完整实例

1 DS1302 简介:DS1302是美国D ALLAS 公司推出的一种高性能、低功耗的实时时钟芯片,附加31字节静态R AM,采用S PI 三线接口与C PU 进行同步通信,并可采用突发方式一次传送多个字节的时钟信号和R AM数据。

实时时钟可提供秒、分、时、日、星期、月和年,一个月小与31天时可以自动调整,且具有闰年补偿功能。

工作电压宽达2.5~5.5V。

采用双电源供电(主电源和备用电源),可设置备用电源充电方式,提供了对后背电源进行涓细电流充电的能力。

DS1302的外部引脚分配如图1所示及部结构如图2所示。

DS1302用于数据记录,特别是对某些具有特殊意义的数据点的记录上,能实现数据与出现该数据的时间同时记录,因此广泛应用于测量系统中。

图1 DS1302的外部引脚分配图2 DS1302的部结构各引脚的功能为:V cc1:主电源;Vcc2:备份电源。

当V cc2>Vcc1+0.2V 时,由V cc2向D S1302供电,当V cc2< Vcc1时,由V cc1向D S1302供电。

SCLK:串行时钟,输入,控制数据的输入与输出;I/O:三线接口时的双向数据线;CE:输入信号,在读、写数据期间,必须为高。

该引脚有两个功能:第一,CE 开始控制字访问移位寄存器的控制逻辑;其次,CE 提供结束单字节或多字节数据传输的方法。

DS1302有下列几组寄存器:① D S1302有关日历、时间的寄存器共有12个,其中有7个寄存器 (读时81h ~8Dh ,写时80h ~8Ch ),存放的数据格式为 BCD 码形式, 如图3所示。

图 3 DS1302有关日历、时间的寄存器 小时寄存器(85h 、84h )的位7用于定义 D S1302是运行于12小时 模式还是24小时模式。

当为高时,选择12小时模式。

在12小时模式时,位5是 ,当为1时,表示 PM 。

在24小时模式时,位5是第二个10小时 位。

秒寄存器(81h 、80h )的位7定义为时钟暂停标志(CH )。

ds1302时钟程序详解-ds1302程序流程图(C程序)

ds1302时钟程序详解-ds1302程序流程图(C程序)

ds1302时钟程序详解,ds1302程序流程图(C程序)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(D 0)为逻辑0,指定写操作(输入),D0=1,指定读操作(输出)。

DS1302程序及连接图

DS1302程序及连接图

/****************************************************************************** ** 标题: 试验数码管显示时钟**** 通过本例程了解DS1302时钟芯片的基本原理和使用,理解并掌握DS1302时钟芯片** 驱动程序的编写以及实现数字字符在数码管中的显示。

** 注意:JP1302跳线冒要短接。

** 请学员认真消化本例程,懂DS1302在C语言中的操作******************************************************************************** */#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:00unsigned 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};//共阴数码管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程序流程图

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实时时钟程序说明
下面是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;

ds1302实时时钟c程序加仿真原理图

ds1302实时时钟c程序加仿真原理图

#ifndef _1602_yejing_#define _1602_yejing_#include<reg52.h>#define uchar unsigned char#define uint unsigned intsbit lcden=P3^4;sbit lcdrs=P3^5;void delay(uint z){uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}void write_com(uchar com) {lcdrs=0;P0=com;delay(5);lcden=1;delay(5);lcden=0;}void write_data(uchar date){lcdrs=1;P0=date;delay(5);lcden=1;delay(5);lcden=0;}void write_lcd(uchar x,char *cha){ uchar length,i=0;write_com(x);for(length=0;cha[length]!=0;length++);for(i=0;i<length;i++){write_data(cha[i]);delay(5);}}void write_bcd(uchar cha){uchar ch1,ch2;ch1=(cha&0x0f)+'0';ch2=((cha>>4)&0x0f)+'0';write_data(ch2);write_data(ch1);}void write_fd(float t)//显示float型函数{ uchar s1,s2,s3,s4;uint tt;tt=t*100;s1=tt/1000;s1+=0x30;s2=tt%1000/100;s2+=0x30;s3=tt%1000%100/10;s3+=0x30;s4=tt%10;s4+=0x30;write_data(s1);write_data(s2);write_data(46);write_data(s3);write_data(s4);}void init(){lcden=0;write_com(0x38);//设置16*2显示write_com(0x0c);//设置开显示,不显示光标write_com(0x06);//写一个字符后地址指针加1write_com(0x01);//显示清0,数据指针清0}#endif/**************************************************************************THE REAL TIMER DS1302 DRIVER LIBCOPYRIGHT (c) 2010 BY ZYK.-- ALL RIGHTS RESERVED --File Name: DS1302.hAuthor: ZHANG YUAN KECreated: 2010/06/21Modified: NORevision: 1.0***************************************************************************/ #ifndef _DS1302_2010_06_21_#define _DS1302_2010_06_21_sbit SCLK = P1^6; //实时时钟时钟线引脚sbit DIO = P1^7; //实时时钟数据线引脚sbit CE = P1^5; //实时时钟复位线引脚sbit ACC0 = ACC^0;sbit ACC7 = ACC^7;char sec,min,hour,day,mon,week,year;char *tab[7]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat",};void write_1302(uchar add,uchar dat){uchar i;ACC=add;CE=0;SCLK=0;CE=1;for(i=0;i<8;i++){DIO=ACC0;SCLK=1;SCLK=0;ACC>>=1;}ACC=dat;for(i=0;i<8;i++){DIO=ACC0;SCLK=1;SCLK=0;ACC>>=1;}CE=0;}uchar read_1302(uchar add){uchar i;ACC=add;CE=0;SCLK=0;CE=1;for(i=8;i>0;i--) // 为什么不能for(i=0;i<8;i++) 又为什么用我写的函数不能改时间!!!!!!!!!!!!{DIO=ACC0;SCLK=1;ACC>>=1;SCLK=0;}for(i=8;i>0;i--){ ACC>>=1;ACC7=DIO;SCLK=1;SCLK=0;}return(ACC);CE=0;}void inputbyte(uchar d) //实时时钟写入一字节(内部函数){uchar i;ACC=d;for(i=8;i>0;i--){DIO=ACC0; //相当于汇编中的RRCSCLK=1;SCLK=0;ACC>>=1;}}uchar outputbyte() //实时时钟读取一字节(内部函数){uchar i;for(i=8; i>0; i--){ACC=ACC>>1; //相当于汇编中的RRCACC7=DIO;SCLK=1;SCLK=0;}return(ACC);}void write_1302(uchar add,uchar dat) //ucAddr: DS1302地址, ucData: 要写的数据{CE=0;SCLK=0;CE=1;inputbyte(add); // 地址,命令inputbyte(dat); // 写1Byte数据CE=0;}uchar read_1302(uchar add) //读取DS1302某地址的数据{uchar dat;CE=0;SCLK=0;CE=1;inputbyte(add); // 地址,命令dat=outputbyte(); // 读1Byte数据CE=0;return(dat);}void setprotect(bit flag){if(flag)write_1302(0x8e,0x80);elsewrite_1302(0x8e,0x00);}void gettime_1302(){sec=read_1302(0x81);min=read_1302(0x83);hour=read_1302(0x85);day=read_1302(0x87);mon=read_1302(0x89);week=read_1302(0x8b);year=read_1302(0x8d);}void stop_time(bit flag) // 是否将时钟停止{unsigned char dat;dat=read_1302(0x81);setprotect(0);if(flag)write_1302(0x80, dat|0x80);elsewrite_1302(0x80, dat&0x7F);}void init_1302(){uchar second=read_1302(0x81);if(second&0x80)write_1302(0x80,0);}/****************************************************************************** **void BurstWrite1302(unsigned char *pWClock) //往DS1302写入时钟数据(多字节方式) {unsigned char i;Write1302(0x8e,0x00); // 控制命令,WP=0,写操作?DS1302_RST = 0;DS1302_CLK = 0;DS1302_RST = 1;DS1302InputByte(0xbe); // 0xbe:时钟多字节写命令for (i = 8; i>0; i--) //8Byte = 7Byte 时钟数据+ 1Byte 控制{DS1302InputByte(*pWClock); // 写1Byte数据pWClock++;}DS1302_CLK = 1;DS1302_RST = 0;}void BurstRead1302(unsigned char *pRClock) //读取DS1302时钟数据(时钟多字节方式) {unsigned char i;DS1302_RST = 0;DS1302_CLK = 0;DS1302_RST = 1;DS1302InputByte(0xbf); // 0xbf:时钟多字节读命令for (i=8; i>0; i--){*pRClock = DS1302OutputByte(); // 读1Byte数据pRClock++;}DS1302_CLK = 1;DS1302_RST = 0;}******************************************************************************* */#endif#include "1602.h"#include "DS1302.h"sbit set=P3^2;sbit jia1=P3^0;sbit jian1=P3^1;uchar bcdtoasc(uchar cha){return ((cha/16)*10+(cha%16));}uchar asctobcd(uchar cha){return ((cha/10)*16+(cha%10));}void disp_week(){ switch(week){case 1:{write_lcd(0xcd,tab[0]); break;}case 2:{write_lcd(0xcd,tab[1]); break;}case 3:{write_lcd(0xcd,tab[2]); break;}case 4:{write_lcd(0xcd,tab[3]); break;}case 5:{write_lcd(0xcd,tab[4]); break;}case 6:{write_lcd(0xcd,tab[5]); break;}case 7:{write_lcd(0xcd,tab[6]); break;}}}void disp_time(){write_com(0x87);write_bcd(year);write_com(0x8a);write_bcd(mon);write_com(0x8d);write_bcd(day);write_com(0xc5);write_bcd(hour);write_com(0xc8);write_bcd(min);write_com(0xcb);write_bcd(sec);disp_week();}void keyscan(){jia1=1;jian1=1;stop_time(1);if(set==0){delay(10);if(set==0) {delay(200); slect++;}if(slect==8) {slect=0; stop_time(0);write_com(0x0c);} }if(slect){switch(slect){ case 1:{write_com(0xcb);write_com(0x0d);if(jia1==0){delay(10);if(jia1==0){delay(200);sec=read_1302(0x81);sec=sec&0x7f;sec=bcdtoasc(sec);sec+=1;if(sec==60)sec=0;sec=asctobcd(sec);write_1302(0x80,sec);write_com(0x0c);write_bcd(sec);}}if(jian1==0){delay(10);if(jian1==0){ delay(200);sec=read_1302(0x81);sec=sec&0x7f;sec=bcdtoasc(sec);sec-=1;if(sec<0)sec=59;sec=asctobcd(sec);write_1302(0x80,sec);write_com(0x0c);write_bcd(sec);}}break;}case 2:{write_com(0xc8);write_com(0x0d);if(jia1==0){delay(10);if(jia1==0){delay(200);min=read_1302(0x83);min=bcdtoasc(min);min+=1;if(min==60)min=0;min=asctobcd(min);write_1302(0x82,min);write_com(0x0c);write_bcd(min);}}if(jian1==0){delay(10);if(jian1==0){ delay(200);min=read_1302(0x83);min=bcdtoasc(min);min-=1;if(min<0)min=59;min=asctobcd(min);write_1302(0x82,min);write_com(0x0c);write_bcd(min);}}break;}case 3:{write_com(0xc5);write_com(0x0d);if(jia1==0){delay(10);if(jia1==0){delay(200);hour=read_1302(0x85);hour=bcdtoasc(hour);hour+=1;if(hour==24)hour=0;hour=asctobcd(hour);write_1302(0x84,hour);write_com(0x0c);write_bcd(hour);}}if(jian1==0){delay(10);if(jian1==0){ delay(200);hour=read_1302(0x85);hour=bcdtoasc(hour);hour-=1;if(hour<0)hour=23;hour=asctobcd(hour);write_1302(0x84,hour);write_com(0x0c);write_bcd(hour);}}break;}case 4:{write_com(0x8d);write_com(0x0d);if(jia1==0){delay(10);if(jia1==0){delay(200);mon=read_1302(0x89);year=read_1302(0x8d);day=read_1302(0x87);day=bcdtoasc(day);day+=1;year=bcdtoasc(year);if(year%4==0){if(mon==2){if(day==29)day=1;}else if(day==30)day=1;}else{ switch(mon){case 1:{if(day==32)day=1;break;}case 2:{if(day==30)day=1;break;}case 3:{if(day==32)day=1;break;}case 4:{if(day==31)day=1;break;}case 5:{if(day==32)day=1;break;}case 6:{if(day==31)day=1;break;}case 7:{if(day==32)day=1;break;}case 8:{if(day==32)day=1;break;}case 9:{if(day==31)day=1;break;}case 0x10:{if(day==32)day=1;break;}case 0x11:{if(day==31)day=1;break;}case 0x12:{if(day==32)day=1;break;}}if(mon==1|mon==3|mon==5|mon==7|mon==8|mon==0x10|mon==0x12) if(day==32)day=0; */if(mon==4|mon==6|mon==9|mon==0x11){if(day==31)day=1;}else if(day==32)day=1;}day=asctobcd(day);write_1302(0x86,day);write_com(0x0c);write_bcd(day);}}if(jian1==0){delay(10);if(jian1==0){ delay(200);day=read_1302(0x87);day=bcdtoasc(day);day-=1;if(day<1){ mon=read_1302(0x89);year=read_1302(0x8d);switch(mon){ case 0x01: {day=31; break;}case 0x02: {day=29; break;}case 3: {day=31; break;}case 4: {day=30; break;}case 5: {day=31; break;}case 6: {day=30; break;}case 7: {day=31; break;}case 8: {day=31; break;}case 9: {day=30; break;}case 0x10: {day=31; break;}case 0x11: {day=30; break;}case 0x12: {day=31; break;}}year=bcdtoasc(year);if(year%4==0)if(mon==2)day=28;}day=asctobcd(day);write_1302(0x86,day);write_com(0x0c);write_bcd(day);}}break;}case 5:{write_com(0x8a);write_com(0x0d);if(jia1==0){delay(10);if(jia1==0){delay(200);mon=read_1302(0x89);mon=bcdtoasc(mon);mon+=1;if(mon==13)mon=1;mon=asctobcd(mon);write_1302(0x88,mon);write_com(0x0c);write_bcd(mon);}}if(jian1==0){delay(10);if(jian1==0){ delay(200);mon=bcdtoasc(mon);mon-=1;if(mon<1)mon=12;mon=asctobcd(mon);write_1302(0x88,mon);write_com(0x0c);write_bcd(mon);}}break;}case 6:{write_com(0x87);write_com(0x0d);if(jia1==0){delay(10);if(jia1==0){delay(200);year=read_1302(0x8d);year=bcdtoasc(year);year+=1;if(year==100)year=0;year=asctobcd(year);write_1302(0x8c,year);write_com(0x0c);write_bcd(year);}}if(jian1==0){delay(10);if(jian1==0){ delay(200);year=read_1302(0x8d);year=bcdtoasc(year);year-=1;if(year<0)year=99;year=asctobcd(year);write_com(0x0c);write_bcd(year);}}break;}case 7:{write_com(0xcd);write_com(0x0d);if(jia1==0){delay(10);if(jia1==0){delay(200);week=read_1302(0x8b);week=bcdtoasc(week);week+=1;if(week==8)week=1;week=asctobcd(week);write_1302(0x8a,week);write_com(0x0c);disp_week();/* switch(week){case 1:{write_lcd(0xcd,tab[0]); break;}case 2:{write_lcd(0xcd,tab[1]); break;}case 3:{write_lcd(0xcd,tab[2]); break;}case 4:{write_lcd(0xcd,tab[3]); break;}case 5:{write_lcd(0xcd,tab[4]); break;}case 6:{write_lcd(0xcd,tab[5]); break;}case 7:{write_lcd(0xcd,tab[6]); break;}} */}}if(jian1==0){delay(10);if(jian1==0){ delay(200);week=read_1302(0x8b);week=bcdtoasc(week);week-=1;if(week<1)week=7;week=asctobcd(week);write_1302(0x8a,week);write_com(0x0c);disp_week();/* switch(week){case 1:{write_lcd(0xcd,tab[0]); break;}case 2:{write_lcd(0xcd,tab[1]); break;}case 3:{write_lcd(0xcd,tab[2]); break;}case 4:{write_lcd(0xcd,tab[3]); break;}case 5:{write_lcd(0xcd,tab[4]); break;}case 6:{write_lcd(0xcd,tab[5]); break;}case 7:{write_lcd(0xcd,tab[6]); break;} } */}}break; }}}}main(){init();init_1302();write_lcd(0x80,"DATE:20 - -");write_lcd(0x80+0x40,"TIME: : :");while(1){gettime_1302();set=1;if(set==0){delay(10);if(set==0){delay(200);slect++;}}while(slect)keyscan();disp_time();delay(30);}}。

DS1302时钟程序(完整版),液晶显示

DS1302时钟程序(完整版),液晶显示

#include<reg52.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned intuchar table0[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39}; //液晶显示数字0——9代码sbit SCLK=P1^0;sbit DATA=P1^1;sbit CE=P1^2;sbit RS=P2^0;sbit RW=P2^1;sbit EN=P2^2;sbit FB=P0^7;sbit start=P1^4;sbit stop=P1^5;uchar i;/*******************延时n微秒函数*****************/void delaynus(uchar n) //n us延时函数{// uchar i;for(i=n;i>0;i--);}/*******************写数据函数*****************/void write1302(uchar add,uchar dat){CE=0;SCLK=0;CE=1;for(i=0;i<8;i++) //写入地址{DATA=add&0x01;SCLK=1;SCLK=0;add>>=1;}for(i=0;i<8;i++) //写入数据{DATA=dat&0x01;SCLK=1;SCLK=0;dat>>=1;}SCLK=1;CE=0;}/*******************读数据函数*****************/uchar read1302(uchar add){uchar dat;CE=0;SCLK=0;CE=1;for(i=8;i>0;i--) //写入地址{DATA=add&0x01;SCLK=1;SCLK=0;add>>=1;}for(i=8;i>0;i--) //读出数据/********************为神马???**************************/{dat>>=1;if(DATA==1)dat=dat|0x80;SCLK=1;SCLK=0;}SCLK=1;CE=0;return dat;}/*******************DS1302初始化函数*****************/void init1302(){uchar flag;flag=read1302(0x81);if(flag&0x80){write1302(0x8e,0x00);write1302(0x80,0x00);write1302(0x82,(((1/10)<<4)|(1%10)));write1302(0x84,(((20/10)<<4)|(20%10)));write1302(0x86,(((19/10)<<4)|(19%10)));write1302(0x88,(((7/10)<<4)|(7%10)));write1302(0x8a,((2/10)<<4)|(2%10));write1302(0x8c,(((11/10)<<4)|(11%10)));write1302(0x90,0xa5); //充电。

DS1302时钟 LCD1206 显示 C程序

DS1302时钟 LCD1206 显示 C程序

STC12C5A08AD 单片机DS1302 时钟芯片LCD1602 液晶显示#include <stc12c5a08ad.h> //stc单片机专用的头文件#include <reg52.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned int#define ulong unsigned long#define dat P0 //定义LCD1602的数据口为P0 void delay(unsigned int xms ); //声明延时函数void delay2(unsigned int xms);void display(void); //显示程序void keyscan(void);sbit key0=P2^0;sbit key1=P2^1;sbit key2=P2^2;sbit key3=P2^3;sbit beep=P3^4;/****ds1302****/#define DS1302_SECOND_WRITE 0x80#define DS1302_MINUTE_WRITE 0x82#define DS1302_HOUR_WRITE 0x84#define DS1302_DAY_WRITE 0x86#define DS1302_MONTH_WRITE 0x88#define DS1302_WEEK_WRITE 0x8A#define DS1302_YEAR_WRITE 0x8Cvoid Set_MIN(uchar s);void Set_HR(uchar s);void Init_DS1302(void) ;void DS1302WriteByte(uchar dat);void DS1302Write(uchar cmd,uchar dat);uchar DS1302Read(uchar cmd);uchar DS1302Read_1(uchar cmd);uchar DS1302ReadByte();uchar DS1302ReadByte_1();sbit RST=P1^4;sbit SCLK=P3^6;sbit SDA=P3^7;/*** lcd1206***/sbit rs=P1^0; //定义RS口为P10sbit rw=P1^1; //定义RW口为P11sbit e=P1^2; //定义E口为P12void xianshi_sfm(uchar wei,uchar dat);void shj_1602(uchar a); //液晶写数据程序void int_1602(void); //液晶初始化void zhl_1602(uchar a); //液晶写指令程序uchar a,b,c,d;uchar code table0[7]={"time is"}; //定义LCD1602显示2行的字符uchar code table3[10]={"0123456789"};uchar code table4[1]={":"};/**************延时函数*****************/void delay(unsigned int xms) //延时函数,{unsigned int i,j ;for(i=xms;i>0;i--)for(j=110;j>0;j--);}/*****************LCD1602 显示程序******************************/void zhl_1602(uchar a) //写指令到LCM程序{// busy_1602(); //查询忙碌标志信号程序e=0;rs=0;rw=0;e=1;dat=a;delay(5);e=0;}void shj_1602(uchar a) //写数据到LCM程序{// busy_1602(); //查询忙碌标志信号程序e=0;rs=1;rw=0;e=1;dat=a;delay(5);e=0;}void int_1602(void) //启动LCM程序{zhl_1602(0x38); // 设置显示模式,数据接口位数zhl_1602(0x0c); // 设置显示开关,是否显示光标,是否闪动光标zhl_1602(0x06); // 设置光标移动方向左或右,设置所有文字是否移动}/*****************液晶LCD1602显示主程序程序***********/void display(void) //液晶显示程序{uchar i,ri,yue,nian; //定义计数值int_1602(); //初始化1602zhl_1602(0x80);delay(5); //写指令(11000000) 指定从第一行指针位置开始写for(i=0;i<7;i++) //发送数据第一行time is:{shj_1602(table0[i]);delay(5);}zhl_1602(0x80+10);delay(5); //for(i=0;i<1;i++) //发送数据第一行时间显示的“: ”{shj_1602(table4[i]);delay(5);}zhl_1602(0x80+13);delay(5); //for(i=0;i<1;i++) //发送数据第一行时间显示的“: ”{shj_1602(table4[i]);delay(5);}a=(DS1302Read(0x81)/16)*10+(DS1302Read(0x81)%16); //转换为十进制c=(DS1302Read(0x83)/16)*10+(DS1302Read(0x83)%16);d=(DS1302Read(0x85)/16)*10+(DS1302Read(0x85)%16);ri=(DS1302Read(0x87)/16)*10+(DS1302Read(0x87)%16);yue=(DS1302Read(0x89)/16)*10+(DS1302Read(0x89)%16);nian=(DS1302Read(0x8d)/16)*10+(DS1302Read(0x8d)%16);xianshi_sfm(8,d); // 时钟显示时delay(20);xianshi_sfm(11,c); // 时钟显示分delay(20);xianshi_sfm(14,a); // 时钟显示秒delay(20);xianshi_sfm(0X48,ri); // day 0X48 为换第二行写入显示年月日delay(20);xianshi_sfm(0X45,yue); // yuedelay(20);xianshi_sfm(0X42,nian); // niandelay(20);xianshi_sfm( 0x40,20); // 显示20 xx 年份的前缀}/*****时间显示子程序***/void xianshi_sfm(uchar wei,uchar dat){uchar shi,ge;shi=dat/10;ge=dat%10;zhl_1602(0x80+wei);//第一行显示+位选择delay(5);shj_1602(table3[shi]);delay(5);shj_1602(table3[ge]);delay(5);}/*************DS1302程序*************** /cmd: 要写入的控制字节dat: 读取的数据******uchar DS1302Read_1(uchar cmd)//十二小时制调用{uchar dat;RST=0; //////// 初始CE 线置为0SCLK=0; //////// 初始时钟线置为0RST=1; //////// 初始CE 置为 1 ,传输开始DS1302WriteByte(cmd); //////// 传输命令字,要读取的时间dat=DS1302ReadByte_1(); //////// 读取要得到的时间SCLK=1; //////// 时钟线拉高RST=0; //////// 读取结束,CE 置为0 ,结束数据的传输return dat; //////// 返回得到的时间/ / / / 日期}/********** 读操作************/uchar DS1302ReadByte_1() //十二小时制调用{uchar i,dat,dat1,dat2;delay(2);for(i=0;i<8;i++){dat>>=1; //////// 要返回的数据左移一位if(SDA==1) //////// 当数据线为高时,证明该位数据为1dat|=0x80; //////// 要传输数据的当前值置为1, 若不是则为0SCLK=1; // 拉高时钟线delay(5);SCLK=0; //////// 制造下降沿delay(5);}// RST=0; //////// 初始CE 线置为0dat1=dat-0x80; // -0x80 是设置12小时制后去掉”DS1302_HOUR_WRITE 0x84“设置的最高位1 以免影响取值错误否则时显示错误dat2=dat1/16; //数据进制转换dat1=dat1%16; //十六进制转十dat1=dat1+dat2*10;return (dat1); //////// 返回读取出的数据}/********** 读操作************/uchar DS1302Read(uchar cmd) //二四小时制调用{uchar dat;RST=0; //////// 初始CE 线置为0SCLK=0; //////// 初始时钟线置为0RST=1; //////// 初始CE 置为 1 ,传输开始DS1302WriteByte(cmd); //////// 传输命令字,要读取的时间dat=DS1302ReadByte(); //////// 读取要得到的时间SCLK=1; //////// 时钟线拉高RST=0; //////// 读取结束,CE 置为0 ,结束数据的传输return dat; //////// 返回得到的时间/ / / / 日期}/****写数据***/void DS1302Write(uchar cmd, uchar dat){RST=0; //////// 初始CE 线置为0SCLK=0; //////// 初始时钟线置为0RST=1; //////// 初始CE 置为1 ,传输开始DS1302WriteByte(cmd);DS1302WriteByte(dat); //////// 写入要修改的时SCLK=1; //////// 时钟线拉高RST=0; //////// 读取结束,CE 置为0 ,}/*******写操作*******/void DS1302WriteByte(uchar dat){uchar i;SCLK=0; //////// 初始时钟线置为0delay(5);for(i=0;i<8;i++) //////// 开始传输8 个字节的数据{SDA=dat&0x01; //////// 取最低位,注意DS130的数据和地址都是从最低位开始传输的delay(5);SCLK=1; //////// 时钟线拉高,制造上升沿,SDA 的数据被传输delay(5);SCLK=0; //////// 时钟线拉低,为下一个上升沿做准备dat>>=1; //////// 数据右移一位,准备传输下一位数据}// RST=0; //////// 初始CE 线置为0}/********** 读操作************/uchar DS1302ReadByte() //二四小时制调用{uchar i,dat;delay(2);for(i=0;i<8;i++){dat>>=1; //////// 要返回的数据左移一位if(SDA==1) //////// 当数据线为高时,证明该位数据为1dat|=0x80; //////// 要传输数据的当前值置为1, 若不是则为0SCLK=1; // 拉高时钟线delay(5);SCLK=0; //////// 制造下降沿delay(5);}RST=0; //////// 初始CE 线置为0return (dat); /}/*******DS1302初始化***********/void Init_DS1302(void){DS1302Write(0x8e,0x00); //////// 写保护关DS1302Write(DS1302_SECOND_WRITE,0x55); //////// 初始秒值为55DS1302Write(DS1302_MINUTE_WRITE,0x59); //////// 初始分钟值为59DS1302Write(0x84,0x23);////////24小时模式///若设置(0X84 0X92)初始为12小时模式,初始时间为12点,读程序时调用uchar DS1302Read_1(uchar cmd)DS1302Write(DS1302_DAY_WRITE,0x18); //年月日星期初值设置DS1302Write(DS1302_MONTH_WRITE,0x05);DS1302Write(DS1302_YEAR_WRITE,0x13);DS1302Write(DS1302_WEEK_WRITE,0x06);DS1302Write(0xc0,0xf0); //////// 初始化一次标示DS1302Write(0x8e,0x80); //开启写入保护}//主程序void main(){Init_DS1302();delay(5);while(1){display(); // 显示keyscan();}}/*****键控设置时间程序调整时,分的显示值可对时间校准***/void Set_MIN(uchar s) //1为分钟加,0为分钟减{unsigned char temp;DS1302Write(0x8E,0x00);//去除写保护temp=DS1302Read(0x83);if(s){temp+=1;if(temp>0x59)temp=0;if((temp&0x0f)>0x09) //if(temp%0x10>0x09) 当低四位大于9时temp=(temp+16)&0xf0; // temp=((temp+0x10) & 0xf0);高四位进1位低四位归零}else{if(temp>0) //temp-=1;else //TEMP 等于0 时;·temp=0x59;if((temp%0x10)>0x09) //减到低位为0后再减一次低位为1111,为15 取余运算后大于9 ,同时高位被低位借位减1,降了一个十位数temp=(temp&0xf0+0x09); //temp=((temp/0x10)*0x10 + 0x09) 则取高位值,低位置9,从而达到0至9循环}DS1302Write(0x82,temp);DS1302Write(0x8e,0x80);}void Set_HR(uchar s) //1为小时加,0为小时减{unsigned char temp;DS1302Write(0x8E,0x00);//去除写保护temp=DS1302Read(0x85);//小时数保存在低5位// temp<<=3;// temp>>=3;if(s){temp+=1;if(temp==0x0a) //加到0000 1010 时分位不需要10 手动加一操作时是按照2进制加一,芯片自动运行时按照BCD码进位的即低四位到9后加1 ,进位至高四位加1temp=0x10; //进一至十位BCD码if(temp==0x1a)temp=0x20;if(temp==0x24)temp=0;}else{ temp-=1;if(temp==0xff) //当为00000000 再减一位变成0XFFtemp=0x23; //改变0XFF 为自己需要的0X23 .3.2.1.0.23.22............... 循环调整if(temp==0x1f) //当20 (0010 0000)再减1时其实际值是0X1F(0001 1111 )temp=temp&0xf0+0x09; //舍弃低四位的值将其个位置9if(temp==0x0f)temp=0x09;}DS1302Write(0x84,temp);DS1302Write(0x8e,0x80); //写保护启动}void keyscan(){if(key0==0){delay(2);if(key0==0){ //分减更改Set_MIN(0);while(!key0);}}if(key1==0){delay(2);if(key1==0){ //分加更改Set_MIN(1);while(!key1);}}if(key2==0){delay(2);if(key2==0)Set_HR(0); //时减更改while(!key2);}if(key3==0){delay(2);if(key3==0)Set_HR(1); //时加更改while(!key3);}}。

DS1302时钟芯片完整C语言应用程序_可直接调用

DS1302时钟芯片完整C语言应用程序_可直接调用

}
for(i=0;i<8;i++)
{
DS1302_CLK=0;
DS1302_DATA=DDATA&0X01;
DS1302_CLK=1;
DDATA=DDATA>>1; //传送数据。
}
DS1302_CLK=0;
DS1302_RST=0;
//使能端关闭。
}
/************************************************************/
uchar DS1302_Clock[8]={0x01,0x01,0x00,0x06,0x09,0x02,0x11,0}; //时钟缓存。秒、分、时、
日、月、周、年、控制寄存器。
void DS1302_Write(uchar CDATA,uchar DDATA); //写数据。
uchar DS1302_Read(uchar CDATA); //读数据。
#endif
/********DS1302_WriteClock()***********************************
函数名 :DS1302_WriteClock() 突发方式,写入所有时钟数据。
入口参数:无
出口参数:无
**************************************************************/
void DS1302_Write(uchar CDATA,uchar DDATA)
{
uchar i;
DS1302_RST=1;
//使能端有效,开始传送数据。
for(i=0;i<8;i++)

DS1302显示时钟程序

DS1302显示时钟程序

#include<reg52.h>#include<intrins.h>#define uint unsigned int#define uchar unsigned charsbit k1=P1^0; //开关的位置sbit k2=P1^1;sbit k3=P1^2;sbit k4=P1^3;sbit clk=P3^6; //时钟线sbit en=P3^5; //使能端sbit io=P3^4; //DS1302的IO口sbit lcden=P2^7; //液晶使能端sbit lcdrd=P2^6; //数据命令端sbit lcdwr=P2^5; //读写选择端sbit beep=P2^4; //蜂鸣器位置bit flag; //按键标志位uchar code t[]="LCD LOCK"; //第一行显示字符uchar code b[]="****"; //第二行显示字符uchar c[8] ={0x00}; //定义显示缓冲区uchar d[7] ={0,0,0x12,0,0,0,0}; //DS1302时间缓冲区,存放秒、分、时、日、月、uchar e[2]={0}; //用来存放分钟小时的中间值void delay(uint x) //延时函数{ uint i,j;for(i=0;i<x;i++)for(j=0;j<115;j++); //延时X*MS}void write_com(uchar com) //命令函数{ lcdrd=0; //选择命令端P0=com; //要写的命令送到P0口delay(5);lcden=1; //开启使能端delay(5);lcden=0; //关闭使能端}void write_data(uchar dat) //数据函数{ lcdrd=1; //数据选择端P0=dat;delay(5);lcden=1; //开使能delay(5);lcden=0;}bit busy() //忙碌检查函数{ bit result;lcdrd=0;lcdwr=1;lcden=1;_nop_(); //延时几微秒_nop_();_nop_();_nop_();result=(bit)(P0&0x80);lcden=0;return result;}void lcdclr() //LCD清屏函数{ write_com(0x01); //清零显示,数据指针清零delay(5);}void init() //初始化函数{ delay(15);write_com(0x38); //16*2显示,5*7点阵,8位数据delay(15);write_com(0x38);write_com(0x06); //写一个字符地址指针加1 delay(5);write_com(0x0c); //设置显示,不显示光标delay(5);write_com(0x01); //显示清零,数据指针清零}void write_byte(uchar date) //写一个字节函数{ uchar i;for(i=0;i<8;i++){ clk=0; //低电平改变数据if(date&0x01)io=1;elseio=0;clk=1; //高电平写入1302_nop_();date=date>>1;}}uchar read_byte() //读一个字节函数{uchar i,temp=0;io=1;for(i=0;i<7;i++){clk=0;if(io==1)temp=temp|0x80;elsetemp=temp&0x7f;clk=1; //产生下跳沿temp=temp>>1;}return temp;}void write1302(uchar com,uchar dat) //写1302函数在某个地址写数据{ clk=0;en=1;write_byte(com);write_byte(dat);clk=0;en=0;}uchar read1302(uchar add) //读1302函数,从地址读数据{ uchar d;clk=0;en=1;write_byte(add); //先写地址d=read_byte(); //后读数据clk=0;en=0;return d;}void set1302(uchar add,uchar *p,uchar n) //时间初始化{ write1302(0x80,0x00); //写控制,允许写操作for(;n>0;n--){ write1302(add,*p);p++;add=add+2;}write1302(0x8e,0x80); //写保护,不允许写操作}void get1302(uchar add,uchar *p,uchar n) //读取当前数据{ for(;n>0;n--){ *p=read1302(add);p++;add=add+2;}}void init1302() //初始化1302函数{ en=0;clk=0;write1302(0x80,0x00); //写秒寄存器write1302(0x90,0xab); //写充电器write1302(0x8e,0x80); //写保护,禁止写}void BEEP() //蜂鸣器函数{ beep=0; //响蜂鸣器delay(100); //响0.1sbeep=1;delay(100);}void lcdcon(uchar m1,m2,m3) //将数据转化成适合LCD显示的数据{ c[0]=m1/10+0x30; //小时十位数据c[1]=m1%10+0x30; //小时个位数据c[2]=m2/10+0x30; //分钟十位数据c[3]=m2%10+0x30; //分钟个位数据c[4]=m3/10+0x30; //秒十位c[5]=m3%10+0x30; //秒个位}void lcddis() //LCD显示函数{ write_com(0x44|0x80); //第二行第四列write_data(c[0]); //小时十位write_data(c[1]); //小时个位write_data(':'); //显示:write_data(c[2]); //显示分钟十位write_data(c[3]); //显示分钟个位write_data(':');write_data(c[4]); //显示秒十位write_data(c[5]); //显示秒个位}void keyscan() //按键函数{ uchar fen,shi; //定义两个16位分钟和小时write1302(0x8e,0x00); //1302写保护,允许写write1302(0x80,0x80); //时钟停止运行if(k2==0) //按键2被按下{ d elay(10); //去抖动if(k2==0) //确认被按下{ while(!k2); //等待按键释放BEEP(); //蜂鸣器函数d[2]=d[2]+1; //小时加1if(d[2]==24) //满24清零d[2]=0;shi=d[2]/10*16+d[2]%10; //将小时转化成16进制write1302(0x84,shi); //调整后写入1302}}if(k3==0) //按键3被按下{ delay(10); //抖动if(k3==0) //确认被按下{ while(!k3); //等待按键放开BEEP(); //蜂鸣器函数d[1]=d[1]+1; //分钟加1if(d[1]==60) //满60清零d[1]=0;fen=d[1]/10*16+d[1]%10; //将分钟转化为16进制write1302(0x82,fen); //调整后,写入1302}}if(k4==0) //按键4被按下{ d elay(10); //去抖动if(k4==0) //确认被按下{ while(!k4); //等待按键释放BEEP(); //蜂鸣器函数write1302(0x80,0x00); //调整后,启动时钟运行write1302(0x8e,0x80); //写保护,禁止写flag=0; //按键1标志位清零}}}void gettime() //读取当前时间,转化为10进制{ uchar miao,fen,shi;write1302(0x8e,0x00); //控制命令,0表示允许写write1302(0x90,0xab); //电流控制miao=read1302(0x81); //读取秒fen=read1302(0x83); //读取分shi=read1302(0x85); //读取小时d[0]=miao/16*10+miao%16; //转化为10进制d[1]=fen/16*10+fen%16; //转化为10进制d[2]=shi/16*10+shi%16; //转换为10进制}void main() //主函数{ uchar i;P0=0xff;P2=0xff;init1302(); //1302初始化函数lcdclr(); //1302清屏函数write_com(0x00|0x80); //第一行第0列i=0;while(t[i]!=0){ write_data(t[i]); //第一个字符显示i++;}write_com(0x40|0x80); //第二行显示第0列i=0;while(b[i]!=0);{ write_data(b[i]);i++;}init1302();while(1){ gettime();if(k1==0) //按键1按下{ delay(10); //去抖动if(k1==0) //确认按下{ while(!k1); //等待按键释放BEEP(); //蜂鸣器函数flag=1; //按键1标志位置位,进行时钟调整}}if(flag==1) //如为1,则进行调整keyscan();lcdcon(d[2],d[1],d[0]); //将1302的数据送到函数转换lcddis(); //调整LCD显示,显示小时,分钟,秒}}。

DS1302原理及程序说明

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所示。

ds1302操作说明

ds1302操作说明

一、 电路原理图说明
说明:1. 晶振为32.768KHz晶振,晶振参数如下表所示:
二、 寄存器说明
注:1. 上表为:日历时钟寄存器地址和数据位功能说明;
1、单字节读写时序
注:在单字节或多字节读操作时,读出的第一个bit位,必须是在命令发送完后第一个下降沿处取得的,否则,读出的数据会出错。

(如上图所示)
2、多字节读写程序
对于多字节写,需要特别注意的是,在发送0xbe命令并连续完成7字节的时钟数据写入后,必须在rst信号有效的情况下,再追加一个字节的写保护使能字节0x80;否则,无法完成写入操作。

当然,在多字节写之前,也必须先发一条写保护使能关闭命令。

(如上图的N,应该为8,而第8个字节写入的应该是0x80这个值)
四、 程序说明。

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实时时钟C程序

ds1302实时时钟C程序

ds1302实时时钟C程序*//*会员经典作品已经测试成功/#include < reg52.h>#include <intrins.h>#define uchar unsigned charsbit T_CLK = P3^4; /*实时时钟时钟线引脚*/sbit T_IO = P3^3; /*实时时钟数据线引脚*/sbit T_RST = P3^2; /*实时时钟复位线引脚*///sbit OE=P3^6;sbit ACC0=ACC^0;sbit ACC7=ACC^7;uchar time[8]=" : : ";uchar min,hou,day,mon,yea;void Init1302(void);// 初始化DS1302void v_W1302(uchar ucAddr, uchar ucDa);// 往DS1302写入数据uchar uc_R1302(uchar ucAddr);// 读取DS1302某地址的数据void v_BurstW1302T(uchar *pSecDa);// 往DS1302写入时钟数据(多字节方式) void v_BurstR1302T(uchar *pSecDa);// 读取DS1302时钟数据void v_BurstW1302R(uchar *pReDa);// 往DS1302寄存器数写入数据(多字节方式) void v_BurstR1302R(uchar *pReDa);// 读取DS1302寄存器数据void v_Set1302(uchar *pSecDa);// 设置初始时间void v_Get1302(uchar ucCurtime[]);//读取DS1302当前时间void donetime(void); 时间处理void bcd_int(uchar i);void bcdtoInt(void);void SetTime(void);//时间设置/********************************************************************** 名称: v_RTInputByte* 说明:* 功能: 往DS1302写入1Byte数据* 调用:* 输入: ucDa 写入的数据* 返回值: 无***********************************************************************/ void v_WTInputByte(uchar ucDa){uchar i;//OE=0;ACC= ucDa;for(i=8; i>0; i--){T_IO = ACC0; //*相当于汇编中的RRCT_CLK = 1;T_CLK = 0;ACC =ACC>> 1;}// OE=1;}/********************************************************************** 名称: uchar uc_RTOutputByte* 说明:* 功能: 从DS1302读取1Byte数据* 调用:* 输入:* 返回值: ACC***********************************************************************/ uchar uc_RTOutputByte(void){uchar i;//OE=0;for(i=8; i>0; i--){ACC = ACC>>1; //*相当于汇编中的RRCACC7 = T_IO;T_CLK = 1;T_CLK = 0;}//OE=1;return(ACC);}/********************************************************************** 名称: v_W1302* 说明: 先写地址,后写命令/数据* 功能: 往DS1302写入数据* 调用: v_RTInputByte()* 输入: ucAddr: DS1302地址, ucDa: 要写的数据* 返回值: 无***********************************************************************/ void v_W1302(uchar ucAddr, uchar ucDa){//OE=0;T_RST = 0;T_CLK = 0;T_RST = 1;v_WTInputByte(ucAddr); /* 地址,命令*/v_WTInputByte(ucDa); /* 写1Byte数据*/T_CLK = 1;T_RST =0;//OE=1;}/********************************************************************** 名称: uc_R1302* 说明: 先写地址,后读命令/数据* 功能: 读取DS1302某地址的数据* 调用: v_RTInputByte() , uc_RTOutputByte()* 输入: ucAddr: DS1302地址* 返回值: ucDa :读取的数据***********************************************************************/ uchar uc_R1302(uchar ucAddr){uchar ucDa;//OE=0;T_RST = 0;T_CLK = 0;T_RST = 1;v_WTInputByte(ucAddr); /* 地址,命令*/ucDa = uc_RTOutputByte(); /* 读1Byte数据*/T_CLK = 1;T_RST =0;// OE=1;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_WTInputByte(0xbe); //* 0xbe:时钟多字节写命令for (i=8;i>0;i--) //*8Byte = 7Byte 时钟数据+ 1Byte 控制{v_WTInputByte(*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_WTInputByte(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_WTInputByte(0xfe); //* 0xbe:时钟多字节写命令for (i=31;i>0;i--) //*31Byte 寄存器数据{v_WTInputByte(*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_WTInputByte(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: 初始时间地址。

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

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寄存器,此方式下可一次性读写所有的RA
M的31个字节,命令控制字为FEH(写)、FFH(读)。

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

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

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

在DS1302的时钟日历或RAM进行数据传送时,DS13 02必须首先发送命令字节。

若进行单字节传送,8位命令字节传送结束之后,在下2个SCLK周期的上升沿输入数据字节,或在下8个SCLK周期的下降沿输出数据字节。

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

要特别说明的是备用电源B1,可以用电池或者超级电容器(0.1F以上)。

虽然DS1302在主电源掉电后的耗电很小,但是,如果要长时间保证时钟正常,最好选用小型充电电池。

可以用老式电脑主板上的充电电池。

如果断电时间较短(几小时或几天)时,就可以用漏电较小的普通电解电容器代替。

100 μF就可以保证1小时的正常走时。

DS1302在第一次加电后,必须进行初始化操作。

初始化后就可以按正常方法
调整时间。

相关文档
最新文档