Listing 1
$ i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: 50 -- -- -- 54 -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
Um nun ein Byte in das EEPROM mit der Adresse 0x50 am I2C-Bus zu schreiben, verwenden Sie die Kommandos aus den ersten beiden Zeilen von Listing 2. Das erste schreibt den Wert 0xaa an die Adresse 0x0001, das zweite 0xbb an die Adresse 0x0002. Um nun das erste Byte wieder auszulesen, verwenden Sie die Befehle aus Zeile 3 und 4. Der erste Befehl teilt dem EEPROM mit, von welcher Adresse Sie lesen wollen, der zweite liest dann den Wert aus. Der interne Adresszähler des 24LC1025 wird dabei automatisch um eins erhöht. Ein weiterer Lesevorgang liefert nun den Wert an der Adresse 0x02 (Zeile 5).
Listing 2
$ i2cset -y 1 0x50 0x00 0x01 0xaa i $ i2cset -y 1 0x50 0x00 0x02 0xbb i $ i2cset -y 1 0x50 0x00 0x01 i $ i2cget -y 1 0x50 0xaa $ i2cget -y 1 0x50 0xbb
Programmgesteuert
Das Testprogramm aus Listing 3 beschreibt die ersten 256 Byte des EEPROMs mit den Zahlen von 0 bis 255. Danach liest es sie wieder aus und gibt sie auf der Konsole aus. Dieses zugegebenermaßen nicht besonders kreative Programm zeigt Ihnen, wie sich das EEPROM beschreiben und auslesen lässt. Außerdem bietet es eine gute Basis für eigene Experimente. Um mehr als 256 Byte zu schreiben, müssen Sie auch das High-Byte verwenden, das in unserem Beispiel fest auf 0 steht.
Listing 3
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <linux/i2c-dev.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main (void) {
int device;
if ((device = open("/dev/i2c-1", O_RDWR)) < 0) {
perror("Can not open I2C Bus");
exit (1);
}
if (ioctl(device, I2C_SLAVE, 0x50) < 0) {
perror("Can not connect to Device");
exit (1);
}
int i;
unsigned char data[3];
for (i=0;i<256;i++) {
data[0]= 0x00; // High Byte Address
data[1]= (unsigned char) i; // Low Byte Address
data[2]= (unsigned char) i; // Data Byte
// data[2]= (unsigned char) 0xaa; // Write-Protect-Test
write(device,data,3);
printf("In : %d\n",i);
usleep(5000);
}
for (i=0;i<256;i++) {
data[0]= 0x00; // High Byte Address
data[1]= (unsigned char) i; // Low Byte Address
write(device,data,2);
read(device,data,1);
printf ("Out[%d]: %d\n",i,data[0]);
}
}
In den Zeilen 1 bis 8 importiert das Programm zuerst alle nötigen Bibliotheken. Der erste Teil der main()-Funktion ab Zeile 10 beschäftigt sich damit, die Verbindung zum EEPROM aufzubauen, im Fehlerfall erscheinen entsprechende Meldungen. Nun kommt der interessantere Part.
Keine der üblichen Bibliotheken bietet an, die Byte-Sequenzen auf den I2C-Bus zu legen, die man benötigt, um den 24LC1025 richtig anzusteuern. Deswegen arbeitet das Programm mit den sehr einfachen Funktionen read() und write(). Um das Protokoll vollständig zu verstehen, muss man sich die entsprechenden Teile des Datenblatts sehr genau ansehen.
Nun folgen zwei For-Schleifen. Die erste ab Zeile 22 schreibt die Bytes in den 24LC1025. Die Funktion usleep() (Zeile 28) wird nötig, weil der 24LC1025 zu schnell geschriebene Daten im Einzel-Byte-Modus nicht korrekt abspeichern kann. Im Page-Write-Modus könnten Sie die Daten über einen Hardware-Buffer schreiben, was erheblich schneller geht. Falls Sie mit einer Anwendung arbeiten, bei der es auf Geschwindigkeit ankommt, schauen Sie bitte in das Datenblatt des 24LC1025, um zu sehen, wie sich komplette Pages schreiben lassen.
Die zweite Schleife ab Zeile 31 liest das EEPROM wieder aus und gibt die Werte in der Konsole aus. Damit ist das Programm auch schon komplett. Um es zu übersetzen, verwenden Sie wie gewohnt den GNU-Compiler und starten das Kompilat dann auf der Kommandozeile (Listing 4).
Listing 4
$ gcc 24LC1025.c $ ./a.out
Write-Protect-Test
Mithilfe des Test-Programms, das den 24LC1025 beschreibt und ausliest, sehen Sie sich jetzt an, wie die Write-Protect-Funktion arbeitet. Dazu ändern Sie die Zeile, die die Werte in das EEPROM schreibt (Listing 2, Zeile 25).
Kommentieren Sie diese Zeile aus und entkommentieren Sie die folgende Zeile, sodass das Programm nun data[2] statt (unsigned char) i; den Wert (unsigned char) 0xaa zuordnet. Dadurch versucht das Programm, den Wert 0xaa (dezimal: 170) in alle Speicherstellen zu schreiben.
Um die Write-Protect-Funktion zu aktivieren, stellen Sie den entsprechenden DIP-Schalter auf ON. Nun kompilieren Sie das geänderte Testprogramm noch einmal und starten es. Und siehe da: Es vermag die Werte im EEPROM nicht mehr zu ändern.
Um den Test zu komplettieren, stellen Sie den DIP-Schalter wieder auf seine Ursprungsposition und starten das Programm erneut. Jetzt beschreibt es tatsächlich alle Speicherstellen mit dem Wert 170 dezimal.





