#include <reg52.h>
#include <intrins.h>
sbit SDA = P3^0;
sbit SCL = P3^1;
typedef unsigned char uchar;
typedef unsigned int uint;
bit AckFlag; //应答标志位
#define At24c02ADDR 0xa0 //AT24C02硬件地址
#define I2cWrite 0 //写方向位
#define I2cRead 1 //读方向位
//延时5us函数
void delay5us()
{
_nop_();
}
//起始信号
void IIC_START()
{
SCL = 1;
SDA = 1;
delay5us();
SDA = 0;
delay5us();
}
//结束信号
void IIC_STOP()
{
SDA = 0;
SCL = 1;
delay5us();
SDA = 1;
delay5us();
}
//应答位,主机主动控制是否应答
void SendACK(bit i)
{
SCL = 0;
delay5us();
if(i ==1)
{
//非应答
SDA = 1;
}
else SDA = 0;//应答
SCL = 1; //拉高总线,让从机读SDA
delay5us();//保持5us
SCL = 0; //拉低时钟总线,允许SDA释放
SDA = 1;//释放数据总线
}
//从机应答检测
bit READACK()
{
SCL = 0;
SCL = 1;
if(SDA)//NOACK
{
SCL = 0;
return(1);//返回1
}
else//ACK
{
SCL = 0;
return(0);//返回0
}
}
//发送一个字节
void I2cSendByte(uchar dat)
{
uchar temp=0,i=0;
for(i = 0;i<8;i++)
{
temp = dat&(0x80);// 1000 000取出最高位
SCL =0;
delay5us();
if(temp) SDA = 1;
else SDA = 0;
delay5us();
SCL = 1; //拉高时钟,让从机读SDA
dat<<=1;
}
SCL = 0; //拉低时钟总线,允许SDA释放
SDA = 1;//释放数据总线
}
//读取一个字节
uchar IIC_READ()
{
uchar i, DAT;
for(i=0;i<8;i++)
{
DAT= DAT<<1; //数据左移1位,准备接收一位,或者放再后面写个if(i<7)
SCL = 0; //拉低时钟总线,允许从机控制SDA变化
SCL = 1; //拉高时钟总线,读取SDA上的数据
if(SDA) DAT |= 0X01;
else DAT &= ~(1<<0);//这句可以省略
}
return (DAT);
}
//以上是IIC的初始化,下面的是对AT24C02进行的读操作
void At24c02Write(uchar ADDR,uchar DAT)
{
IIC_START();
I2cSendByte(At24c02ADDR+I2cWrite);
if(READACK())
AckFlag = 1;//非应答
else AckFlag = 0;//应答
I2cSendByte(ADDR);
if(READACK()) AckFlag = 1;//非应答
else AckFlag = 0;//应答
I2cSendByte(DAT);
if(READACK()) AckFlag = 1;//非应答
else AckFlag = 0;//应答
IIC_STOP();
}
uchar At24c02Read(uchar ADDR)
{
uchar DAT;
IIC_START();//I2C起始信号
I2cSendByte(At24c02ADDR + I2cWrite);//发送器件地址加读写方向位
if(READACK())//读从机应答
AckFlag = 1; //NOACK
else
AckFlag = 0; //ACK
I2cSendByte(ADDR);//I2C发送一个字节
READACK();//读从机应答
IIC_START();//再次产生I2C起始信号
I2cSendByte(At24c02ADDR + I2cRead);//发送器件地址加读写方向位 读
if(READACK())//读从机应答
AckFlag = 1; //NOACK
else
AckFlag = 0; //ACK
DAT = IIC_READ();//读一字节
SendACK(1);//主机发送非应答
IIC_STOP(); //I2C停止信号
return(DAT);//返回读出数据
}
int main()
{
uchar re;
At24c02Write(0X00,1000);
re = At24c02Read(0X00);
while(1);
return 0;
}
51模拟IIC
猜你喜欢
转载自blog.csdn.net/ABCisCOOL/article/details/107788828
今日推荐
周排行