La operación de lectura de EEPROM siempre devuelve 0xFF

Estoy trabajando con una EEPROM AT24C04 que se comunica con una MCU LPC1768 en un bus I2C.

Intento escribir datos de 8 bits (0xF0) en la dirección 0x00 de la memoria, pero cuando quiero leer el contenido de esta dirección, la EEPROM devuelve 0xFF en lugar de 0xF0, lo que significa que no hay nada escrito en esta dirección.

Parece que no tengo problemas para leer la EEPROM, pero hay algo mal con la operación de escritura.

Mi compilador es uVision v5.28 y aquí está mi código:

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

I2C_Init(LPC_I2C1, 100000);
I2C_Cmd(LPC_I2C1, I2C_MASTER_MODE, ENABLE); 

//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");

Gracias de antemano.

No veo que haya configurado el bit de escritura en I2CTransferConfig.sl_addr7bit (como DeviceAddress<<1 && 0x0). ¿Se hace eso de alguna manera detrás de escena en I2C_MasterTransferData? Consulte la página 11 de la hoja de datos AT24C04 (Figura 8).
@ChrisKnudsen, el hecho de que llamen a la variable addr7bitimplica que quieren la dirección I2C de 7 bits (que no incluye el bit W/R), y el código de la biblioteca se encargará de cambiar e insertar el bit W/R según el operación solicitada.
@ThePhoton Probablemente lo estoy pasando por alto, pero ¿dónde se especifica eso en el código que se muestra (escribir frente a leer)? "I2CTransferConfig.tx_data = NULL;"?
@ChrisKnudsen sí, asignar NULL a I2CTransferConfig.tx_data significa que queremos tener solo la operación de lectura y viceversa. Además, si ninguno de ellos es NULL, significa que queremos leer y escribir, lo que debo hacer para 'Lectura aleatoria' (como mencionó ThePhoton en su respuesta)

Respuestas (1)

Después de su operación de escritura, debe verificar que la EEPROM haya recibido un ACK para asegurarse de que la operación de escritura haya sido exitosa.

Su operación de escritura incrementó el puntero de dirección de la EEPROM a 0x01. De la hoja de datos de Atmel para su EEPROM:

El contador de direcciones de palabras de datos internas mantiene la última dirección a la que se accedió durante la última operación de lectura o escritura, incrementada en uno.

Por lo tanto, cuando realiza la operación de lectura, lee desde la dirección 0x01, no desde 0x00 donde acaba de escribir.

Antes de su operación de lectura, debe realizar una operación de escritura de un byte para volver a establecer el puntero de lectura en 0x00.

Nuevamente de su hoja de datos:

LECTURA ALEATORIA: una lectura aleatoria requiere una secuencia de escritura de bytes "ficticios" para cargar en la dirección de la palabra de datos. Una vez que la EEPROM registra y reconoce la palabra de dirección del dispositivo y la dirección de la palabra de datos, el microcontrolador debe generar otra condición de inicio. El microcontrolador ahora inicia una lectura de dirección actual enviando una dirección de dispositivo con el bit de selección de lectura/escritura alto.

De hecho, la lectura fallará si el chip todavía está ocupado con el ciclo de escritura interno. Tiempo máximo de ciclo de escritura 5ms. Por lo tanto, se deben esperar al menos 5 ms, ya sea a ciegas o sondeando activamente para que el chip responda con ACK para saber cuándo el chip está listo para usarse nuevamente.