我刚开始的时候,往24c02中的0地址开始写,写入0--7这8个数,然后读出来,结果显示:0,1,2,3,4,5,6,7
然后重新我往24c02中的0地址开始写,依次写入0,1...,9这10个数,然后再依次读出来用数码管显示。结果显示的是8,9,2,3,4,5,6,7,8,8.
我不知道为什么?
程序如下:其中I2C子程序测试过了 没问题的。
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define TRUE 1
#define FALSE 0
bit acktemp;
uchar ch,tt,cn;
uchar code tab[]={0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,0x7f,0x6f};
sbit WP=P1^0;
sbit scl=P1^1;
sbit sda=P1^2;
void delay(uchar z)
{
uchar x,y;
for(x=z;x>0;x++)
for(y=100;y>0;y++);
}
void init()
{
TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
ET0=1;
TR0=1;
EA=1;
}
void start()
{
sda=1;
_nop_();
scl=1;//起始建立时间大于4.7us
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
sda=0;//起始锁定时间大于4us
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
scl=0;
_nop_();
}
void stop()
{
sda=0;
_nop_();
scl=1;//发送停止条件的时钟信号,停止总线时间大于4us
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
sda=1;//结束总线
_nop_();//保证一个终止信号和起始信号的空闲时间大于4.7us
_nop_();
_nop_();
_nop_();
}
uchar cheak_ack()//主机发送一个字节数据后检查应答位
{
bit FO=0;
sda=1;//释放数据线等待接收应答信号ACK
_nop_();
_nop_();
scl=1;//应答位时钟拉高
_nop_();
_nop_();
F0=sda;
scl=0;
_nop_();
_nop_();
if(F0==1)
return FALSE;
else
return TRUE;
}
void master_ack()//主机接收一个字节数据应答
{
sda=0;
scl=1;
_nop_();
_nop_();
_nop_();
_nop_();
scl=0;
sda=1;
}
void master_uack()//主机接收一个字节数据非应答
{
sda=1;
scl=1;
_nop_();
_nop_();
_nop_();
_nop_();
scl=0;
sda=0;
}
void write_byte(uchar date)//在EEPROM上写一个字节数据
{
uchar i,temp;
temp=date;
for(i=0;i<8;i++)
{
temp=temp<<1;
sda=CY;
_nop_();
scl=1;
_nop_();
scl=0;
_nop_();
}
}
uchar read_byte()//从EEPROM上读一个字节数据
{
uchar i,j,k;
sda=1;
_nop_();
for(i=0;i<8;i++)
{
scl=1;
_nop_();
k=sda;
scl=0;
_nop_();
j=(j<<1)|k;
}
return j;
}
void main()
{
init();
WP=0;
P2=1;
start();
write_byte(0xae); //写24c02的地址
acktemp=cheak_ack();
write_byte(0); //从24c02内部地址0开始写
acktemp=cheak_ack();
for(ch=0;ch<9;ch++)
{
write_byte(tab[ch]);//向24c02中依次写入0到9
acktemp=cheak_ack();
}
stop();
delay(100);
while(cn<9)
{
start();
write_byte(0xae);
acktemp=cheak_ack();
write_byte(cn);
acktemp=cheak_ack();
start();
write_byte(0xaf);
master_ack();
P0=read_byte();
master_uack();
stop();
}
while(1);
}
void time0() interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
tt++;
if(tt==20)
{
tt=0;
cn++;
}
} |