从前,利用51单片机自带的时钟做的电子钟时差太大,不停地在程序里去写时间矫正程序,之后发现了DS1302这个芯片,那时候是新手,不太了解,所以一直搁置,现在有了时间,把这个芯片详细研究了一下,之后发现开发板上程序只能读,不能写,专门挑了半天来研究这个芯片的驱动,果然功夫不负有心人,终于把这个做了出来,成品如下
原理图:
现在把代码发一下
- /***temp.h***/
- #ifndef _temp_h_
- #define _temp_h_
- #include"reg52.h"
- #include"intrins.h"
- #define uint unsigned int
- #define uchar unsigned char
-
- extern uchar shuzu[7];
- sbit sclk=P3^2;
- sbit dsio=P3^3;
- sbit dir=P3^4;
- sbit dq=P3^5;
- sbit sb1=P1^0;
- sbit sb2=P1^1;
- sbit sb3=P1^2;
- //void delay(uint z);
- void dee(uint z);
- void csh1302();
- void dq1302();
- void xzl1302(uchar add,uchar dar);
- uchar kzzsc(uchar ram,uchar temp,uchar wd);
- #endif
复制代码- /***main.c***/
- #include"temp.h"
- uchar dtt,drr;
- uchar smgshuzu[4];
- uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
- uint et0time=(65535-50000);
- void zhdq1302(uchar i)
- {
- uchar ge,shi,miao;
- if(i==0){dq1302();}
- smgshuzu[0]=table[shuzu[2]/16];
- smgshuzu[1]=dtt+table[shuzu[2]%16];
- smgshuzu[2]=table[shuzu[1]/16];
- smgshuzu[3]=table[shuzu[1]%16];
- shi=shuzu[0]/16;
- ge=shuzu[0]%16;
- miao=ge+shi*10;
- if(miao!=drr)
- {
- drr=miao;
- if(dtt==0x00){dtt=0x80;}
- else {dtt=0x00;}
- }
- }
- void smgxs()
- {
- uchar i;
- P0=0xfe;
- for(i=0;i<4;i++)
- {
- P2=smgshuzu[i];
- dee(100);
- P2=0x00;
- P0=_crol_(P0,1);
- }
- }
- void szcsh()
- {
- TCON=1;
- TH0=et0time/256;
- TL0=et0time%256;
- TR0=1;
- EA=1;
- ET0=1;
- }
- void main()
- {
- uchar i,k;
- uint l;
- csh1302();
- szcsh();
- while(1)
- {
- zhdq1302(0);
- if(sb1==0)
- {
- dee(100);
- if(sb1==0)
- {
- while(sb1==0){l++,dee(110);if(l==1000){k=1;l=0;}}
- dee(100);
- xzl1302(0x8e,0x00);
- xzl1302(kzzsc(0,1,1),0x80);
- while(sb1!=0 && k!=1)
- {
- zhdq1302(1);
- smgxs();
- if(sb2==0){while(sb2==0);dee(100);shuzu[1]++;}
- if(sb3==0){while(sb3==0);dee(100);shuzu[2]++;}
-
- if(shuzu[1]%16==10){shuzu[1]-=10;shuzu[1]+=16;}
-
- if(shuzu[1]/16==6){shuzu[1]=0;shuzu[2]++;}
-
- if(shuzu[2]%16==10){shuzu[2]-=10;shuzu[2]+=16;}
-
- if(shuzu[2]%16==4&&shuzu[2]/16==2){shuzu[0]=shuzu[1]=shuzu[2]=0;}
-
- }
- while(sb1==0);
- if(k==0)
- {
- for(i=0;i<7;i++)
- {
- xzl1302(kzzsc(0,i,0),shuzu[i]);
- }
- xzl1302(0x8e,0x80);
- }
- k=0;
- }
- }
- }
- }
- void zhong1() interrupt 1
- {
- uint i;
-
- TH0=et0time/256;
- TL0=et0time%256;
-
- smgxs();
-
- i++;
-
- if(i==200)
- {
- i=0;
- }
- }
复制代码
这边是核心的驱动
- /***ds1302.c***/
- #include"temp.h"
- uchar shuzu[7]={0,0,0x12,0x07,0x05,0x06,0x16};
- void dee(uint z)
- {
- while(z--);
- }
- /*void delay(uint z)
- {
- uint x,y;
- for(x=z;x>0;x--)
- for(y=110;y>0;y--);
- }*/
- void xzl1302(uchar add,uchar dar)
- {
- uchar i;
- sclk=0;
- _nop_();
- dir=1;
- _nop_();
-
- for(i=0;i<8;i++)
- {
- dsio=add&0x01;
- add>>=1;
- _nop_();
- sclk=1;
- _nop_();
- sclk=0;
- _nop_();
- }
- _nop_();
- for(i=0;i<8;i++)
- {
- dsio=dar&0x01;
- dar>>=1;
- _nop_();
- sclk=1;
- _nop_();
- sclk=0;
- _nop_();
- }
- _nop_();
- dir=0;
- }
- uchar dsj1302(uchar dar)
- {
- uchar bi,temp,i;
- sclk=0;
- _nop_();
- dir=1;
- _nop_();
-
- for(i=0;i<8;i++)
- {
- dsio=dar&0x01;
- dar>>=1;
- _nop_();
- sclk=1;
- _nop_();
- sclk=0;
- _nop_();
- }
- _nop_();
- for(i=0;i<8;i++)
- {
- bi=dsio;
- temp=(temp>>=1)|(bi<<=7);
- _nop_();
- sclk=1;
- _nop_();
- sclk=0;
- _nop_();
- }
-
- dir=0;
- _nop_();
- sclk=1;
- _nop_();
- dsio=0;
- _nop_();
- dsio=1;
- _nop_();
- return temp;
- }
- uchar kzzsc(uchar ram,uchar temp,uchar wd)
- {
- uchar drr;
- drr=1;
- drr<<=1;
- drr=drr|ram;
- drr<<=5;
- drr+=temp;
- drr<<=1;
- drr+=wd;
- return drr;
- }
- void dq1302()
- {
- uchar i;
- for(i=0;i<7;i++)
- {
- shuzu[i]=dsj1302(kzzsc(0,i,1));
- _nop_();
- }
- }
- void csh1302()
- {
- uchar i;
- xzl1302(0x8e,0x00);
- for(i=0;i<7;i++)
- {
- xzl1302(kzzsc(0,i,0),shuzu[i]);
- _nop_();
- }
- xzl1302(0x8e,0x80);
- }
复制代码
里面有一些没用的代码,本来是要加上温度显示功能,结果没加,现在把文件发了:
相关工程文件.rar
(2.07 MB, 下载次数: 50)
|