Forum: Mikrocontroller und Digitale Elektronik Frage zur Adressierung EEPROM FM24CL16B


von Martin S. (martinst)


Lesenswert?

Hallo,
ich verstehe das Verhalten vom FM24CL16B nicht. Der Speicher ist 
organisiert in 3 pages von je 256 Byte, also insgesamt 2048 x 8 Bit. Der 
Adresszähler macht immer bei 2047 nach 0 einen Überlauf.


Folgendes Vorgehen:

Ich schreibe 261 Bytes der Werte [0..255,0..5] an page=0, word address=0 
in den FM24CL16B.
Ein Auslesen von 512 Bytes an page=0, word address = 0 ergibt, dass das 
Schreiben erfolgreich war, ich sehe die geschriebenen Bytes in den 
ersten 261 Bytes, der Rest sind Nullen.

Jetzt schreibe ich 80 Bytes mit dem Wert 0 an page=0, word address = 0.
Ein Auslesen von 512 Bytes an page=0, word address = 0 ergibt jetzt dass 
die ersten 80 Bytes Nullen sind - OK, jedoch sind die Bytes 256-261 
ebenfalls Null!
Vorher war doch an den Stellen 256-261 noch Werte, keine Nullen!


Was ich gar nicht verstehe:

Wenn ich beginnend von page=1 z.B. 5000 Bytes auslese, erhalte ich meine 
Werte [80..255,0..4], natürlich mehrfach und umgeben von vielen Nullen.
Lese ich jedoch beginnend von page=0, bekomme ich nur die Werte 
[80..255], wieder umgeben von Nullen. Wo sind die Zahlen [0..4] ???

Vielleicht kann mir jemand auf die Sprünge helfen.
Oder ist das ein Bug? So dass der page-Zähler zwar mitzählt, aber wenn 
vorher page=0 geschrieben wurde, nicht zur Adressierung verwendet wird, 
sondern immer page=0.

Danke,
Martin

von Stefan K. (stefan64)


Lesenswert?

Ich glaube, Du hast da ein paar Sachen falsch verstanden. Wenn ich das 
richtige Datenblatt vorliegen habe, dann hat der Chip 8 pages a 256 
Byte. Entspricht 3 Page-Select Adressleitungen im Slave-Device-Adress 
Byte.

Und ich tippe mal, dass Deine Schreib-Lese-Routinen immer auf die Page 0 
lesen/schreiben. Das fällt bei Deinem 261-Byte-Test nicht auf, weil die 
Daten in Page 0 undd Page 1 identisch sind. Ohne den Code kann man dazu 
aber nicht mehr sagen.

Gruß, Stefan

von Martin S. (martinst)


Lesenswert?

Tschuldigung, mein Schreibfehler. Natürlich sind es 8 pages, ich denke 
schon in Bit ;-)

Wenn ich den Speicher sequentiell mehrfach hintereinander auslese (z.B. 
3 x 2048), bekomme ich verschiedene Sequenzen, abhängig davon ob ich bei 
page 0 oder page 1 starte. Wie ist das zu erklären?

von Martin S. (martinst)


Lesenswert?

@Stefan: Die Daten von Page 0 und 1 sind nicht identisch.
Die Adressen stimmen laut Oszilloskop. Hier ist der Code zum Schreiben 
und Lesen vom EEPROM:
1
uint32_t FRAM_write(uint8_t page, void* data, uint32_t length)
2
{
3
  uint32_t ret_val = 0;
4
  uint32_t i;
5
  if (length == 0) return 0;
6
  ret_val += I2C_start(I2C);
7
  ret_val += I2C_send_address(I2C, (FM24CL16B_SLAVE_ID << 4) | (page << 1), I2C_Direction_Transmitter); // prepare a write operation
8
  ret_val += I2C_write(I2C, 0);    // set lower 8 bit of the word address to 0
9
  while (length) {          // write all bytes
10
    ret_val += I2C_write(I2C, *(uint8_t*)data);
11
    (uint8_t*)data++;        // proceed to next data byte
12
    length--;
13
  }
14
  I2C_GenerateSTOP(I2C, ENABLE);
15
  return ret_val;
16
}
17
18
uint32_t FRAM_read(uint8_t page, void* data, uint32_t length)
19
{
20
  uint32_t ret_val = 0;
21
  uint32_t i;
22
  if (length == 0) return 0;
23
  ret_val += I2C_start(I2C);
24
  ret_val += I2C_send_address(I2C, (FM24CL16B_SLAVE_ID << 4) | (page << 1), I2C_Direction_Transmitter); // prepare a write operation
25
  ret_val += I2C_write(I2C, 0);      // set word address (lower 8 bits)
26
  ret_val += I2C_restart(I2C);      // do not perform the write operation, instead generate a start condition
27
  ret_val += I2C_send_address(I2C, (FM24CL16B_SLAVE_ID << 4) | (page << 1), I2C_Direction_Receiver); // prepare a read operation
28
  while (length >= 2) {          // read all bytes until second to the last has been read
29
    ret_val += I2C_read(I2C, (uint8_t*)data);
30
    (uint8_t*)data++;          // proceed to next data byte
31
    length--;
32
  }
33
  I2C_AcknowledgeConfig(I2C, DISABLE);    // disable acknowledge of the received data so that no further bytes after the next read byte are requested
34
  ret_val += I2C_read(I2C, (uint8_t*)data);  // read last byte
35
  I2C_AcknowledgeConfig(I2C, ENABLE);      // enable acknowledge again
36
  I2C_GenerateSTOP(I2C, ENABLE);
37
  return ret_val;
38
}

von Stefan K. (stefan64)


Lesenswert?

Ich sehe keinen Fehler in Deinem Code.

Kann es sein, dass das FRAM nur die unteren 8 Adressbits einer Page beim 
sequentiellen r/w inkrementiert? Steht zwar anders im Datenblatt, 
aber...

Ich würde den Code mal so umbauen, dass beim Erreichen einer Pagegrenze 
ein neuer r/w Zyklus gestartet wird.

Viele Grüße, Stefan

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.