#include<reg52.h>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
sbit SCL = P1^0;
sbit SDA = P1^1;
void Delayus(uchar us)
{
while(us--)
{
_nop_();
_nop_();
_nop_();
}
}
void I2CStart() //I2C起始信号
{
SDA=1;
_nop_();
SCL=1; //首先保证SDA SCL都是1;
Delayus(4);
SDA=0;
Delayus(4);
SCL=0; //钳住I2C总线,准备发送或接受数据;
_nop_();
_nop_();
}
void I2CStop() //I2C终止信号
{
SDA=0; //首先保证SDA SCL都为0
_nop_();
SCL=1;
Delayus(4);
SDA=1;
Delayus(4);
}
bit I2C_Write_Byte(uchar dat) //I2C写字节函数 返回从机应答值,为1时,接受成功,否则失败;
{
bit ACK; //暂存从机应答值
uchar Mask; //用于探测字节内某一位值的掩码变量
for(Mask=0x80;Mask!=0;Mask>>=1)
{
if((Mask&dat)==0) SDA=0;
else SDA=1;
_nop_();
SCL=1;
Delayus(4);
SCL=0;
}
_nop_();
_nop_();
SDA = 1;
_nop_();
_nop_();
SCL=1;
Delayus(3);
if(SDA==0)ACK=0;
else ACK=1;
SCL=0;
Delayus(2);
return (~ACK); //0写入失败,1写入成功
}
uchar I2C_Rec_Byte() //I2C读字节函数;返回读取的字节;发送应答信号;(若发送非应答信号只要将最后发送的0改为1即可)
{
uchar Dat=0x00; //定义返回值
uchar Mask; //设置掩码;
SDA = 1; //首先确保主机释放SDA
for(Mask=0x80;Mask!=0;Mask>>=1) //从高位到低位依次进行;
{
Delayus(1);
SCL=1; //拉高SCL
if(SDA==0)Dat&=~Mask;
else Dat|=Mask;
Delayus(1);
SCL=0;
}
SDA=0; //应答信号(非应答信号为1) //这里的0或1是主机的应答信号;应答0——表示继续读取;应答1——表示停止读取
Delayus(2);;
SCL=1;
Delayus(4);
SCL=0;
return Dat;
}
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
sbit SCL = P1^0;
sbit SDA = P1^1;
void Delayus(uchar us)
{
while(us--)
{
_nop_();
_nop_();
_nop_();
}
}
void I2CStart() //I2C起始信号
{
SDA=1;
_nop_();
SCL=1; //首先保证SDA SCL都是1;
Delayus(4);
SDA=0;
Delayus(4);
SCL=0; //钳住I2C总线,准备发送或接受数据;
_nop_();
_nop_();
}
void I2CStop() //I2C终止信号
{
SDA=0; //首先保证SDA SCL都为0
_nop_();
SCL=1;
Delayus(4);
SDA=1;
Delayus(4);
}
bit I2C_Write_Byte(uchar dat) //I2C写字节函数 返回从机应答值,为1时,接受成功,否则失败;
{
bit ACK; //暂存从机应答值
uchar Mask; //用于探测字节内某一位值的掩码变量
for(Mask=0x80;Mask!=0;Mask>>=1)
{
if((Mask&dat)==0) SDA=0;
else SDA=1;
_nop_();
SCL=1;
Delayus(4);
SCL=0;
}
_nop_();
_nop_();
SDA = 1;
_nop_();
_nop_();
SCL=1;
Delayus(3);
if(SDA==0)ACK=0;
else ACK=1;
SCL=0;
Delayus(2);
return (~ACK); //0写入失败,1写入成功
}
uchar I2C_Rec_Byte() //I2C读字节函数;返回读取的字节;发送应答信号;(若发送非应答信号只要将最后发送的0改为1即可)
{
uchar Dat=0x00; //定义返回值
uchar Mask; //设置掩码;
SDA = 1; //首先确保主机释放SDA
for(Mask=0x80;Mask!=0;Mask>>=1) //从高位到低位依次进行;
{
Delayus(1);
SCL=1; //拉高SCL
if(SDA==0)Dat&=~Mask;
else Dat|=Mask;
Delayus(1);
SCL=0;
}
SDA=0; //应答信号(非应答信号为1) //这里的0或1是主机的应答信号;应答0——表示继续读取;应答1——表示停止读取
Delayus(2);;
SCL=1;
Delayus(4);
SCL=0;
return Dat;
}