模拟I2C读取时钟芯片PCF8563中的日期时间
#define SCLK_Clr() GPIO_ResetBits(GPIOD, GPIO_PIN_1)//SDA IIC接口的时钟信号
#define SCLK_Set() GPIO_SetBits(GPIOD, GPIO_PIN_1)#define SDIN_Clr() GPIO_ResetBits(GPIOD, GPIO_PIN_2)//SCL IIC接口的数据信号
#define SDIN_Set() GPIO_SetBits(GPIOD, GPIO_PIN_2)
u8 buf[7];
void SDA_IN(u8 in)
{
if(in)
GPIO_Init(GPIOD, GPIO_PIN_2, GPIO_Mode_In_PU_IT ); //输入
else
GPIO_Init(GPIOD, GPIO_PIN_2, GPIO_Mode_Out_OD_HiZ_Slow); //输出
}
void delay_u()
{
while(--10);
}
/**************************************************
**************************************************/
void Start()
{
SCLK_Set();
SDIN_Set();
delay_u();
SDIN_Clr();
delay_u();
SCLK_Clr();
}
/**********************************************
//IIC Stop
**********************************************/
void Stop()
{
SCLK_Clr();
delay_u();
SDIN_Clr();
delay_u();
SCLK_Set();
delay_u();
SDIN_Set();
delay_u();
}
{
if(ack) SDIN_Set();
else SDIN_Clr();
delay_u();
SCLK_Set();
delay_u();
SCLK_Clr();
}
{
u8 errtime;
errtime = 0;
SDA_IN(1);
SCLK_Set();
delay_u();
while(SDA_READ)
{ errtime++;
if(errtime==20)
{Stop();
break;}
}
SCLK_Clr();
SDA_IN(0);
}
/**********************************************
// IIC Write byte
**********************************************/
void writebyte(u8 IIC_Byte)
{
u8 i;
u8 m,da;
da=IIC_Byte;
SDA_IN(0);
SCLK_Clr();
for(i=0;i<8;i++)
{
m=da;
m=m&0x80;
if(m==0x80)
{SDIN_Set();}
else SDIN_Clr();
da=da<<1;
SCLK_Set();
delay_u();
SCLK_Clr();
}
WaitACK(); //关键问题
}
u8 Readbyte()
{
u8 i,bytedata;
SDA_IN(1);
delay_u();
SDIN_Set();
for(i=0;i<8;i++)
{
SCLK_Set();
bytedata<<=1;
if(SDA_READ)
{
bytedata++;
}
SCLK_Clr();
delay_u();
}
SDA_IN(0);
return(bytedata);
}
/**********************************************
// IIC Write Command
**********************************************/
void writeData(u8 address,u8 mdata)
{
Start();
writebyte(0xa2); /*写命令*/
writebyte(address); /*写地址*/
writebyte(mdata); /*写数据*/
Stop();
}
/********************************************
输入数据<-pcf8563
********************************************/
u8 ReadData(u8 address) /*单字节*/
{ u8 rdata =0;
Start();
writebyte(0xa2); /*写命令*/
writebyte(address); /*写地址*/
Start();
writebyte(0xa3); /*读命令*/
rdata=Readbyte();
WriteACK(1);
Stop();
return(rdata);
}
void ReadData1(u8 address,u8 count,u8 * buff) /*多字节*/
{
u8 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(void)
{
buf[0]=ReadData(0x02);
buf[1]=ReadData(0x03);
buf[2]=ReadData(0x04);
buf[3]=ReadData(0x05);
buf[4]=ReadData(0x06);
buf[5]=ReadData(0x07);
buf[6]=ReadData(0x08);
Stop();
buf[0]=buf[0]&0x7F;//秒
buf[1]=buf[1]&0x7F;//分
buf[2]=buf[2]&0x3F;//时
buf[3]=buf[3]&0x3F;//日
buf[4]=buf[4]&0x07;//星期
buf[5]=buf[5]&0x1F;//月
delay_u();
buf[0]=HexToBcd(buf[0]);
buf[1]=HexToBcd(buf[1]);
buf[2]=HexToBcd(buf[2]);
buf[3]=HexToBcd(buf[3]);
buf[5]=HexToBcd(buf[5]);
buf[6]=HexToBcd(buf[6]);
}
/*******************
写时间修改值
*******************/
void RTC_Set_Time(u8 sec,u8 min,u8 hour,u8 day,u8 week,u8 month,u8 year)
{
sec=BcdToHex(sec);
min=BcdToHex(min);
hour=BcdToHex(hour);
day=BcdToHex(day);
week=week;
month=BcdToHex(month);
year=BcdToHex(year);
delay_u();
writeData(0x02,sec);
writeData(0x03,min);
writeData(0x04,hour);
writeData(0x05,day);
writeData(0x06,week);
writeData(0x07,month);
writeData(0x08,year);
}
/****************************
P8563的初始化
********************************/
void P8563_init(void)
{
writeData(0x00,0x20); //时钟停止
RTC_Set_Time(30,12,12,1,5,12,17); //秒,分,时,天,星期,月,年
delay_u();
writeData(0x00,0x00); //时钟开始
}
/********************************************************************/