#include<reg52.h>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
sbit SDA=P2^0;
sbit SCL=P2^1;
void delay()
{
;;
}
void delayms(uint xms)
{
uint i,j;
for(i=xms;i>0;i--)
for(j=114;j>0;j--);
}
void I2C_init()
{
SDA=1;
delay();
SCL=1;
delay();
}
void I2C_start()
{
SCL=1;
delay();
SDA=1;
delay();
SDA=0;
delay();
}
void I2C_stop()
{
SDA=0;
delay();
SCL=1;
delay();
SDA=1;
delay();
}
/*当主机接收数据时,接收完成时主机需要告诉从机数据已经发送完成发送非应答*/
/*void Master_ACK(bit i)
{
SCL=0; //允许数据变化
_nop_();
if(i)
{
SDA=0;
}
else
{
SDA=1;
}
_nop_();
SCL=1; //为1时读走数据
_nop_();
SCL=0; //应答后将时钟线拉低为了能将数据读走
_nop_();
SDA=1; //释放总线
_nop_();
}
/*主机发送数据时检测从机是否应答*/
/*bit Test_ACK()
{
SCL=1;
delay_5us();
if(SDA)
{
SCL=0;
_nop_(); //由时序图可以看出
I2C_stop(); //当从机不能接受该数据时,主机终止该信号的发送
return(0); //给主机返回一个零表示未应答
}
else
{
SCL=0;
_nop_(); //由时序图可以看出
return(1); //当从机能接受该数据时返回一个1告诉主机可以发送数据
}
} */
void respons()
{
uchar i=0;
SCL=1;
delay();
while((SDA==1)&&(i<255))
i++;
SCL=0;
delay();
}
void I2C_send_byte(uchar byte)
{
uchar i;
for(i=0;i<8;i++)
{
SCL=0; //如果放外面当一次for循环结束后时钟线等于1那么下一次数据无法输入
delay();
if(byte&0x80) //当dat&0x80等于1证明第一位为1,当等于0时证明第一位为0,令数据线为0或1读走数据
{
SDA=1;
delay();
}
else
{
SDA=0;
delay();
}
SCL=1;
delay();
byte<<=1;
}
SCL=0; //拉低时钟总线允许
delay();
SDA=1;
delay();
}
uchar I2C_read_byte()
{
uchar dat,i;
SCL=0;
delay();
SDA=1;
delay();
for(i=0;i<8;i++)
{
SCL=1;
delay();
if(SDA)
{
dat=dat|0x01;
}
else
{
dat=dat&0xfe;
}
delay();
SCL=0;
delay();
if(i<7)
{
dat=dat<<1;
}
}
return(dat);
}
void main()
{
I2C_init();
I2C_start();
I2C_send_byte(0xa0);
respons();
I2C_send_byte(5);
respons();
I2C_send_byte(0x0ee);
respons();
I2C_stop();
delayms(10);
I2C_start();
I2C_send_byte(0xa0);
respons();
I2C_send_byte(5);
respons();
I2C_start();
I2C_send_byte(0xa1);
respons();
P1=I2C_read_byte();
respons();
I2C_stop();
while(1);
}
改好啦,谢谢大家,这是用I2C通信软件模拟。发送一个数据给AT24C02然后读出来赋值给P1口;控制LED灯 |