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

电子说

1.2w人已加入

描述

  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;

  }

  }

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分