前段时间用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 LCD_Display()
{
lcd_display_char(0,2,((g8563_Store[6]&0xf0)>>4)+0x30);//年
lcd_display_char(0,3,(g8563_Store[6]&0x0f)+0x30);//
}*/
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;
else
buffer++;
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;
}
else
buffer--;
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]; //sec
sec_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]; //min
min_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;
goto hour_bit1;
}
P3=0x20;
P1=LedTable[g8563_Store[2]&0x0f]; //hour
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}; /*写入时间初值:秒,分,时,日,周,月,年(BCD码)
07:59:00*/
void delay(long time)
{while(time--);
}
/********************************************
内部函数,延时1
********************************************/
void DD()
{
//delay(1);
// uchar i;
// for(i=0;i<250;i++)
_nop_();
_nop_(); /*根据晶振频率制定延时时间*/
}
/********************************************
内部函数,I2C开始
********************************************/
void Start()
{ EA=0;
SDA=1;
SCL=1;
DD();
SDA=0;
DD();
SCL=0;
}
/********************************************
内部函数,I2C结束
********************************************/
void Stop()
{
SDA=0;
SCL=0;
DD();
SCL=1;
DD();
SDA=1;
DD();
EA=1;
}
/********************************************
内部函数,输出ACK ,每个字节传输完成,输出ack=0,结束读数据,ack=1;
********************************************/
void WriteACK(uchar ack)
{
SDA=ack;
DD();
SCL=1;
DD();
SCL=0;
}
/********************************************
内部函数,等待ACK
********************************************/
void WaitACK()
{ uchar errtime=20;
SDA=1;
DD(); /*读ACK*/
SCL=1;
DD();
while(SDA)
{ errtime--;
if(!errtime)
{
Stop();
SDA=0; //自己加的******
}
}
SDA=1; //自己加的******
SCL=0;
DD();
}
/********************************************
内部函数.输出数据字节
入口:B=数据
********************************************/
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通讯
}
/********************************************
内部函数.输入数据
出口:B
********************************************/
uchar Readbyte()
{
uchar i,bytedata;
SDA=1;
for(i=0;i<8;i++)
{
SCL=1;
bytedata<<=1;
bytedata|=SDA;
SCL=0;
DD();
}
return(bytedata);
}
/********************************************
输出数据->pcf8563
********************************************/
void writeData(uchar address,uchar mdata)
{
Start();
writebyte(0xa2); /*写命令*/
writebyte(address); /*写地址*/
writebyte(mdata); /*写数据*/
Stop();
}
/********************************************
输入数据<-pcf8563
********************************************/
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(); /*如果为秒=0,为防止时间变化,再读一次*/
}
/********************************************
写时间修改值
********************************************/
//void P8563_settime()
//{
// uchar i;
// for(i=2;i<=8;i++) { writeData(i,g8563_Store[i-2]); }
// writeData(6,g8563_Store[3]);
//}
/********************************************
P8563的初始化-----外部调用
********************************************/
/*
void P8563_init()
{
uchar i;
if((ReadData(0xa)&0x3f)!=0x8) //检查是否第一次启动,是则初始化时间
{
// for(i=0;i<=6;i++) g8563_Store[i]=c8563_Store[i]; //初始化时间
// P8563_settime();
writeData(0x0,0x00);
writeData(0xa,0x8); //8:00报警
writeData(0x1,0x12); //报警有效
writeData(0xd,0xf0);
}
}
*/
#endif
谢谢,搞定发到我QQ邮箱,[email protected],十分感谢!!!