以下的C语言源程序是用8051单片机的普通I/O口(如P0.0/P0.4)模拟实现PCF8563的I2C时钟/日历芯片的操作,有字节写/读两种状态。程序中从地址的读地址为0A3H,写地址为0A2H.所发送的数据字节为9个,发送的初始数据在rom_sed[9]中,rom_sed[9]定义了寄存器中当前发送的值:控制/状态寄存器1为0,控制/状态寄存器2为0,秒寄存器为0,分钟寄存器55,小时寄存器为23,日寄存器为31,星期寄存器为6,月/世纪寄存器为0x12,年寄存器为0x99(即1999年12月31日23点55分0秒),当程序运行一段时间(5分钟)后,从地址寄存器02H开始读数据,数据存放在rom_rec7中,发现变量rom_rec7变为2000年1月1日0点0分。若外转帐电路有显示,则时间可以显示在面板上。
#include
#define byte unsignedchar sbit scl=0x81; //定义串行I/O口
sbit sda=0x80;
idata byte rom_sed[9];
idata byte rom_rec[7];
idata byte j,k;
bit flag,flag1;
void delay(void)//延时子程序
{
data byte i;
for(i=0;i<6;i );
}
void I_start(void)//发送I2C总线起始条件子程序
{sda=1; ;
scl=1;
delay();
sda=0;
delay();
scl=0; ;
}
void I_stop(void) //I2C总线停止条件子程序
{
sda=0; ;
scl=1;
delay();
sda=1;
delay();
}
bit I_send(byte I_data) //字节数据传送子程序
{
data byte i;
for(i=0,i<8;i )
{
sda-(bit)(I_data&0x80);
I_data=I_data<<1; ;
scl=1;
delay();
scl=0; } ;;
sda=1; ;; //readyfor receiving ACK
bit scl=1; ;; //start receiving ack
bit flag=0;
if(sda= =0)
flag=0;
else flag=1; //
return(~I_clock());
scl=0;return(flag);
}
byte I_receive(void) //字节数据接收子程序
{
data byte i;
byteI_data=0;
sda=1;
for(i=0;I<8;i )
{
I_data*=2; ;
scl=0;
delay();
scl=1;
;; if(sda= =1)I_data ; ;;
}
scl=0; ;;; sda=0;
if(flag1==0)
{
;;scl=1;
delay();
scl=0;
} //not last receic_byte ACK
else
{
sda=1;;;scl=1;
delay();
scl=0;
flag1=0;
} //the last receive_byte ~ACK
return(I_data);
}
main() //主程序
{
data byte i;
rom_sed[0]=0x00;
rom_sed[1]=0x00;
rom_sed[2]=0x00;
rom_sed[3]=0x55;
rom_sed[4]=0x23;
rom_sed[5]=0x31;
rom_sed[6]=0x06;
rom_sed[7]=0x92;
rom_sed[8]=0x99;
for(i=0;i<255;i )
delay();
I_start();
if(~I_send(rom_sed[i]))
;
else
;
}
I_stop();
}
else
;
}
else
;
start: I_start();
if(~I_send(0xa2))//pcf_write address
{
if(~I_send(0x02)) //pcf_status register address
{
I_start();
if(~I_send(0xa3)) //write status register
{for(i=0;i<7;i )
{
if(i= =6)
flag1=1;
else
flag1=0;
rom_rec[i]=I_receive();
switch(i)
{
case1:rom_rec[i]=rom_rec[i]&0x7f;break;
case2:
case3:
rom_rec[i]=rom_rec[i]&0x3f;break;
case4:
rom_rec[i]=rom_rec[i]&0x07;
break;
case5:
rom_rec[i]=rom_rec[i]&0x9f;
brealk;
default:break;
}
}
I_stop()
}
}
}
goto start;
}