c51单片机I2c总线的读写编程步骤

2024-06-23 22:16:24
推荐回答(1个)
回答1:

你说的枯激是IO模拟i2c吧弊败旦,这个你参考下
#pragma ot(6,SIZE)
#define ERRORCOUNT 10
enum eepromtype {M2401,M2402,M2404,M2408,M2416,M2432,M2464,M24128,M24256};
enum eepromtype EepromType;

/****************************** I2C总线 ******************************/

bit RW24XX(uchar *DataBuff,uchar ByteQuantity,uint Address,uchar ControlByte,enum eepromtype EepromType)
{
void Delay(uchar DelayCount);
void IICStart(void);
void IICStop(void);
bit IICRecAck(void);
void IICNoAck(void);
void IICAck(void);
uchar IICReceiveByte(void);
void IICSendByte(uchar sendbyte);

uchar data j,i = ERRORCOUNT;
bit errorflag = 1;

while (i--)
{
IICStart();
IICSendByte(ControlByte & 0xfe);
if (IICRecAck())
continue;
if (EepromType > M2416)
{
IICSendByte((uchar)(Address >>租扰 8));
if (IICRecAck())
continue;
}
IICSendByte((uchar)Address);
if (IICRecAck())
continue;
if (!(ControlByte & 0x01))
{
j = ByteQuantity;
errorflag = 0;

while (j--)
{
IICSendByte(*DataBuff++);
if(!IICRecAck())
continue;
errorflag = 1;
break;
}

if (errorflag==1)
continue;
break;
}
else
{
IICStart();
IICSendByte(ControlByte);
if (IICRecAck())
continue;

while (--ByteQuantity)
{
*DataBuff++ = IICReceiveByte();
IICAck();
}

*DataBuff = IICReceiveByte(); //read last byte data
IICNoAck();
errorflag = 0;
break;
}
}

IICStop();

if (!(ControlByte & 0x01))
{
Delay(255);
Delay(255);
Delay(255);
Delay(255);
}

return(errorflag);
}

/***************** 启动总线 ********************/
void IICStart(void)
{
scl = 0;
sda = 1;
scl = 1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
sda = 0;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
scl = 0;
sda = 1;
}

/***************** 停止IIC总线 ****************/
void IICStop(void)
{
scl = 0;
sda = 0;
scl = 1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
sda = 1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
scl = 0;
}

/************** 检查应答位 *******************/
bit IICRecAck(void)
{
scl = 0;
sda = 1;
scl = 1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
CY = sda; //因为返回值总是放在CY中的
scl = 0;
return(CY);
}

/*************** 对IIC总线产生应答 *******************/
void IICACK(void)
{
sda = 0;
scl = 1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
scl = 0;
_nop_();
_nop_();
sda = 1;
}

/***************** 不对IIC总线产生应答 ***************/
void IICNoAck(void)
{
sda = 1;
scl = 1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
scl = 0;
}

/******************* 向IIC总线写数据 *********************/
void IICSendByte(uchar sendbyte)
{
uchar data j = 8;
for (;j > 0;j--)
{
scl = 0;
sendbyte <<= 1; //无论C51怎样实现这个操作,始终会使CY=sendbyte^7;
sda = CY;
scl = 1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
scl = 0;
}

/***************** 从IIC总线上读数据子程序 ******************/
uchar IICReceiveByte(void)
{
register receivebyte,i = 8;
scl = 0;
while (i--)
{
scl = 1;
receivebyte = (receivebyte << 1) | sda;
scl = 0;
}
return(receivebyte);
}

/*************** 一个简单延时程序 ******************/
void Delay(uchar DelayCount)
{
while(DelayCount--);
}

void Delay_Msec(uchar t)
{
uchar i;
while (t > 0)
{
for (i = 0;i < 200;i++)
{
WDT = 1;
_nop_();
_nop_();
_nop_();
_nop_();
}
t--;
}
}

/*************** 24C256读一个字节 *****************/
uchar Rd_24c256(uint beginbyte)
{
uchar data result;
uchar i;
EA = 0;
i = RW24XX(&result,1,beginbyte,rd_24c256,M24256);
EA = 1;
return(result);
}

/*************** 24C256写一个字节 ***************/
void Wr_24c256(uint address,uchar datum)
{
uchar i;
EA = 0;
i = RW24XX(&datum,1,address,wr_24c256,M24256);
Delay_Msec(10);
EA = 1;
}