EEPROM 读写驱动 (AT24C256 , C8051F020)

zsxx   2009-7-2 21:58 楼主
MCU是 8051F020  ,,,,, EEPROM 是AT24C256

当初设计板子没注意, 结果SDA用的P45 ,SCL用的P46 。 因为P4口不能按位寻址,所以SDA和SCL都是用直接操作,很麻烦。
比如SDA = 1 就要写成P4 = P4 | 0x20 了。 所以把同学用的程序(AT89C52上调试通过的程序,用P3口调试的,比如P3 = P3 | 0x20 )改写了下,但是再自己的MCU上就是读取不成功。郁闷了2天了 ,说请高手看下,希望能有意见。谢谢!




/////////////////////////////////////
//  Generated Initialization File  //
/////////////////////////////////////

#include "C8051F020.h"
#include "INTRINS.H"

// Peripheral specific initialization functions,
// Called from the Init_Device() function
void Reset_Sources_Init()
{
    WDTCN     = 0xDE;
    WDTCN     = 0xAD;
}

void Oscillator_Init()
{
    int i = 0;
    OSCXCN    = 0x67;
    for (i = 0; i < 3000; i++);  // Wait 1ms for initialization
    while ((OSCXCN & 0x80) == 0);
    OSCICN    = 0x08;
}

// Initialization function for device,
// Call Init_Device() from your main program
void Init_Device(void)
{
    Reset_Sources_Init();
    Oscillator_Init();
}
//////////////////////////////以上部分是MCU的初始化,晶振的设置,关看门狗。



#include "INTRINS.H"
#define unchar unsigned char
#define unint unsigned int
#define uchar unsigned char
#define uint unsigned int
#define unlong unsigned long

data bank0=0x00 , addr=0x00 ;
uchar FromIIC = 0 , FromIIC2 ;
uchar pp ;

bit ISDA , ISCL ;

//*************** 端口分配 SDA=>P45 ; SCL=>P46 ; WP=>P47*************************/
/********************************************************************************  
        ISDA = 1 <===>  P4 = P4 | 0x20 ;           ISDA = 0  <===>  P4 = P4 & 0xDF ;
        ISCL = 1 <===>  P4 = P4 | 0x40 ;           ISCL = 0  <===>  P4 = P4 & 0xBF ;
*******************************************************************************/

/*****************************延时程序****************************************/
void delay_ms (uint ms)
{
  uint i,j;
  for(i=0;i   for(j=0;j<1000;j++)
  ;
}


//-----------EEPROM读写模块开始-----------------------------------------------
//=============================================

//Wait for some time to get proper I2C timing                 //EEPROM 开始
void I2cWait (void)
{
  _nop_();
  _nop_();
}
/*=============================================
I2c start condition
SDA high->low while SCL=high
=============================================*/
void I2cStart(void)
{
  P4 = P4 | 0x20 ;                //ISDA = 1;
  P4 = P4 | 0x40 ;                //ISCL = 1;
  I2cWait();
  P4 = P4 & 0xDF ;                //ISDA = 0;
  I2cWait();
  P4 = P4 & 0xBF ;                //ISCL = 0;
}
/*=============================================
I2c stop condition
SDA low->high while SCL=high
=============================================*/
void I2cStop(void)
{
  P4 = P4 & 0xDF ;                //ISDA = 0;
  I2cWait();
  P4 = P4 | 0x40 ;                //ISCL = 1;
  I2cWait();
  P4 = P4 | 0x20 ;                //ISDA = 1;
}
//master transfer data to slave and return acknowledge bit
bit I2cSentByte(uchar bytedata)
{
  uchar i;
  bit ack;

  P4 = P4 | 0x20 ;                //ISDA = 1;
  for(i=0; i<8; i++)
  {
        bytedata = _crol_(bytedata, 1);
        if(bytedata & 0x01)
          P4 = P4 | 0x20 ;            //ISDA = 1;
        else
          P4 = P4 & 0xDF ;            //ISDA = 0;
          
        P4 = P4 | 0x40 ;              //ISCL = 1;
        I2cWait();
        P4 = P4 & 0xBF ;              //ISCL = 0;
        I2cWait();
  }
  P4 = P4 | 0x20 ;                //ISDA = 1;
  I2cWait();
  P4 = P4 | 0x40 ;                //ISCL = 1;
  I2cWait();
  ack =  P4 & 0x20 ;              //ack = ISDA;
  P4 = P4 & 0xBF ;                //ISCL = 0;
  I2cWait();
  return ack;
}

//slave transfer data to master
uchar I2cReceiveByte(void)
{
  uchar i, bytedata = 0;
  
  //Receive byte (MSB first)
  for(i=0; i<8; i++)
  {
    P4 = P4 | 0x40 ;                //ISCL = 1;
        I2cWait();
       
        bytedata <<= 1;
        ISDA = P4 & 0x20 ;
        if ( ISDA ) bytedata |= 0x01;   ///////////

        P4 = P4 & 0xBF ;                //ISCL = 0;
        I2cWait();
  }
  return bytedata;
}

//Master send acknowledge bit to slave
//acknowledge="0",non-acknowledge="1"
void SendAcknowledge (bit ack)
{
  //ISDA = ack
  if ( ack )
    P4 = P4 | 0x20 ;               //ISDA = 1 ;
  else
    P4 = P4 & 0xDF ;               //ISDA = 0 ;
  P4 = P4 | 0x40 ;                 //ISCL = 1;
  I2cWait();
  P4 = P4 & 0xBF ;                 //ISCL = 0;
}


//do 1 times, and un-check acknowledge
void I2cByteWrite(uchar device, uchar address, uchar bytedata)
{
  I2cStart();
  I2cSentByte (device);
  I2cSentByte (address);
  I2cSentByte (bytedata);
  I2cStop();
  delay_ms(10);
}
uchar I2cByteRead(uchar device, uchar address)
{
  uchar bytedata;

  I2cStart();
  I2cSentByte(device);
  I2cSentByte(address);
  I2cStart();
  //  I2cSentByte (device|0x01);
  I2cSentByte(device+0x01);
  bytedata = I2cReceiveByte();
  SendAcknowledge(1);
  I2cStop();
  return bytedata;
}


//Write byte data into EEPROM
void EEPROMByteWrite0(uchar bank, uchar addr, uchar value)        //bank,addr->地址,value->所写值
{
  I2cByteWrite((0xA0|bank), addr, value);
}
void  EEPROMDataWrite(uchar bank, uchar addr, uchar *dat, uchar n)        //写数组
{
  uchar i;
  for(i=0x00;i           EEPROMByteWrite0( bank,  addr+i,*(dat+i));
}
//Read byte data from EEPROM
uchar EEPROMByteRead0(uchar bank, uchar addr)                //bank,addr->地址
{
  return(I2cByteRead((0xA0|bank), addr));
}
void  EEPROMDataRead(uchar bank, uchar addr, uchar *dat, uchar n)        //读数组
{
  uchar i;
  for(i=0x00;i           *(dat+i)=EEPROMByteRead0(bank,addr+i);
}
//-----------EEPROM读写模块结束-----------------------------------------------



void main ()
{
        Init_Device();
        pp = 2 ;
        P4 = 0x00 ;
               
        while ( 1 )
        {
                delay_ms ( 1000 ) ;   //调试用的看P4口是不是通的
                P4 = P4 | 0x01  ;     //调试用的看P4口是不是通的
                delay_ms ( 1000 ) ;
                P4 = P4 & 0xFE  ;
                delay_ms ( 1000 ) ;

                EEPROMByteWrite0 ( bank0 , 0x00 + addr , pp ) ;  //写
                FromIIC  = EEPROMByteRead0( bank0 , addr) ;    //总是读出来的255 ,而不是2
        }

}

回复评论 (10)

人家的用的是C52,你用的8051,速度都不一样,能直接用吗,插入点延时
点赞  2009-7-3 09:29
//master transfer data to slave and return acknowledge bit
bit I2cSentByte(uchar bytedata)
{
  
   for(i=0; i <8; i++)
  {

  }
  P4 = P4 | 0x20 ;                //ISDA = 1;
  I2cWait();
  P4 = P4 | 0x40 ;                //ISCL = 1; // 这里为什么还要送一个bit出去?  
  I2cWait();
  ack =  P4 & 0x20 ;              //ack = ISDA;
  P4 = P4 & 0xBF ;                //ISCL = 0;
  I2cWait();
  return ack;
}


如果你读回的是255,也就是0xff, 说明根本没有写成功。
点赞  2009-7-3 09:40
应该有速度不一样 ,但是等几秒总会写进去吧
但是都没有成功!
点赞  2009-7-3 09:45
引用: 引用 2 楼 zyzhang365 的回复:
//master transfer data to slave and return acknowledge bit
bit I2cSentByte(uchar bytedata)
{
  
  for(i=0; i <8; i++)
  {

  }
  P4 = P4 | 0x20 ;                //ISDA = 1;
  I2cWait();
  P4 = P4 | 0x40 ;                //ISCL = 1; // 这里为什么还要送一个bit出去?  
  I2cWait();
  ack =  P4 & 0x20 ;              //ack = ISDA;
  P4 = P4 & 0xBF ;                //ISCL = 0;


我也觉得是没写进去 ,感觉是8051F020设置的问题。    EEPROM读写的时序应该没问题,程序测试过可以读写。
点赞  2009-7-3 09:53
引用: 引用 2 楼 zyzhang365 的回复:
..................


下面是在同学的AT89C52上测试的程序,只是把P4口改成P3,其他都没改动,AT89C52上测试时通过的,可以读出来。
AT89C52的P3口可以按位寻址,但是为了测试我的程序,改成了字节操作


///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include "reg52.h"
#include
#define unint unsigned int
#define uchar unsigned char
#define uint unsigned int
#define unlong unsigned long

bit ISDA , ISCL ;
data bank0=0x00 , bank1=0x01 , addr=0x00 ;
uchar FromIIC = 0 ;
uchar pp ;

//*************** 端口分配 SDA=>P37 ; SCL=>P36 *************************/
/********************************  
        ISDA = 1  P3 = P3 | 0x80 ;
        ISDA = 0  P3 = P3 & 0x7F ;
        ISCL = 1  P3 = P3 | 0x40 ;
        ISCL = 0  P3 = P3 & 0xBF ;
********************************/

/*****************************延时程序****************************************/
void delay_ms (uint ms)
{
  uint i,j;
  for(i=0;i   for(j=0;j<1000;j++)
  ;
}


//-----------EEPROM读写模块开始-----------------------------------------------
//=============================================

//Wait for some time to get proper I2C timing                 //EEPROM 开始
void I2cWait (void)
{
  _nop_();
  _nop_();
}
/*=============================================
I2c start condition
SDA high->low while SCL=high
=============================================*/
void I2cStart(void)
{
  P3 = P3 | 0x80 ;                //ISDA = 1;
  P3 = P3 | 0x40 ;                //ISCL = 1;
  I2cWait();
  P3 = P3 & 0x7F ;                //ISDA = 0;
  I2cWait();
  P3 = P3 & 0xBF ;                //ISCL = 0;
}
/*=============================================
I2c stop condition
SDA low->high while SCL=high
=============================================*/
void I2cStop(void)
{
  P3 = P3 & 0x7F ;                //ISDA = 0;
  I2cWait();
  P3 = P3 | 0x40 ;                //ISCL = 1;
  I2cWait();
  P3 = P3 | 0x80 ;                //ISDA = 1;
}
//master transfer data to slave and return acknowledge bit
bit I2cSentByte(uchar bytedata)
{
  uchar i;
  bit ack;

  P3 = P3 | 0x80 ;                //ISDA = 1;
  for(i=0; i<8; i++)
  {
        bytedata = _crol_(bytedata, 1);
        if(bytedata & 0x01)
          P3 = P3 | 0x80 ;            //ISDA = 1;
        else
          P3 = P3 & 0x7F ;            //ISDA = 0;
          
        P3 = P3 | 0x40 ;              //ISCL = 1;
        I2cWait();
        P3 = P3 & 0xBF ;              //ISCL = 0;
        I2cWait();
  }
  P3 = P3 | 0x80 ;                //ISDA = 1;
  I2cWait();
  P3 = P3 | 0x40 ;                //ISCL = 1;
  I2cWait();
  ack =  P3 & 0x80 ;              //ack = ISDA;
  P3 = P3 & 0xBF ;                //ISCL = 0;
  I2cWait();
  return ack;
}

//slave transfer data to master
uchar I2cReceiveByte(void)
{
  uchar i, bytedata = 0;
  
  //Receive byte (MSB first)
  for(i=0; i<8; i++)
  {
    P3 = P3 | 0x40 ;               //ISCL = 1;
        I2cWait();
       
        bytedata <<= 1;
        ISDA = P3 & 0x80 ;
        if ( ISDA ) bytedata |= 0x01;   //////////////////////

        P3 = P3 & 0xBF ;                //ISCL = 0;
        I2cWait();
  }
  return bytedata;
}

//Master send acknowledge bit to slave
//acknowledge="0",non-acknowledge="1"
void SendAcknowledge (bit ack)
{
  //ISDA = ack
  if ( ack )
    P3 = P3 | 0x80 ;               //ISDA = 1 ;
  else
    P3 = P3 & 0x7F ;               //ISDA = 0 ;
  P3 = P3 | 0x40 ;                 //ISCL = 1;
  I2cWait();
  P3 = P3 & 0xBF ;                 //ISCL = 0;
}


//do 1 times, and un-check acknowledge
void I2cByteWrite(uchar device, uchar address, uchar bytedata)
{
  I2cStart();
  I2cSentByte (device);
  I2cSentByte (address);
  I2cSentByte (bytedata);
  I2cStop();
  delay_ms(10);
}
uchar I2cByteRead(uchar device, uchar address)
{
  uchar bytedata;

  I2cStart();
  I2cSentByte(device);
  I2cSentByte(address);
  I2cStart();
  //  I2cSentByte (device|0x01);
  I2cSentByte(device+0x01);
  bytedata = I2cReceiveByte();
  SendAcknowledge(1);
  I2cStop();
  return bytedata;
}


//Write byte data into EEPROM
void EEPROMByteWrite0(uchar bank, uchar addr, uchar value)        //bank,addr->地址,value->所写值
{
  I2cByteWrite((0xA0|bank), addr, value);
}
void  EEPROMDataWrite(uchar bank, uchar addr, uchar *dat, uchar n)        //写数组
{
  uchar i;
  for(i=0x00;i           EEPROMByteWrite0( bank,  addr+i,*(dat+i));
}
//Read byte data from EEPROM
uchar EEPROMByteRead0(uchar bank, uchar addr)                //bank,addr->地址
{
  return(I2cByteRead((0xA0|bank), addr));
}
void  EEPROMDataRead(uchar bank, uchar addr, uchar *dat, uchar n)        //读数组
{
  uchar i;
  for(i=0x00;i           *(dat+i)=EEPROMByteRead0(bank,addr+i);
}
//-----------EEPROM读写模块结束-----------------------------------------------


void main ()
{
//        Init_Device();
        pp = 2 ;
        P3 = 0x00 ;
               
while(1){
        EEPROMByteWrite0 ( bank0 , 0x00 + addr , pp ) ;
        FromIIC = EEPROMByteRead0( bank0 , addr) ;}

}

下面是在同学的AT89C52上测试的程序,只是把P4口改成P3,其他都没改动,AT89C52上测试时通过的,可以读出来。
AT89C52的P3口可以按位寻址,但是为了测试我的程序,改成了字节操作

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
点赞  2009-7-3 10:22
你用的单片机资料我没有找到,你如果能确认P4口已经能输入输出了,就可以了。
请将各函数按如下方式修改。然后试验一下。如果编译不过去,有可能是网页导致的格式不正确,请理解意思自己修改就可以了。
另看最后的说明。如果仍然解决不了你的问题,那么请再仔细阅读EEPROM的时序图,查看一下时序,和你的延时时间。最主要是要理解过程。
另,请不要认为别人的程序都是对的,因为有时候环境不一样,或者考虑不周全,包括我写的这些。


void I2cStart(void)
{
  P4 = P4 | 0x20 ;                //ISDA = 1;
  P4 = P4 | 0x40 ;                //ISCL = 1;
  I2cWait();
  P4 = P4 & 0xDF ;                //ISDA = 0;
  I2cWait();
  P4 = P4 & 0xBF ;                //ISCL = 0;
  I2cWait();                         //这个是我加的 090703
}

//应该在函数后边加 SCL=0;。
void I2cStop(void)
{
  P4 = P4 & 0xDF ;                //ISDA = 0;
  P4 = P4 | 0x40 ;                //ISCL = 1;
  I2cWait();
  P4 = P4 | 0x20 ;                //ISDA = 1;
  P4 = P4 & 0xBF ;                //ISCL = 0; 这个是我加的 090703
  I2cWait();                           //这个是我加的 090703
}

bit I2cSentByte(uchar bytedata)
{
  uchar i;
  bit ack;

  P4 = P4 | 0x20 ;                //ISDA = 1;
  for(i=0; i <8; i++)
  {
        //*******请确认这段代码是将数据按从高到低发送,因为我不知道_crol_()这个函数的作用
        bytedata = _crol_(bytedata, 1);
        if(bytedata & 0x01)
          P4 = P4 | 0x20 ;            //ISDA = 1;
        else
          P4 = P4 & 0xDF ;            //ISDA = 0;
        //*******请确认上边代码是将数据按从高到低发送,因为我不知道_crol_()这个函数的作用
  

        P4 = P4 | 0x40 ;              //ISCL = 1;
        I2cWait();
        P4 = P4 & 0xBF ;              //ISCL = 0;
        I2cWait();
  }

  //P4 = P4 | 0x20 ;                //ISDA = 1; 这个是我去掉的 090703
  I2cWait();
  P4 = P4 | 0x40 ;                //ISCL = 1;
  I2cWait();

  //ack =  P4 & 0x20 ;              //ack = ISDA;  这个是我去掉的 090703
  while( (P4 & 0x20) == 0x20){}          //我加的,等待回复ACK 有可能导致死循环。090703
  P4 = P4 & 0xBF ;                //ISCL = 0;
  I2cWait();
  return ack;
}

uchar I2cByteRead(uchar device, uchar address)
{
  uchar bytedata;

  I2cStart();
  I2cSentByte(device);
  I2cSentByte(address);
  I2cStart();
  //  I2cSentByte (device|0x01);
  I2cSentByte(device+0x01);
  bytedata = I2cReceiveByte();
  //SendAcknowledge(1);         // 这个是我去掉的 090703
  I2cStop();
  return bytedata;
}

uchar I2cReceiveByte(void)
{
  uchar i, bytedata = 0;
  
  //Receive byte (MSB first)
  for(i=0; i <8; i++)
  {
        P4 = P4 | 0x40 ;                //ISCL = 1;
        I2cWait();
        //bytedata < <= 1; //这句话能编译过去吗 <<中间有空格
        bytedata <<= 1; // 我修改的。090703
        ISDA = P4 & 0x20 ;
        if ( ISDA ) bytedata |= 0x01;  ///////////
        P4 = P4 & 0xBF ;                //ISCL = 0;
        I2cWait();
  }
  return bytedata;
}

I2C总线注意事项:
1,要区分什么时候是读操作,什么时候是写操作。比如随机读(目前的程序是随机读),只有读数据周期是读操作,其他几个周期都是写操作。
2,要区分ACK信号由谁发出的。当读的时候,ACK信号由MCU->eeprom  SDA输出。当写的时候ACK信号由eeprom->MCU SDA输入。
3,在一帧操作中(例如一个完整的读字节或写字节),有全写的操作,但是没有全读的操作
4,当写完一个字节的时候,或写完一个页(8字节),必须要有延时,否则其他操作不能进行
5,一定要严格遵守时序(顺序,不是时间长短),否则会出错。比如连续读时,最后一个字节是没有ACK位的,如果MCU发出去了,则后边的操作会出错。
6,延时时间可以长,但不可以短。 你可以试下,如果还不成功,可能是延时时间短了。
7,当写页操作时,必须以8的整数倍为起始地址,如果不这样,写的只是本8字节页中,最后的几个字节,剩余从头写(循环写)




点赞  2009-7-3 10:41
检查下口线是不是缺上拉电阻
EEPROMByteWrite0 ( bank0 , 0x00 + addr , pp ) ; bank0这个器件地址和EEPROM得A0,A1,(A2)是对应的?
附一个我用的程序

#include "W79E824.H"
#include
#define uint unsigned int
#define uchar unsigned char

//#define WP=0 _nop_()
//#define WP=1 _nop_()
bit flag;
#define SCL P12
sbit SDA1=P1^3;
//sbit WP=P3^4;

/*EEPROM Fuction*/
void delay(void)
{
  uchar i;
  for(i=20;i>0;i--)
  _nop_();
}
/*
void delayij(uchar i,uchar j)
{
        uchar m,n;
        for(m=0;m         {
                for(n=j;n>0;n--);  //???±124*8+10=1002us
                {
                        _nop_();
                }
        }
}
         */

/*********************************************************
**??????I2C_Start
**??????????I2C
**????????
**·???????
*********************************************************/
void I2C_Start()
{
        SDA1=1;
        delay();
        SCL=1;
        delay();
        SDA1=0;
        delay();
        SCL=0;
}

/**********************************************************
**??????I2C_Stop
**??????????I2C
**????????
**·???????
**********************************************************/
void I2C_Stop()
{
        SDA1=0;
        delay();
        SCL=1;
        delay();
        SDA1=1;
        delay();
}




/**********************************************************
**??????Ack
**??????????????
**????????
**·???????
**********************************************************/
void Ack()
{
        SDA1=0;
        delay();
        SCL=1;
        delay();
        SCL=0;
        delay();
        SDA1=1;
        delay();
}



/********************************************************
**??????NoAck
**??????·???·?????????
**????????
**·???????
********************************************************/
void NoAck()
{
        SDA1=1;
        delay();
        SCL=1;
        delay();
        SCL=0;
        delay();
        SDA1=0;
        delay();
}




/********************************************************
**??????Test_Ack()
**???????ì????????
**????????
**·?????flag,???????±flag??0?????????±flag??1
*********************************************************/
bit Test_Ack()
{
        SCL=0;
        SDA1=1;//????????
        _nop_();_nop_();_nop_();_nop_();
        SCL=1;
        _nop_();_nop_();_nop_();_nop_();
        if(SDA1==0)
                flag=1;
        else        flag=0;
        SCL=0;
        return(flag);
}



/********************************************************
**??????SendData()        
**??????·?????×???????
**??????buffer
**·?????
*******************************************************/
void SendData(uchar buffer)
{
        uchar BitCnt=8;//??×???8??
        uchar temp=0;
        do
        {
                temp=buffer;
                SCL=0;
                delay();
                if((temp&0x80)==0) //
                        SDA1=0;
                else
                        SDA1=1;
                delay();
                SCL=1;
                temp=_crol_(buffer,1);//rl buff
                buffer=temp;
                BitCnt--;
        }
        while(BitCnt);
        SCL=0;        
}

/**************************************************************
**??????uint ReceiveData()
**????????????×???????
**??????
**·?????ucReceData
**???÷????????????????·???ucReceData??
**************************************************************/
uchar ReceiveData()
{
                uchar ucReceData;
        uchar BitCnt=8;
        uchar temp=0;
        SDA1=1;//????????
        do
        {
                SCL=0;
                delay();
                SCL=1;
                delay();
                if(SDA1==1)
                        ucReceData=ucReceData|0x01;
                else
                        ucReceData=ucReceData&0x0fe;
                if(BitCnt-1)
                {
                        temp=_crol_(ucReceData,1);
                        ucReceData=temp;
                }
                BitCnt--;
        }
        while(BitCnt);
        SCL=0;
        return(ucReceData);
}

/*************************************************************
**bit WriteNByte()
**24C64???????à×???????
**
** *s-data to write   sbbab-data address 8bits low
**sla-device address  suba-data address 8bits high  n-bytes(n<=32)
**************************************************************
bit WriteNByte(uchar sla,uchar suba,uchar subab,uchar *s,uint n)
{
        uchar i;
        I2C_Start();
        SendData(sla);
        Test_Ack();
        if(flag==0)        return(0);
        SendData(suba);
        Test_Ack();
                if(flag==0)        return(0);

        SendData(subab);
        Test_Ack();
        if(flag==0)        return(0);

        for(i=0;i         {
                SendData(*(s+i));
                Test_Ack();
                if(flag==0)        return(0);
        }
        I2C_Stop();
        return(1);
}
*/
bit WriteNByte(uchar sla,uint addr,uchar *s,uint n)
{
        uchar i;
                uchar suba;
                uchar subab;
                suba=(addr>>8);
                subab=addr&0x00ff;
        I2C_Start();
        SendData(sla);
        Test_Ack();
        if(flag==0)        return(0);
        SendData(suba);
        Test_Ack();
                if(flag==0)        return(0);

        SendData(subab);
        Test_Ack();
        if(flag==0)        return(0);

        for(i=0;i         {
                SendData(*(s+i));
                Test_Ack();
                if(flag==0)        return(0);
        }
        I2C_Stop();
        return(1);
}

/*************************************************************
**bit ReadNByte()
**24C64??????N×????????¨n<=32)
**
**
**
**************************************************************
bit ReadNByte(uchar sla,uchar suba,uchar subab,uchar *p,uint n)
{
        uchar i;
        I2C_Start();
        SendData(sla);
        Test_Ack();
        if(flag==0){return(0);}
        SendData(suba);
        Test_Ack();
        if(flag==0){return(0);}

                SendData(subab);
        Test_Ack();
        if(flag==0){return(0);}

        I2C_Start();
        SendData(sla+1);
        Test_Ack();
        if(flag==0){return(0);}
        for(i=0;i         {
                *(p+i)=ReceiveData();
                Ack();
        }
        *(p+n-1)=ReceiveData();
        
        NoAck();
        I2C_Stop();
        return(1);
}
*/
bit ReadNByte(uchar sla,uint addr,uchar *p,uint n)
{
        uchar i;
                uchar suba;
                uchar subab;
                suba=(addr>>8);
                subab=addr&0x00ff;
        I2C_Start();
        SendData(sla);
        Test_Ack();
        if(flag==0){return(0);}
        SendData(suba);
        Test_Ack();
        if(flag==0){return(0);}

                SendData(subab);
        Test_Ack();
        if(flag==0){return(0);}

        I2C_Start();
        SendData(sla+1);
        Test_Ack();
        if(flag==0){return(0);}
        for(i=0;i         {
                *(p+i)=ReceiveData();
                Ack();
        }
        *(p+n-1)=ReceiveData();
        
        NoAck();
        I2C_Stop();
        return(1);
}

/*
bit ReadNByte(uchar sla,uchar suba,uchar subab,uchar *p,uint n)
{
        uchar i;
        ENS1=1;
        I2DAT=sla;
        STA=1;
        while(SI==0);
        SI=0;
//        if(AA==0)return(0);
        I2DAT=suba;
        while(SI==0);
        SI=0;
//        if(AA==0)return(0);
        I2DAT=subab;
        while(SI==0);
        SI=0;
//        if(AA==0)return(0);
        for(i=0;i         {
                while(SI==0);
                *(p+i)=I2DAT;
                SI=0;
        }
        *(p+n-1)=I2DAT;
        STO=1;
        ENS1=0;
        return(1);
}*/

/*
bit ClearROM(uchar s)
{
        uint i;
//                uchar j;
        I2C_Start();
        SendData(0xa0);
        Test_Ack();
        if(flag==0)        return(0);
        SendData(0x00);
        Test_Ack();
                if(flag==0)        return(0);

        SendData(0x00);
        Test_Ack();
        if(flag==0)        return(0);

        for(i=0;i<0x8000;i++)
        {
//                                j=i*100/0x8000;
//                                PrintNumber(36,5,j);
                SendData(s);
                Test_Ack();
                if(flag==0)        return(0);
        }
        I2C_Stop();
        return(1);
}
/*========================================*/
点赞  2009-7-3 11:36
引用: 引用 3 楼 youngbird221 的回复:
应该有速度不一样 ,但是等几秒总会写进去吧
但是都没有成功!

你怎么不拿个酷睿2去模拟I2C,一般I2C的最高速度就是400K,I2cWait就两个NOP,你算算你的时序的速度都是多少了,
C8051F的速度都是c51的十几倍,你就是等一年也写不进去
点赞  2009-7-3 12:26
把标准51的程序移植到C8051要注意IO配置...
点赞  2009-7-4 00:35
多谢各位的关注
最终问题得以解决,硬件这东西,出问题会有太多的原因
谢谢!大家
点赞  2009-7-5 10:00
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复