I'm working with a AT24C04 EEPROM which communicates with a LPC1768 MCU on a I2C bus.

I try to write a 8 bit data (0xF0) on the 0x00 Address of the memory but when I want to read the content of this address, EEPROM returns 0xFF instead of 0xF0 which means nothing is written on this address.

It seems I have no problem in reading the EEPROM but there is something wrong with write operation.

My compiler is uVision v5.28 and here is my code:

uint8_t DeviceAddress = 0x50;
uint8_t TxBufferByteWrite[2]={0x00,0xF0};   
uint8_t RxBuffer[1];    

I2C_Init(LPC_I2C1, 100000);

//Byte Write    
I2CTransferConfig.sl_addr7bit = DeviceAddress;
I2CTransferConfig.tx_data = TxBufferByteWrite;
I2CTransferConfig.tx_length = sizeof(TxBufferByteWrite);
I2CTransferConfig.rx_data = NULL;
I2CTransferConfig.rx_length = 0;
I2CTransferConfig.retransmissions_max = 3;
I2C_MasterTransferData(LPC_I2C1, &I2CTransferConfig, I2C_TRANSFER_POLLING);     

//Current Address Read
I2CTransferConfig.sl_addr7bit = DeviceAddress;
I2CTransferConfig.tx_data = NULL;
I2CTransferConfig.tx_length = 0;    
I2CTransferConfig.rx_data = RxBuffer;
I2CTransferConfig.rx_length = sizeof(RxBuffer);
I2CTransferConfig.retransmissions_max = 3;
I2C_MasterTransferData(LPC_I2C1, &I2CTransferConfig, I2C_TRANSFER_POLLING); 

if( RxBuffer[0]==0xF0)
PrintS("Memory Working");

Thanks in advance.

  • \$\begingroup\$ I don't see that you set the write bit in I2CTransferConfig.sl_addr7bit (like DeviceAddress<<1 && 0x0). Is that done somehow behind the scenes in I2C_MasterTransferData? See Page 11 of the AT24C04 datasheet (Figure 8). \$\endgroup\$ Nov 1, 2019 at 18:42
  • \$\begingroup\$ @ChrisKnudsen, the fact they call the variable addr7bit implies they want the 7-bit I2C address (which doesn't include the W/R bit), and the library code will take care of shifting and inserting the W/R bit depending on the requested operation. \$\endgroup\$
    – The Photon
    Nov 1, 2019 at 18:51
  • \$\begingroup\$ @ThePhoton I'm probably over-looking it, but where is that specified in the code that's shown (write vs read)? "I2CTransferConfig.tx_data = NULL;"? \$\endgroup\$ Nov 1, 2019 at 19:10
  • \$\begingroup\$ @ChrisKnudsen yes, assigning NULL to I2CTransferConfig.tx_data means we want to have Read operation only and vise versa. also if non of them are NULL, it means we want to do both Read and Write which I need to do for 'Random Read' (as ThePhoton mentioned in his answer) \$\endgroup\$
    – Nima
    Nov 1, 2019 at 19:58

1 Answer 1


After your write operation, you should check that the EEPROM ACK'ed to be sure the write operation was successful.

Your write operating incremented the EEPROM's address pointer to 0x01. From the Atmel datasheet for your EEPROM:

The internal data word address counter maintains the last address accessed during the last read or write operation, incremented by one.

Therefore, when you do the read operation, you read from address 0x01, not from 0x00 where you just wrote to.

Before your read operation, you should do a one-byte write operation to set the read pointer back to 0x00.

Again from your datasheet:

RANDOM READ: A random read requires a “dummy” byte write sequence to load in the data word address. Once the device address word and data word address are clocked in and acknowledged by the EEPROM, the microcontroller must generate another start condition. The microcontroller now initiates a current address read by sending a device address with the read/write select bit high.

  • 2
    \$\begingroup\$ Indeed, read will fail if the chip is still busy with internal write cycle. Max write cycle time 5ms. So at least 5ms should be waited, either blindly, or actively polling for chip answering with ACK to know when chip is ready for use again. \$\endgroup\$
    – Justme
    Nov 1, 2019 at 19:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.