往at24c02里写入数据,再读出来,赋给P1口,点亮led灯
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit SDA = P2^0;
sbit SCL = P2^1;
void delay_5us()//5us延时
{
_nop_();
}
void delay(uint z) //1ms延时
{
uint x,y;
for(x = z; x > 0; x--)
for(y = 114; y > 0 ; y--);
}
void I2C_Init() //初始化I2C
{
SDA = 1;
_nop_();
SCL = 1;
_nop_();
}
void I2C_Start() //起始信号
{
SCL = 1;
_nop_();
SDA = 1;
delay_5us();
SDA = 0;
delay_5us();
}
void I2C_Stop() //终止信号
{
SDA = 0;
_nop_();
SCL = 1;
delay_5us();
SDA = 1;
delay_5us();
}
void I2C_Send(uchar a) //发送一个字节
{
uchar i;
for(i = 0; i < 8; i++)
{
SCL = 0;
_nop_();
if( a & 0x80 )
{
SDA = 1;
_nop_();
}
else
{
SDA = 0;
_nop_();
}
SCL = 1; //拉高SCL,让从机读走数据
_nop_();
a = a << 1;
}
SCL = 0; //拉低SCL,防止SCL高电平时,SDA波动触发其他命令
_nop_();
SDA = 1; //释放SDA总线
_nop_();
}
bit I2C_Ack() // 从机应答
{
SCL = 1;
delay_5us();
if(SDA)
{
SCL = 0;
_nop_();
I2C_Stop();
return(0);
}
else
{
SCL = 0;
_nop_();
return(1);
}
}
uchar I2C_Read() //读取一个字节
{
uchar dat;
uchar i;
SCL=0;
_nop_();
SDA = 1;
_nop_();
for(i = 0; i < 8; i++)
{
SCL = 1;
_nop_();
if(SDA)
{
dat |= 0x01;
}
else
{
dat &= 0xfe;
}
_nop_();
SCL = 0 ;
_nop_();
if(i < 7) //接收第八位后,不用再左移
{
dat = dat << 1;
}
}
return (dat);
}
void Master_Ack(bit i) //主机应答
{
SCL = 0;
_nop_();
if (i) //如果i = 1 那么拉低数据总线 表示主机应答
{
SDA = 0;
}
else
{
SDA = 1; //发送非应答
}
_nop_();
SCL = 1;//拉高时钟总线 让从机从SDA线上读走主机的应答信号
delay_5us();
SCL = 0;
_nop_();
SDA = 1;
_nop_();
}
int main()
{
I2C_Init(); //初始化
I2C_Start(); //开始信号
I2C_Send(0xa0+0); //发送器件地址,方向为写
if(!I2C_Ack()) //判断从机是否应答
return 0;
I2C_Send(255); //往哪个单元写入数据
if(!I2C_Ack()) //判断从机是否应答
return 0;
I2C_Send(0xfe); //发送数据
if(!I2C_Ack()) //判断从机是否应答
return 0;
I2C_Stop(); //停止
delay(2000);
I2C_Start();
I2C_Send(0xa0+0);
if(!I2C_Ack())
return 0;
I2C_Send(255);
Master_Ack(1);
I2C_Start();
I2C_Send(0xa0+1);
if(!I2C_Ack())
return 0;
P1=I2C_Read();
Master_Ack(0);
I2C_Stop();
while(1);
}