I2C总线驱动的C语言源程序详细说明

发布时间:2023-06-07  

i2c 总线上单片机系统中常用到的总线技术这里给大家介绍一个I2C总线驱动的C51语言源程序。


//#pragma ot(6,SIZE)

#i nclude 《AT89X52.H》

#i nclude 《intrins.h》

#define ERRORCOUNT 10

#define readI2C 0xa1

#define writeI2C 0xa0

sbit SDA=P1^6;

sbit SCL=P1^5;

enum eepromtype {M2401,M2402,M2404,M2408,M2416,M2432,M2464,M24128,M24256};

enum eepromtype EepromType;

//DataBuff为读写数据输入/输出缓冲区的首址

//ByteQuantity 为要读写数据的字节数量

//Address 为EEPROM的片内地址

//ControlByte 为EEPROM的控制字节,具体形式为(1)(0)(1)(0)(A2)(A1)(A0)(R/W),其中R/W=1,

//表示读操作,R/W=0为写操作,A2,A1,A0为EEPROM的页选或片选地址;

//EepromType为枚举变量,需为M2401至M24256中的一种,分别对应24C01至24C256;

//函数返回值为一个位变量,若返回1表示此次操作失效,0表示操作成功;

//ERRORCOUNT为允许最大次数,若出现ERRORCOUNT次操作失效后,则函数中止操作,并返回1

//SDA和SCL由用户自定义,这里暂定义为P0^0和P0^1;

//其余的用户不用管,只要把只子程序放在你的程序中并调用它就可以了;

/*******************************I2C总线驱动(C51语言源程序)**********************************************/

bit RW24XX(unsigned char *DataBuff,unsigned char ByteQuantity,unsigned int Address,

unsigned char ControlByte,enum eepromtype EepromType)

{

void Delay(unsigned char DelayCount);

void I2CStart(void);

void I2CStop(void);

bit I2CRecAck(void);

void I2CNoAck(void);

void I2CAck(void);

unsigned char I2CReceiveByte(void);

void I2CSendByte(unsigned char sendbyte);

unsigned char data j,i=ERRORCOUNT;

bit errorflag=1;

while(i--)

{

I2CStart();

I2CSendByte(ControlByte&0xfe);

if(I2CRecAck())

continue;

if(EepromType》M2416)

{

I2CSendByte((unsigned char)(Address》》8));

if(I2CRecAck())

continue;

}

I2CSendByte((unsigned char)Address);

if(I2CRecAck())

continue;

if(!(ControlByte&0x01))

{

j=ByteQuantity;

errorflag=0; //********clr errorflag

while(j--)

{

I2CSendByte(*DataBuff++);

if(!I2CRecAck())

continue;

errorflag=1;

break;

}

if(errorflag==1)

continue;

break;

}

else

{

I2CStart();

I2CSendByte(ControlByte);

if(I2CRecAck())

continue;

while(--ByteQuantity)

{

*DataBuff++=I2CReceiveByte();

I2CAck();

}

*DataBuff=I2CReceiveByte(); //read last byte data

I2CNoAck();

errorflag=0;

break;

}

}

I2CStop();

if(!(ControlByte&0x01))

{

Delay(255);

Delay(255);

Delay(255);

Delay(255);

}

return(errorflag);

}

/*****************以下是对I2C总线的操作子程序***/

/*****************启动总线**********************/

void I2CStart(void)

{

SCL=0; //

SDA=1;

SCL=1;

_nop_();

_nop_();

_nop_();

SDA=0;

_nop_();

_nop_();

_nop_();

_nop_();

SCL=0;

SDA=1; //

}

/*****************停止I2C总线****************/

void I2CStop(void)

{

SCL=0;

SDA=0;

SCL=1;

_nop_();

_nop_();

_nop_();

SDA=1;

_nop_();

_nop_();

_nop_();

SCL=0;

}

/**************检查应答位*******************/

bit I2CRecAck(void)

{

SCL=0;

SDA=1;

SCL=1;

_nop_();

_nop_();

_nop_();

_nop_();

CY=SDA; //因为返回值总是放在CY中的

SCL=0;

return(CY);

}

/***************对I2C总线产生应答*******************/

void I2CACK(void)

{

SDA=0;

SCL=1;

_nop_();

_nop_();

_nop_();

_nop_();

SCL=0;

_nop_();

SDA=1;

}

/*****************不对I2C总线产生应答***************/

void I2CNoAck(void)

{

SDA=1;

SCL=1;

_nop_();

_nop_();

_nop_();

_nop_();

SCL=0;

}

/*******************向I2C总线写数据*********************/

void I2CSendByte(unsigned char sendbyte)

{

unsigned char data j=8;

for(;j》0;j--)

{

SCL=0;

sendbyte《《=1; //无论C51怎样实现这个操作,始终会使CY=sendbyte^7;

SDA=CY;

SCL=1;

}

SCL=0;

}

/**********************从I2C总线上读数据子程序**********/

unsigned char I2CReceiveByte(void)

{

register receivebyte,i=8;

SCL=0;

while(i--)

{

SCL=1;

receivebyte=(receivebyte《《1)|SDA;

SCL=0;

}

return(receivebyte);

}

/***************一个简单延时程序************************/

void Delay(unsigned char DelayCount)

{

while(DelayCount--);

}

void main()

{

// unsigned int i;

//unsigned char j[32];

unsigned char *pa,*pb,temp=0;

unsigned char a[8]={5,6,7,8,9,10,11,12};

unsigned char b[8]={0,0,0,0,0,0,0,0};

pa=&a[0];

pb=&b[0];

P2_7=0;

RW24XX(pa,8,0x0,writeI2C,M2401);

RW24XX(pa,8,0x20,writeI2C,M2401);

RW24XX(pb,8,0x20,readI2C,M2401);

RW24XX(pb,8,0x30,writeI2C,M2401);

// RW24XX(unsigned char *DataBuff,unsigned char ByteQuantity,unsigned int Address,

// unsigned char ControlByte,enum eepromtype EepromType)

while(1)

{

P2_7=1;

}

}


文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>