embeddedstm32eeprom

AT24C04 EEPROM Byte write


I am using AT24C04 or AT24C16 using STM32 MCU with STM32CubeIDE for data storage. I am trying to write an address 256, but in both the IC the data gets collapsed or unable to write properly.

For the better understanding I have attached the debugging image: enter image description here

What is the solution?


Solution

  • The AT24C04 device has 512 * 8 bits, requiring a 9-bit data word address, but the address word is only 8-bit. The most significant bit of the address is conveyed in the bit 1 of the Device Address Byte. Effectively the device is addressed as if it were two separate 256 x 8 bit EEPROMs with addresses 0xA0 and 0xA2 (assuming A1 and A2 pins are tied low), as indicated in the datasheet

    ![enter image description here

    So to write to data word address offset 256 (byte zero of the upper page) for example:

    HAL_I2C_Mem_Write( &hi2c2, EEPROM_WRITE_ADDRESS | A8_BIT, 0,
                       I2C_MEMADD_SIZE_8BIT, datawd, 6, 100 );
    

    Where A8_BIT has value 0x02u.

    Similarly to write to address 256:

    HAL_I2C_ Mem Read( &hi2c2, EEPROM_READ_ADDRESS | A8_BIT, 0,
                       I2C_MEMADD_SIZE_8BIT, datar2, 6, 100 ) ;
    

    No substitute for actually reading and understanding the datasheet. You would do well to wrap all this into an EEPROM read/write interface will deal with all this transparently given a 9-bit address and deal with writes spanning the page boundary by issuing two separate writes.

    AT24C16 is similar but has an 11-bit data word address, with the three most-significant address bits (page address 0 to 7) in the device address byte: enter image description here So in this case the device addresses for each page are:

    Where page address is 0 to 7 and can be determined from the data word address by:

    The AT24C16 does not have external I2C address pins.

    The same expressions can be used for AT24C04 of course, only page_address would be 0 or 1, with a data_word_address mask of 0x10. Though the mask is not critical if all data_word_address values are in range for the specific EEPROM - making it easier to write one driver for both EEPROMs (and AT24C08).

    There are other caveats with both devices that you need to be aware of such as you cannot cannot write more than 16 bytes consecutively in a single I2C transaction, and cannot write consecutive bytes spanning a 256 byte page boundary. All compelling reasons for writing an EEPROM agnostic API rather than direct I2C HAL access, to make all that transparent.


    To explain the debugger output, I suspect that the invalid address 256 (0x100) becomes an 8-bit address 0x01 (the most significant byte is interpreted as the 8-bit address), so you are reading the page 0 data, starting from the second byte.

    The reason why the read from data word 16 is offset I am less certain about, but in both cases using a 16-bit data word address when the device only accepts 8-bits is not going to help - it does not really need any explanation since it is clearly an invalid transaction for this device, so you would not expect correct results.