I2C读写EEPROM程序

[ 2006-5-23 9:34:00 | By: ly_zw ]

#i nclude <reg51.h>
#i nclude <intrins.h>
#define uchar  unsigned char
#define uint  unsigned int

sbit SDA=P0^4;
sbit SCL=P0^5;
sbit P0_0=P0^0;               //
void  delay()
{
   _nop_();  
   _nop_();
   _nop_();
   _nop_();
   _nop_();
}

void delayms(uint dlycnt)
{
  uint i;
  for(;dlycnt>0;dlycnt--)
     {
       for(i=0;i<124;i++)
       {;}
     }
 
}

void  Start()       //SCL为高时,SDA由高到低的变化就是一个起始状态
{
  SCL=0;
  _nop_();
  SDA=1;
  _nop_();
  SCL=1;
  delay();
  SDA=0;
  delay();
  SCL=0;
  _nop_();
}
void  Stop()       //SCL为高时,SDA由低到高的变化就是一个起始状态
{
  SDA=0;
  _nop_();
  SCL=1;
  _nop_();
  SDA=1;
  delay();
  SCL=0;
  _nop_();
}

void  SendByte(uchar SData)     //发送数据SCL为低时数据SDA改变,SCL为高时发送
{
  uchar j;
  for(j=0;j<8;j++)
  {
     SCL=0;
     SData<<=1;
     SDA=CY;
     SCL=1;
     delay();
  }
  SCL=0;
}
uchar ReceiveByte()        //接收数据
{
   uchar i;
   uchar RData;
   RData=0;

   for(i=0;i<8;i++)
   { 
      SDA=1;
      _nop_();
      SCL=1;
      _nop_();
      _nop_();
      RData=RData<<1;
      RData=RData|SDA;
      _nop_();
      _nop_();
      SCL=0;
    }
   return(RData);
}

bit  ReceiveAck()                    //主机接收应答信号
{
  bit Ack;
  SDA=1;                 
  _nop_();
  _nop_();
  SCL=1;          
  _nop_();
  _nop_();
  Ack=SDA;
  _nop_();
  _nop_();
  SCL=0;
  _nop_();
  return(Ack);
}
void SendAck()
{
  SDA=0;
  _nop_();
  _nop_();
  SCL=1;
  delay();         
  SCL=0;
  _nop_();
  _nop_();
}

void SendNoAck()
{
  SDA=1;
  _nop_();
  _nop_();
  SCL=1;
  delay();  
  SCL=0;
  _nop_();
  _nop_();
}
void SendToSubAddress(uchar SlaveAddress,uchar SubAddress,uchar *pSData,uchar N)
{
  uchar i;
  Start();
  SendByte(SlaveAddress);    //选择器件地址
  ReceiveAck();
  SendByte(SubAddress);    //发送字地址
  ReceiveAck();

  for(i=0;i<N;i++)
  {
    SendByte(pSData[i]);
    ReceiveAck();
  }
  Stop();
}
void ReceiveFromSubAddress(uchar SlaveAddress,uchar SubAddress,uchar *pRData,uchar N)
{
  uchar i;
  Start();
  SendByte(SlaveAddress);    //发送器件地址
  ReceiveAck();
  SendByte(SubAddress);    //发送字地址
  ReceiveAck();
  Start();                              //I2C 开始
  SendByte(SlaveAddress+1);    //读设备
  ReceiveAck();
  for(i=0;i<N-1;i++)
  {
     pRData[i]=ReceiveByte();
     SendAck();
  }
  pRData[i]=ReceiveByte();
  SendNoAck();
  Stop();
}

main()
{
  uint i;
  uchar *pData;
  uchar a[16]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
  uchar b[16];
  pData=a;
  SendToSubAddress(0xA0,0,pData,16);
  delayms(1);
  ReceiveFromSubAddress(0xA0,0x20,pData,16);
  delayms(1);
  for(i=0;i<17;i++)
  {
    P0_0=0;
    if(a[i]!=*pData)
      P0_0=1;
    pData++;
  }
}

Re:I2C读写EEPROM程序

[ 2008-5-3 20:03:00 | By: arm_uclinux(游客) ]
请教在这个程序里receiveack()的作用是什么?
是不是没有处理应答信号!谢谢!
我的信箱是arm_uclinux@163.com
个人主页 | 引用 | 返回 | 删除 | 回复

Re:I2C读写EEPROM程序

[ 2008-5-13 21:15:00 | By: LTO(游客) ]
你好,谢谢你的资料,不过在函数void sendbyte(uchar sdata) 里的cy是指什么呢 ?可否讲解一下?我已经收藏了你空间的地址了
个人主页 | 引用 | 返回 | 删除 | 回复

Re:I2C读写EEPROM程序

[ 2008-5-31 17:38:00 | By: 求经者(游客) ]
多谢您无私共享.
个人主页 | 引用 | 返回 | 删除 | 回复

Re:I2C读写EEPROM程序

[ 2008-9-7 19:56:00 | By: 文文(游客) ]
tms28332与at24c08通讯编程i2c实现
个人主页 | 引用 | 返回 | 删除 | 回复

Re:I2C读写EEPROM程序

[ 2008-10-12 2:07:00 | By: GuoHui(游客) ]
请问receivefromsubaddress(0xa0,0x20,pdata,16);,为什么要用0x20?而不是0?
个人主页 | 引用 | 返回 | 删除 | 回复

发表评论:

    大名:
    密码: (游客无须输入密码)
    主页:
    标题:
    正在载入数据,请稍候……