前段时间用pcf8563芯片做了个电子时钟,这个芯片自动走时间,我只用去读和写就行了,pcf8563要加一个后备电池,这样就不怕单片机掉电了。这个不太符合你的要求,不过这是我现成的,我可不想在这里重新写代码。代码不是很规范,但是能正常运行。
你在Keil里建个工程,下面一段是display.c的代码:

#include?"at89x51.h"
#include?"PCF8563.h"
//#include?"TG12232.h"
#define?Key_Set?P2_2
#define?Key_Add?P2_1
#define?Key_Sub?P2_0
//#define?LCD_CS?P2_5
//#define?LCD_DATA?P2_6
//#define?LCD_CLK?P2_7
void?Key_down();
void?Displaybuffer(char?Location);
//void?LCD_Display();
unsigned?char?LedTable[10]={0x3f,0x03,0x6d,0x67,0x53,0x76,0x7e,0x23,0x7f,0x77};
bit?state=0;
char?set=0;
void?main()
{
unsigned?char?i,j,n=2; P1=0; TMOD=0x01; TH0=0x4c; TL0=0x00; ET0=1; EA=1;//?P8563_init();
P2=0xff; P3=0x02; P1=LedTable[8];//?while(n--)
for(i=0;i<250;i++)for(j=0;j<6;j++)
{
delay(10);;
P3<<=1;
if(P3==0x80)
P3=0x02;
delay(10);
}
delay(5000);//?lcd_init();
//?set_lcd_position(0,1); //汉字定位到上行左端
//?lcd_display(0,0,"Welcome?to?use!");
//?lcd_display(1,0,"? Leo.Zheng? ");
//?delay(1000);
//?lcd_send_com(0x01);//清除
//?lcd_display(0,0,"20? /? /");
while(1) { Key_down(); Displaybuffer(set); //?LCD_Display(); }}
void?Time0_H()?interrupt?1
{
static?unsigned?char?i=0;? TH0=0x4c; TL0=0x00; i++; if(i==8) {? i=0; state=~state; }}?
void?Key_down()
{
//?static?char?set=0;
unsigned?char?buffer; if(!Key_Set) for(buffer=0;buffer<250;buffer++)_nop_();
if(!Key_Set) { if(set==0) {writeData(0x0,0x20);//使时间停止?
TR0=1;
} set++; if(set==4) {set=0;
TR0=0;
writeData(0x0,0x00);
} while(!Key_Set)Displaybuffer(set);
} if(!Key_Add) for(buffer=0;buffer<250;buffer++)_nop_();
if(!Key_Add) { if(set==0)return;
P8563_gettime(); buffer=?g8563_Store[set-1]; buffer=((buffer&0xf0)>>4)*10+(buffer&0x0f); if(buffer>=59)buffer=0;
else?if(buffer>=23?&&?set==3)buffer=0;
elsebuffer++;
buffer=(buffer/10<<4)+(buffer%10); writeData(set+1,buffer); while(!Key_Add)Displaybuffer(set);
} if(!Key_Sub) for(buffer=0;buffer<250;buffer++)_nop_();
if(!Key_Sub) { if(set==0)return;
P8563_gettime(); buffer=?g8563_Store[set-1]; buffer=((buffer&0xf0)>>4)*10+(buffer&0x0f); if(buffer?==?0) {if(set==3)
buffer=23;
else
buffer=59;
} elsebuffer--;?
buffer=(buffer/10<<4)+(buffer%10); writeData(set+1,buffer); while(!Key_Sub)Displaybuffer(set);
}}?
void?Displaybuffer(char?Location)
{
unsigned?char?i; P8563_gettime(); if(Location==1?&&?state==0) {? P1=0; P3=0; goto?sec_bit1; }? P3=0x02;? P1=LedTable[g8563_Store[0]&0x0f];?//secsec_bit1:
for(i=0;i<250;i++); P1=0;? if(Location==1?&&?state==0) { P1=0; P3=0; goto?sec_bit2; }? P3=0x04; P1=LedTable[(g8563_Store[0]&0xf0)>>4];sec_bit2:
for(i=0;i<250;i++);? P1=0; if(Location==2?&&?state==0) {? P1=0; P3=0; goto?min_bit1; }? P3=0x08; P1=LedTable[g8563_Store[1]&0x0f];? //minmin_bit1:
for(i=0;i<250;i++);? P1=0; if(Location==2?&&?state==0) {? P1=0; P3=0; goto?min_bit2; } P3=0x10;? P1=LedTable[(g8563_Store[1]&0xf0)>>4];min_bit2:
for(i=0;i<250;i++);? P1=0; if(Location==3?&&?state==0) {? P1=0; P3=0;
hour_bit1:
for(i=0;i<250;i++);? P1=0; if(Location==3?&&?state==0) {? P1=0; P3=0; goto?hour_bit2; }? P3=0x40; P1=LedTable[(g8563_Store[2]&0xf0)>>4];hour_bit2:
for(i=0;i<250;i++); P1=0; P3=0x02;?}
这下面一段是pcf8563.h的代码:
#ifndef?__PFC8563_H__
#define?__PFC8563_H__
#include?<intrins.h>
#define?uchar?unsigned?char
sbit?SDA=P2^4;
sbit?SCL=P2^3;
//extern?void ? _nop_ ?(void);
//extern?void?delay(unsigned?int?ms);
uchar?g8563_Store[7];?
uchar?code?c8563_Store[7]={0x01,0x02,0x07,0x09,0x04,0x02,0x12};?
void?delay(long?time)
{while(time--);
}
void?DD()
{
//delay(1);
//?uchar?i;
// for(i=0;i<250;i++)
_nop_();_nop_();?
}
void?Start()
{? EA=0;
SDA=1;
SCL=1;
DD();
SDA=0;
DD();
SCL=0;
}
void?Stop()
{
SDA=0;
SCL=0;
DD();
SCL=1;
DD();
SDA=1;
DD();
EA=1;
}
void?WriteACK(uchar?ack)
{
SDA=ack;
DD();
SCL=1;
DD();
SCL=0;
}
void?WaitACK()
{? uchar?errtime=20;
SDA=1;
DD();?
SCL=1;
DD();
while(SDA)
{? errtime--;
? if(!errtime)?
? {
Stop(); SDA=0;? //自己加的******? }
}
SDA=1;?//自己加的******
SCL=0;
DD();
}
void?writebyte(uchar?wdata)
{
uchar?i;
for(i=0;i<8;i++)
{
if(wdata&0x80)?SDA=1;
else?SDA=0;
wdata<<=1;
SCL=1;
DD();
SCL=0;
}
WaitACK(); ?//I2C器件或通讯出错,将会退出I2C通讯
}
uchar?Readbyte()
{
uchar?i,bytedata;
SDA=1;
for(i=0;i<8;i++)
{
? SCL=1;?
? bytedata<<=1;
? bytedata|=SDA;
? SCL=0;
? DD();
}
return(bytedata);
}
void?writeData(uchar?address,uchar?mdata)
{
Start();
writebyte(0xa2);?
writebyte(address);?
writebyte(mdata);?
Stop();
}
uchar?ReadData(uchar?address)?
{? uchar?rdata;
Start();
writebyte(0xa2);?
writebyte(address);?
Start();
writebyte(0xa3);?
rdata=Readbyte();
WriteACK(1);
Stop();
return(rdata);
}
void?ReadData1(uchar?address,uchar?count,uchar?*?buff)?
{? uchar?i;
Start();
writebyte(0xa2);?
writebyte(address);?
Start();
writebyte(0xa3);?
for(i=0;i<count;i++)
{
buff[i]=Readbyte();
if(i<count-1)?WriteACK(0);
}
WriteACK(1);Stop();
}
void?P8563_Read()
{ uchar?time[7];
ReadData1(0x02,0x07,time);
g8563_Store[0]=time[0]&0x7f;?
g8563_Store[1]=time[1]&0x7f;?
g8563_Store[2]=time[2]&0x3f;?
g8563_Store[3]=time[4]&0x07;?
g8563_Store[4]=time[3]&0x3f;? g8563_Store[5]=time[5]&0x1f;? g8563_Store[6]=time[6];?}
void?P8563_gettime()
{
P8563_Read();
if(g8563_Store[0]==0)
? P8563_Read();?
}
//void?P8563_settime()
//{
// ?uchar?i;
// ?for(i=2;i<=8;i++)?{?writeData(i,g8563_Store[i-2]);?}
// ?writeData(6,g8563_Store[3]);
//}
#endif



