您好,欢迎访问三七文档
当前位置:首页 > 行业资料 > 酒店餐饮 > DS1302时钟C语言编程完整实例
1DS1302简介:DS1302是美国DALLAS公司推出的一种高性能、低功耗的实时时钟芯片,附加31字节静态RAM,采用SPI三线接口与CPU进行同步通信,并可采用突发方式一次传送多个字节的时钟信号和RAM数据。实时时钟可提供秒、分、时、日、星期、月和年,一个月小与31天时可以自动调整,且具有闰年补偿功能。工作电压宽达2.5~5.5V。采用双电源供电(主电源和备用电源),可设置备用电源充电方式,提供了对后背电源进行涓细电流充电的能力。DS1302的外部引脚分配如图1所示及内部结构如图2所示。DS1302用于数据记录,特别是对某些具有特殊意义的数据点的记录上,能实现数据与出现该数据的时间同时记录,因此广泛应用于测量系统中。图1DS1302的外部引脚分配图2DS1302的内部结构各引脚的功能为:Vcc1:主电源;Vcc2:备份电源。当Vcc2Vcc1+0.2V时,由Vcc2向DS1302供电,当Vcc2Vcc1时,由Vcc1向DS1302供电。SCLK:串行时钟,输入,控制数据的输入与输出;I/O:三线接口时的双向数据线;CE:输入信号,在读、写数据期间,必须为高。该引脚有两个功能:第一,CE开始控制字访问移位寄存器的控制逻辑;其次,CE提供结束单字节或多字节数据传输的方法。DS1302有下列几组寄存器:①DS1302有关日历、时间的寄存器共有12个,其中有7个寄存器(读时81h~8Dh,写时80h~8Ch),存放的数据格式为BCD码形式,如图3所示。图3DS1302有关日历、时间的寄存器小时寄存器(85h、84h)的位7用于定义DS1302是运行于12小时模式还是24小时模式。当为高时,选择12小时模式。在12小时模式时,位5是,当为1时,表示PM。在24小时模式时,位5是第二个10小时位。秒寄存器(81h、80h)的位7定义为时钟暂停标志(CH)。当该位置为1时,时钟振荡器停止,DS1302处于低功耗状态;当该位置为0时,时钟开始运行。控制寄存器(8Fh、8Eh)的位7是写保护位(WP),其它7位均置为0。在任何的对时钟和RAM的写操作之前,WP位必须为0。当WP位为1时,写保护位防止对任一寄存器的写操作。②DS1302有关RAM的地址DS1302中附加31字节静态RAM的地址如图4所示。图4③DS1302的工作模式寄存器所谓突发模式是指一次传送多个字节的时钟信号和RAM数据。突发模式寄存器如图5所示。图5④此外,DS1302还有充电寄存器等。2读写时序说明DS1302是SPI总线驱动方式。它不仅要向寄存器写入控制字,还需要读取相应寄存器的数据。要想与DS1302通信,首先要先了解DS1302的控制字。DS1302的控制字如图6。图6控制字(即地址及命令字节)控制字的最高有效位(位7)必须是逻辑1,如果它为0,则不能把数据写入到DS1302中。位6:如果为0,则表示存取日历时钟数据,为1表示存取RAM数据;位5至位1(A4~A0):指示操作单元的地址;位0(最低有效位):如为0,表示要进行写操作,为1表示进行读操作。控制字总是从最低位开始输出。在控制字指令输入后的下一个SCLK时钟的上升沿时,数据被写入DS1302,数据输入从最低位(0位)开始。同样,在紧跟8位的控制字指令后的下一个SCLK脉冲的下降沿,读出DS1302的数据,读出的数据也是从最低位到最高位。数据读写时序如图7。图7数据读写时序具体操作见驱动程序。3电路原理图:电路原理图如图8,DS1302与单片机的连接也仅需要3条线:CE引脚、SCLK串行时钟引脚、I/O串行数据引脚,Vcc2为备用电源,外接32.768kHz晶振,为芯片提供计时脉冲。图8以上部分是我拷贝别人的,在此我要感谢他,后面的部分全部是我自己写的,经过调试,系统运行稳定。本来是不准备拷贝的,但考虑读者可能会读不懂程序,所以我才将核心器件的通信协议拿来给大家看看,当初老师叫我随便用C语言编写个单片机程序,于是我就找了个DS1302时钟的程序,写的有点长,可能是我第一次经验不够吧。#includereg51.h#includestdio.h#defineucharunsignedchar#defineuintunsignedintucharcodetable[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x7f};//0123456789.sbitsclk=P3^6;sbitdata_io=P3^7;sbitrst=P3^5;sbitk1=P1^4;//mod功能选择键sbitk2=P1^5;//--(待机时按此键显示当前日期)sbitk3=P1^6;//++(待机时,按此键显示闹钟时间及状态,进入闹钟设定时此键是闹铃开关键)sbitk4=P1^7;//退出设定sbitdidi=P3^0;//闹钟铃音ucharmod;ucharkaiguan;bitkeys(void);//函数申明voidshow(x,y,z);//函数申明voidalarmshow(a_shi,a_fen);//函数申明voiddelay(uintms)//1ms延时子程序{uinti,j;for(i=ms;i0;i--)for(j=244;j0;j--);}voidalarmdisplay(ucharshu,ucharwei)//闹钟显示子程序{P2=0x00;P0=table[shu];P2=(1wei);delay(1);P2=0x00;if(kaiguan%2)//显示ON12-23,闹钟时间显示格式{P0=0xc0;P2=0x01;delay(1);P2=0x00;P0=0xc8;P2=0x02;delay(1);P2=0x00;P0=0xf7;P0=0x08;delay(1);P2=0x00;}else//显示OFF12-23,闹钟时间显示格式{P2=0x00;P0=0xc0;P2=0x01;delay(1);P2=0x00;P0=0x8e;P2=0x02;delay(1);P2=0x00;P0=0x8e;P2=0x04;delay(1);P2=0x00;}}voiddisplay(ucharshu,ucharwei)//显示函数{P2=0x00;P0=table[shu];P2=(1wei);delay(1);P2=0x00;//显示该位数字P0=0xbf;P2=0x04;delay(1);//显示横杠P2=0x00;P0=0xbf;P2=0x20;delay(1);//显示横杠P2=0x00;}voidweidisplay(void)//调时间时显示调整哪一个位{ucharwei;P2=0x00;P0=0x7f;if(mod==1||mod==4||mod==7)wei=3;if(mod==2||mod==5)wei=0;if(mod==3||mod==6)wei=6;P2=(3wei);delay(3);P2=0x00;}voidalarm()//闹钟铃音子程序{uinti;for(i=59;i0;i--){didi=1;delay(1);didi=0;delay(1);if(k1==0){delay(5);if(k1==0){while(~k1);break;}}}}voidwrite(ucharaddr,ucharshu)//写两个字节{uchartemp,t;rst=0;sclk=0;rst=1;temp=addr;for(t=0;t8;t++){if(temp&0x01)data_io=1;elsedata_io=0;sclk=1;delay(1);sclk=0;temp=1;}temp=shu;for(t=0;t8;t++){if(temp&0x01)data_io=1;elsedata_io=0;sclk=1;delay(1);sclk=0;temp=1;}rst=0;}ucharread(ucharaddr)//读一个字节{uchartemp,t;rst=0;sclk=0;rst=1;temp=addr;for(t=0;t8;t++){if(temp&0x01)data_io=1;elsedata_io=0;sclk=1;sclk=0;temp=1;}temp=0;for(t=0;t7;t++){if(data_io==1)temp=temp|0x80;elsetemp=temp&0x7f;sclk=1;sclk=0;temp=1;}returntemp;}//************************************************8888//************************************************8888voidmain()//主函数{bitflag;ucharshi,fen,miao,nian,yue,ri,a_shi,a_fen;//当前时间10:06:5310-12-20write(0x80,0x53);write(0x82,0x06);//秒寄存器(初始化年月日,时分秒,闹铃)write(0x84,0x10);//时寄存器write(0x86,0x20);//日寄存器write(0x88,0x12);//月寄存器write(0x8c,0x10);//年寄存器a_shi=0x07;//初始化闹钟时间7:30a_fen=0x30;while(1){shi=read(0x85);//读小时fen=read(0x83);//读分钟miao=read(0x81);//读秒钟if(kaiguan%2)//判断闹钟{if(a_shi==shi&&a_fen==fen)alarm();}if(k3==0&&mod==0)//待机情况下按k3显示闹铃时间{delay(5);if(k3==0&&mod==0){while(~k3)alarmshow(a_shi,a_fen);}}if(k2==0&&mod==0)//待机情况下按k2显示日期{delay(5);if(k2==0&&mod==0){while(~k2)show(nian,yue,ri);}}flag=keys();//按键标识位,有按键按下时flag=1;if(1)//程序出现个小错误,原本这里是写flag,但没有办法,只能写1了,感兴趣的话自己分析{if(mod==1){if(k4==0)//如果k4=0,则退出设定{delay(5);if(k4==0){while(~k4);mod=0;}}if(k2==0){delay(5);if(k2==0){while(~k2);fen=(fen4)*10+(fen&0x0f);fen++;if(fen==60)fen=0;fen=((fen/10)4)+((fen%10)&0x0f);write(0x82,fen);}}}if(mod==2){if(k4==0)//如果k4=0,则退出设定{delay(5);if(k4==0){while(~k4);mod=0;}}if(k2==0){delay(5);if(k2==0){while(~k2);shi=(shi4)*10+(shi&0x0f);shi++;if(shi==24)shi=0;shi=((shi/10)4)+((shi%10)&0x0f);write(0x84,shi);}}}if(mod==1){if(k4==0)//如果k4=0,则退出设定{delay(5);if(k4==0){while(~k4);mod=0;}}if(k3==0){delay(5);if(k3==0){while(~k3);fen=(fen4)*10+(fen&0x0f);if(fen==0)fen=60;fen--;fen=((fen/10)4)+((fen%10)&0x0f);write(0x82,fen);}}}if(mod==2){if(k
本文标题:DS1302时钟C语言编程完整实例
链接地址:https://www.777doc.com/doc-3563332 .html