This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

writing to serial eeprom problem

I'm writting to AT24C128 serial eeprom as shown by the datasheet and the read command shown below works, while the write command doesn't. I wrote to the chip using external programmer and it was ok, reading from it works fine, but writting doesn't. Can anyone check this code for me ?

/******************************************************************************
* NAME: readAt *
* DESCRIPTION: This function reads a byte at a specified address *
******************************************************************************/
unsigned char readAt(unsigned int address)
{
unsigned char data1;
i2c_Start(); // make a start condition
i2c_SendAddress(ROM, 0); // 0 write 1 read
i2c_ReadAcknowledge(); // wait for acknowledge from eeprom
i2c_SendByte(address >> 8); // send upper byte of address to eeprom
i2c_ReadAcknowledge(); // wait for acknowledge from eeprom
i2c_SendByte(address & 0xff); // send lower byte of address to eeprom
i2c_ReadAcknowledge(); // wait for acknowledge from eeprom
i2c_Start(); // make a start condition
i2c_SendAddress(ROM, 1); // issue read command
i2c_ReadAcknowledge(); // wait for acknowledge from eeprom
data1 = (char)i2c_ReadByte(); // get data out of eeprom
i2c_Stop(); // finish the process
return(data1); // give data back to caller
}

/******************************************************************************
* NAME: writeAt *
* DESCRIPTION: This function writes a byte to a specified address *
******************************************************************************/
void writeAt(unsigned int addr, unsigned char data)
{
i2c_Start(); // start condition
i2c_SendAddress(ROM, 0); // 0 = write, 1 = read, ROM is 0xA0
i2c_ReadAcknowledge(); // wait for acknowledge from EEPROM
i2c_SendByte(addr >> 8); // send upper address byte
i2c_ReadAcknowledge(); // wait for acknowledge from EEPROM
i2c_SendByte(addr & 0xff); // send lower address byte
i2c_ReadAcknowledge(); // wait for acknowledge from EEPROM
i2c_SendByte(data); // write the data to EEPROM
i2c_ReadAcknowledge(); // wait for acknowledge from eeprom
i2c_Stop(); // stop
}


I connected the WP to gnd, but the chip seems not to write either for error in the datasheet or I tried to make a memory reset function as indicated by the datasheet but I still have this problem.
Thanks
Mahmood

  • Can you post the code for the i2c_Stop routine? I would kind of suspect it. You only issue it in your read command AFTER you already have the data. If it is wrong you still have your read data. On the other hand, it it is wrong in your write command, the data will not be written.

  • Mahmood had posted on the 8052.com forum as well as here and it was there that he announced that his problem was solved.

    http://www.8052.com/forum/read.phtml?id=71829

  • Yes the problem was solved by finding another library on the internet that worked.
    the reason was I had a deadline and had to finish one project in that day.
    Now since I delivered my project and earned some cash (paid it all to a mechanic to repair a major engine damage in my car haha!) I don't mind fixing the errors in this library for future use because it looks nice.
    Here is the requested code:
    void i2c_Stop(void)
    {
    /* don't assume SCL is high on entry */

    SDA_LOW(); /* ensure data is low first */
    SCL_HIGH();

    DelayUs(I2C_TM_DATA_SU);
    SCL_DIR = I2C_INPUT; /* float clock high */
    DelayUs(I2C_TM_STOP_SU);
    SDA_HIGH(); /* the low->high data transistion */
    DelayUs(I2C_TM_BUS_FREE); /* bus free time before next start */
    SDA_DIR = I2C_INPUT; /* float data high */

    return;
    }

    and here is the code for byte write
    unsigned char i2c_SendByte(unsigned char byte)
    {
    signed char i;

    for(i=7; i>=0; i--)
    {
    SCL_LOW(); /* drive clock low */
    /* data hold time = 0, send data now */
    SDA_DIR = ((byte>>i)&0x01);
    if ((byte>>i)&0x01) { /* bit to send */
    SDA_HIGH();
    }
    else {
    SDA_LOW();
    }
    DelayUs(I2C_TM_DATA_SU);
    SCL_DIR = I2C_INPUT; /* float clock high */

    if(i2c_WaitForSCL()) /* wait for clock release */
    return TRUE; /* bus error */

    DelayUs(I2C_TM_SCL_HIGH); /* clock high time */
    }


    return FALSE;
    }
    Regards
    Mahmood