PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : EEPROM - Speicheraufbau, schreiben und lesen



simple
11.08.2006, 14:06
Hallo zusammen.

Wieder geht es um das leidige Thema EEPROM. Vielleicht findet sich an dieser Stelle auch mal ein eingesessener Profi, der noch mal alle Grundlagen rund um das Thema EEPROM aufrollt, damit ein informationsreiche Referenz für alle weiteren Fragen entsteht.

Ich möchte den EEPROM beschreiben und später wieder auslesen. Leider habe ich auf folgende Fragen noch keine konkrete Antworten gefunden:

1) Wie sieht das Speicherabbild des EEPROMs aus, d.h. welche Adressen kann ich explizit adressieren?

2) Muss ich die aus dem Datenblatt angegebenen Funktionen nochmal implementieren oder tuen es die aus der eeprom.h?

3) Wie beschreibe ich den EEPROM (z.B. eine Variable, ein Array)? Denn ich muss doch die Daten an einer Adresse ablegen, die ich nach einem Power-off wieder finde.

4) Wie lese ich aus dem EEPROM - wie finde ich die Daten an der entsprechenden Adresse?

Es ist eher nicht das Problem wie ich den EEPROM beschreibe, sondern WO ich schreibe. Kann vielleicht jmd. nochmal erwähnen, wie der EEPROM aufbaut ist, und WIE ich dort Daten ablege um ihn effizient zu nützen.

Vielen Dank für Eurer Hilfe,
simple.

SprinterSB
11.08.2006, 21:42
ad 1: Der EEPROM hat Adressen von 0 bis E2END. Letzteres ist ein Define, das du via #include <avr/io.h> definiert bekommst.
ad 2: Nein
ad 3: Dafür hats die Funktionen eeprmo_read_block resp. eeprom_write_block.
ad 4: Die Adressen der Objekte (Strukturen, Arrays, ...) kannst du dem Compiler überlassen. Falls du das nicht magst kannst du die Adressen auch selbst ausdenken, aber wenn die Adressen zur Compilezeit bekannte Konstanten sind ist das Energieverschwendung...

Ein paar Beispiele finden sich im RN-Wissen-Artikel [wiki="avr-gcc"]

simple
14.08.2006, 12:17
Danke erstmal für die Antwort.
Es gibt allerdings noch ein paar Problemchen/Fragen die noch offen sind:

1) Wenn ich eeprom.h include, dann hängt sich jedesmal AVR Studio auf und muss neu gestartet werden. Erst wenn ich das #include <avr/eeprom.h> wieder entferne geht es. Deswegen kann ich dann logischer Weise auch nicht die Funktionen eeprom_read_block etc. verwenden. Kennt jemand diese Phänomen und eine entsprechende Lösung?

2) "Die Adressen der Objekte (Strukturen, Arrays, ...) kannst du dem Compiler überlassen."
Das verstehe ich noch nicht ganz. Ich muss doch den Funktionen irgendeine Adresse übergeben ?!
Außerdem woher weiß ich dann nach einem Reset, wo d.h. an welcher Adresse z.B. mein Datenbyte im EEPROM liegt?

simple
14.08.2006, 14:05
Update zu Problem 1):

Dank dem RN-User "Gerry77" ist das Problem des Aufhängens von AVR Studio beim includen von <avr/eeprom.h> geklärt:
Man muss einfach im Menü "Project - Configuration Options" unter "Include Directories" den Pfad "..\WinAVR\lig\gcc\avr\3.4.6\inlcude\" hinzufügen. Dann hängt sich AVRStudio nicht mehr auf.
Zum Nachlesen der entsprechende Thread von Gerry77 (siehe letzten Beiträge): https://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=19426

SprinterSB
16.08.2006, 11:54
Wenn du ein Byte im "normalen" RAM hast, musst du die Adressverwaltung ja auch nicht übernehmen:


unsigned char ein_byte = 42;
...
ein_byte++;
...

Dir kann doch egal sein, wo ein_byte im Speicher liegt. Nachm RESET liegts doch immer noch an der selben Stelle...

Für den EEPROM sieht es so aus:

#include <avr/eeprom.h>

// EEMEM braucht bei neueren avr-gcc-Versionen nicht mehr extra definiert zu weden.
#define EEMEM __attribute__ ((section (".eeprom")))

const unsigned char ein_byte_EE EEMEM = 42;
...
ein_byte = eeprom_read_byte (& ein_byte_EE);


Falls du dich um die Adressen selber kümmern willst, kann es ratsam sein, den gesamte EEPROM in eine Struktur abzubilden. Die Komponente data in der Struktur unten enthält einfach 100 Bytes, die du lesen und schreiben kannst.

#define NUM_BYTES_EE 100

unsigned char data[10];

typedef struct
{
unsigned short address;
unsigned char data[NUM_BYTES_EE];
} eeprom_t;

// Initialisierung fuer eeprom, wird beschrieben beim Flashen (nicht beim RESET)
const eeprom_t eeprom EEMEM =
{
.address = 0,
.data = {0, 1, 2, 3 /* ... */ }
};

void foo()
{
unsigned short address;

// liest die letzte Adresse
eeprom_read_word ((void*) & eeprom.address);
// liest 10 Bytes vom EEPROM: eeprom.data[last_address]...eeprom.data[last_address+9] nach data
eeprom_read_block (data, & eeprom.data[address], 10);
// Adresse um 10 weiter
eeprom_write_word ((void*) & eeprom.address, address+10);
}

simple
16.08.2006, 11:59
Ah, verstehe. Danke für die Erklärung. Jetzt ist es mir sonnenklar!