Der AT24C512

Zum Anschluss des Speichers möchte ich hier nicht viel sagen, da dieser eigentlich trivial ist. Es wird normal Vcc und GND angeschlossen, SDA und SCL werden an die korrespondierenden Pins des MC angeschlossen. Wer den Schreibschutz nutzen möchte, kann WP auf Vcc legen. Ein wenig Beachtung verdienen noch A0 und A1, welche für die Adresse des Speichers verantwortlich sind. Möchte man nur einen am Bus verwenden, so kann man diese Pins frei lassen (NC). Andernfalls gilt folgendes: Die Adresse des Speichers wird durch ein 8Bit Datenwort repräsentiert. Dieses hat folgenden Aufbau:

 1    0    1    0    0   A0 A1 R/W

Wie man sieht, kann man mittels A0 und A1 maximal 2^n = 4 Kombinationen erreichen, also kann man auch nicht mehr Speicher am Bus betreiben. Der Inhalt von A0 und A1 wird durch die Beschaltung des Anwenders festgelegt. Legt dieser A0 auf Masse, so wird es im jeweiligen EEPROM mit einer Null gefüllt. Alternativ kann man die Pins auf Vcc legen. Das LSB (least significant bit) legt fest, ob ein Lese- oder Schreibzugriff erfolgen soll. Über die beiden obligatorischen Pull-Up Widerstände muss hier nicht weiter gesprochen werden.
Der Speicher ist intern mittels 512 Pages organisiert, von denen jede 512KBit/8/512=128Byte umfasst. Die Adressierung einzelner Bits kann mittels eines 16Bit Wortes erfolgen (2^16 = 65536 --> 65536/1024=64kByte).

Schreiben:

Beim Schreiben auf dem EEPROM können, wie bereits oben erwähnt, zwei Varianten unterschieden werden. Entweder man schreibt ein einzelnes Byte an eine Adresse oder man schreibt eine komplette Page.
Zum Schreiben eines einzelnen Bytes sieht wie folgt aus:

  1. Senden der Start-Bedingung
  2. Senden der Adresse des EEPROMs (Für Schreiben ist R/W = 0, für Lesen ist R/W = 1)
  3. Empfangen des ACK des EEPROMs
  4. Senden der Adresse (High-Byte), an welche das Byte geschrieben werden soll.
  5. Empfangen des ACK des EEPROMs
  6. Senden der Adresse (Low-Byte), an welche das Byte geschrieben werden soll.
  7. Empfangen des ACK des EEPROMs
  8. Senden des Datenwortes (1 Byte)
  9. Empfangen des ACK des EEPROMs
  10. Senden der Stopp-Sequenz.

Nach dem Empfang des Stopp startet der EEPROM intern den Schreibzyklus. Während dieser andauert, sind alle Pins des EEPROM hochohmig und er wird nicht auf Anfragen antworten.

Die zweite Möglichkeit besteht im Schreiben einer kompletten Page, also 128 Byte. Dieses ist nahezu gleich dem Schreiben eines einzelnen Bytes. Nur wird hier der 10. Schritt zunächst weggelassen. Nach dem Empfang des ACK vom EEPROM (9. Schritt) wird einfach das nächste Datenbyte gesendet, erneut auf ein ACK gewartet, das nächste Datenbyte gesendet, auf ein ACK gewartet ... und das ganze insgesamt 128 mal. Danach kann die Stopp-Sequenz gesendet werden, woraufhin der EEPROM mit seinem Schreibzyklus beginnt. Natürlich können auch weniger Bytes geschrieben werden, dann wird einfach bspw. nach dem 29. Byte und dem Empfang des ACK die Stopp-Sequenz gesendet.
Als Startadresse sollte der Beginn der Page gesendet werden, also bspw. 0, 128, 256, 384, 512, 640, 768, 896, 1024, ... , 65408. Um es mathematisch auszudrücken: Die Startadressen der Pages ergeben sich als Vielfache von 128, also bspw. mit Hilfe der Formel i*128, wobei i von 0 bis 511 frei wählbar ist (ganzzahlig).
Sollte man es wagen, mehr als 128 Bytes in eine Page zu schreiben, so beginnt der EEPROM nach erreichen es Endes der Page eiskalt wieder an deren Beginn und würde die zuerst geschriebenen Daten wieder überschreiben.

Lesen:

Beim Lesen werden drei Modi unterschieden.

  1. Current Adress Read
    Der EEPROM verfügt intern über einen Adresszähler. Dieser beinhaltet immer die Adresse, auf die zuletzt zugegriffen wurde, inkrementiert um eins. Die Verwendung des Modus ist einfach. Man muss einfach nur die bereits oben genannten Schritte 1-3 ausführen. Danach sendet der EEPROM den Inhalt der Adresse, welche der Adresszähler gerade beinhaltet. Danach muss der MC die Stopp-Sequenz senden. Ein ACK von Seiten des MC ist nicht notwendig.
  2. Random Read
    Dieser Modus wird verwendet, um ein Byte von einer bestimmten Adresse zu lesen. Hierzu muss zunächst ein Schein-Schreibzugriff ausgeführt werden. Also müssen einfach die oben genannten Schritte 1-9 ausgeführt werden. Der Inhalt des Datenwortes ist egal, die Adresse, an welche es geschrieben werden soll, muss der Adresse entsprechen, von der das Byte gelesen werden soll. Mit diesem Trick setzt man den internen Adresszähler auf das eigentliche Zielbyte. Anstatt den 10. Schritt auszuführen sendet der MC nun eine erneute Start-Bedingung und startet damit einen Current Adress Read, welcher bereits oben beschrieben wurde.
    Ziel der ganzen Aktion ist das Lesen eines Bytes von einer bestimmten Adresse.
  3. Sequential Read
    Wenn ihr die Schreibmodi bis hier her verstanden habt, dann wird der Letzte ganz einfach.
    Mit Hilfe des Sequential Read können mehrere Bytes beginnend an einer bestimmten Adresse gelesen werden. Wo diese Adresse liegt, legt der Benutzer fest. Er startet zunächst einfach einen Current Adress Read oder einen Random Read. Wenn der MC nun das erste Datenbyte empfangen hat, sendet er einfach anstatt eines Stopp ein ACK. Dieses veranlasst den EEPROM, den Adresszähler zu inkrementieren und einfach das nächste Byte zu senden. Diesen Spaß kann man endlos betreiben, da der EEPROM nach erreichen des Page-Ende einfach wieder an deren Beginn weiter macht. Hat man alle gewünschten Bytes gelesen, lässt man den MC einfach ein Stopp senden.

Das war eigentlich auch schon alles, was es zu diesem speziellen Baustein zu sagen gibt. Wie man sieht, ist dessen Verwendung nicht unbedingt schwer, wenn man einmal seine Funktionsweise verstanden hat.

Auf Codeschnipsel u.ä. habe ich hier mit Absicht verzichtet, diese können der Rubrik zum Thema TWI entnommen werden. Alternativ kann man sich auch einfach den von mir verwendeten kompletten Sourcecode anschauen, entweder zur direkten Verwendung, oder als Inspiration. Er ist mehr als ausreichend kommentiert.