I2C EEPROM size

Writing to an external I2C EEPROM 24C512 works fine for the first 4095 bytes.
When I write to address 4096, and then read from this address the value is OK, but at the same time data is changed at address 0. I think this chip has 65536 bytes of space, but it behaves as if it's capacity is only 4096 bytes.

The code:

#include <Wire.h>    
#define disk1 0x50    //Address of 24LC256 eeprom chip
int deviceaddress;
 
void setup(void)
{
  Serial.begin(9600);
  Wire.begin();  
  deviceaddress = disk1;

  for (int i = 0; i < 10; i++) { writeEEPROM(i, 3); }  
  for (int i = 4090; i < 4100; i++) { writeEEPROM(i, 3); }

  writeEEPROM(4096, 0);

  for (int i = 0; i < 10; i++) {
    Serial.print(i);
    Serial.print("\t");
    Serial.println(readEEPROM(i), DEC);
  }
  for (int i = 4090; i < 4100; i++) {
    Serial.print(i);
    Serial.print("\t");
    Serial.println(readEEPROM(i), DEC);
  }
}
 
void loop(){}
 
void writeEEPROM(unsigned int eeaddress, byte data ) 
{
  Wire.beginTransmission(deviceaddress);
  Wire.write((int)(eeaddress >> 8));   // MSB
  Wire.write((int)(eeaddress & 0xFF)); // LSB
  Wire.write(data);
  Wire.endTransmission();
 
  delay(5);
}
 
byte readEEPROM(unsigned int eeaddress ) 
{
  byte rdata = 0xFF;
 
  Wire.beginTransmission(deviceaddress);
  Wire.write((int)(eeaddress >> 8));   // MSB
  Wire.write((int)(eeaddress & 0xFF)); // LSB
  Wire.endTransmission();
 
  Wire.requestFrom(deviceaddress,1);
 
  if (Wire.available()) rdata = Wire.read();
 
  return rdata;
}
Serial output:
|0|0|
|---|---|
|1|3|
|2|3|
|3|3|
|4|3|
|5|3|
|6|3|
|7|3|
|8|3|
|9|3|
|4090|3|
|4091|3|
|4092|3|
|4093|3|
|4094|3|
|4095|3|
|4096|0|
|4097|3|
|4098|3|
|4099|3|

I tested several 24C512, they all give the same result.
I don't know, am I doing something wrong, or are this EEPROMS really only 4096 in size, when they should be 65536.

You write 0 to 4096, you read 0 from 4096, what is the problem?

Writing a zero to 4096 causes that a read at 0 returns a zero.

Try an example of a working library: https://github.com/RobTillaart/I2C_EEPROM.
That library can write many bytes at once, and takes care of the pages that the EEPROM uses internally. That makes it more complex.

I tried without a library, as in the example above, I tried with libraries "I2C_EEPROM.h", and "AT24C512C.h", but the result is always the same. I only need to write one byte at a time.
When I write to address 4096, the value at address 0 is also changed, and I don't want this.

There could be a bug in both libraries (that would be weird), or your EEPROM is damaged, or something else.
Did you try the examples that came with those libraries ?

Do you have an other EEPROM ?

I tried the examples from both libraries, and they work.

I tried with several 24C512, and 24LC256. The result is the same.

That's why I came here :slight_smile:

@lukc
1. This is (Fig-1) the conceptual organizational diagram of AT24C512 EEPROM.
eeprom512X
Figure-1:
2. The EEPROM has the capacity of holding 512 kbits (512x1024) data. This means that there are 512x1024 memory cells inside the EEPROM. Each cell can hold 1-bit data.

3. The cells of the EEPROM are organized as memory locations; where, each memory location can hold 8-bit data (byte). Thus, there are (512x1024)/8 = 65536 memory locations in the EEPROM.

4. Every memory location has a 16-bit address. Thus, the address of the bottom location is 0 in decimal-base (0x0000 in hex-base). The addres of the top location is 65535 in decimal-base (0xFFFF in hex-base).

5. The address of the target location into which we wish to perfrom data read/write operation is 4096 in decimal-base (0x1000 in hex-base).

6. Check that the EEPROM is connected with UNO as per following diagram (Fig-2).
eeprom512y
Figure-2:

7. Let us upload the following (tested) sketch to write 0x23 into location 4096 (0x1000) and read back.

#include<Wire.h>

void setup()
{
  Serial.begin(9600);
  Wire.begin();

  //-- writing process----
  int memAddress = 0x1000;
  Wire.beginTransmission(0x50);  //EEPROM I2C address
  Wire.write(highByte(memAddress));  //pointing/queueing memory address
  Wire.write(lowByte(memAddress));  //pointing/queueing memory address
  Wire.write(0x23);                  //queueing data byte in buffer
  Wire.endTransmission();
  delay(5); //write cycle delay

  //----reading back--------------------
  Wire.beginTransmission(0x50);  //EEPROM I2C address
  Wire.write(highByte(memAddress));  //pointing/queueing memory address
  Wire.write(lowByte(memAddress));  //pointing/queueing memory address
  Wire.endTransmission();
  //------------------------
  Wire.requestFrom(0x50, 1); //reading 1-byte from location 0x1000 (4096)
  byte y = Wire.read();
  Serial.println(y, HEX);   //check that Serial Monitor shows: 23
}

void loop()
{

}

8. Now write 0x67 into location 0 (0x0000), read it back, and also read from location 4096 (0x1000). Check that the data are different.

9. Now do the experiment with the sketch of your Post-1.

I have executed your sketch of Post-1, and I see that the Location-0 still holds 3 though data of Location-4096 was chaned from 3 to 0.

0	3
1	3
2	3
3	3
4	3
5	3
6	3
7	3
8	3
9	3
4090	3
4091	3
4092	3
4093	3
4094	3
4095	3
4096	0
4097	3
4098	3
4099	3
Location-0 holds: 3

Thank you all for your time. My eeprom was already on a breadboard with 2 more I2C devices, and other things, when I encountered this problem.

Now I tested with only eeprom on the breadboard, and it works correct.
So now I know my eeprom chips are ok, and I know where too look for the problem.

1 Like

This problem was caused by DS1307. I replaced it with DS3231, and all works fine :slight_smile:

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.