24c32 eeprom with AT89c52

hi friends, this is my very first post in this forum. I'm trying to interface a 32Kbits EEprom 24c32 with AT89c52, but i'm not able to achieve the goal. I found this code for 24c256 EEPROM on net which i'm using, but i think there should'nt be a difference for 24c32.

//---------------------------------------
// 24LC256 I2C EEPROM driver
// http://www.GetMicro.com
//---------------------------------------
#include<reg8252.h>
#include<intrins.h>
#

#define ACK     1
#define NO_ACK  0


unsigned char i;


sbit SDA  =  P2^1;      // connect to SDA pin (Data)
sbit SCL  =  P2^0;      // connect to SCL pin (Clock)



//-------------------------------
// start I2C
//-------------------------------
void Start(void)
{
    SDA = 1;
        SCL = 1;
        _nop_();_nop_();
        SDA = 0;
        _nop_();_nop_();
        SCL = 0;
        _nop_();_nop_();
}

//-------------------------------
// stop I2C
//-------------------------------
void Stop(void)
{
        SDA = 0;
        _nop_();_nop_();
        SCL = 1;
        _nop_();_nop_();
        SDA = 1;
}

//-------------------------------
// Write I2C
//-------------------------------
void WriteI2C(unsigned char Data)
{

        for (i=0;i<8;i++)
        {
        SDA = (Data & 0x80) ? 1:0;
                SCL=1;SCL=0;
                Data<<=1;
        }

        SCL = 1;
        _nop_();_nop_();
        SCL = 0;

}

//-------------------------------
// Read I2C
//-------------------------------
unsigned char ReadI2C(bit ACK_Bit)
{

    unsigned char Data=0;

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

        if (ACK_Bit == 1)
        SDA = 0; // Send ACK
        else
        SDA = 1; // Send NO ACK

        _nop_();_nop_();
        SCL = 1;
        _nop_();_nop_();
        SCL = 0;

        return Data;
}

//-------------------------------
// Read 1 byte form I2C
//-------------------------------
unsigned char ReadBYTE(unsigned int Addr)
{
        unsigned char Data;
        Start();
        WriteI2C(0xA0);
        WriteI2C((unsigned char)(Addr>>8)&0xFF);
        WriteI2C((unsigned char)Addr&0xFF);
        Start();
        WriteI2C(0xA1);
        Data = ReadI2C(NO_ACK);
        Stop();
        return(Data);
}

//-------------------------------
// Write 1 byte to I2C
//-------------------------------
void WriteBYTE(unsigned int Addr,unsigned char Data)
{
        Start();
        WriteI2C(0xA0);
        WriteI2C((unsigned char)(Addr>>8)&0xFF);      // send address high
        WriteI2C((unsigned char)Addr&0xFF);                 // send address low
        WriteI2C(Data);
        Stop();
}



Please help me out.

Thanks

With best regards
Neelam

Parents
  • Hi,

    At the very least I would add a few _nop_(); in your ReadI2C and WriteI2C routines between all changes to SDA and SCL lines because - unless you are using a very slow processor XTAL - you will probably be toggling the lines at >400kHz for 'High Speed' I2C and most definitly >100kHz for the 'standard' I2C.

    So check your processors XTAL so you can work out how long it takes to execute a nop instruction then check the I2C timing requirements and add (more than) enough nops to bring the I2C bus timings into spec.

    Mark.

Reply
  • Hi,

    At the very least I would add a few _nop_(); in your ReadI2C and WriteI2C routines between all changes to SDA and SCL lines because - unless you are using a very slow processor XTAL - you will probably be toggling the lines at >400kHz for 'High Speed' I2C and most definitly >100kHz for the 'standard' I2C.

    So check your processors XTAL so you can work out how long it takes to execute a nop instruction then check the I2C timing requirements and add (more than) enough nops to bring the I2C bus timings into spec.

    Mark.

Children
No data
More questions in this forum