Forum: Compiler & IDEs [AVR] eeprom_write_word funktioniert nicht


von Sven (Gast)


Lesenswert?

Hallo,

ich habe ein längeres Programm geschrieben, in welchem unter anderem ein 
Zufallszahlengenerator zum Einsatz kommt. Damit nicht nach jedem Reset 
usw. die gleichen Zufallszahlen geliefert werden lese ich beim Start 
jeweils einen Seed aus dem EEPROM aus und schreibe die nächste erzeugte 
Zufallszahl ins EEPROM zurück. Ursprünglich benötigte ich nur 8-Bit 
Zufallszahlen, hier klappte das Ganze wunderbar mit "eeprom_read_byte" 
bzw. "eeprom_write_byte". Nun benötige ich aber 16-Bit Zufallszahlen, 
und hier funktioniert das Speichern mittels "eeprom_write_word" 
überhaupt nicht mehr, bei jedem Reset/Neustart wird wieder die gleiche 
Sequenz erzeugt. Ich habe das Ganze dann im Simulator nachvollzogen, und 
auch hier ist es so, dass ich bis zu "eeprom_write_word" steppen kann 
und der Simulator anschließend in einer Art Endlosschleife landet. Da 
ich auch den Watchdog usw. nutze habe ich das Programm nun auf das 
Nötigste abgespeckt (u.a. auch wieder den 
Standard-Zufallszahlengenerator), und auch hier funktioniert das 
Schreiben ins EEPROM nicht. Hat jemand eine Idee, was schief gehen kann? 
Anbei mein minimales Testprogramm, Der Inhalt der Header-Datei 
entspricht den ersten drei Zeilen. Entwickelt habe ich für einen 
Attiny44A mit AtmelStudio 6. Compiler-Optimierungen waren ursprünglich 
auf "-Os", bei der Fehlersuche habe ich sie jedoch auf "-O0" gesetzt.

1
#define F_CPU 8000000UL
2
#include <avr/eeprom.h>
3
#define EEPROM_SEED_ADDRESS 0U
4
5
uint16_t random;
6
7
static void initRng(void) {
8
  seed= eeprom_read_word((uint16_t *)EEPROM_SEED_ADDRESS);
9
  srand(seed);
10
  eeprom_write_byte((uint16_t *)EEPROM_SEED_ADDRESS, rand()); // klappt!
11
  eeprom_write_word((uint16_t *)EEPROM_SEED_ADDRESS, rand());// klappt nicht, der Debugger scheint in einer Schleife o.ä. zu hängen!
12
  srand(seed); // nur da zum Pausieren beim Steppen
13
}
14
15
int main(void)
16
{
17
    initRng();
18
19
    while(1) {}
20
}

Viele Grüße,
Sven

von Peter II (Gast)


Lesenswert?

warum schreibst du ein byte und liest ein word?

 eeprom_write_byte
 eeprom_write_word

von Sven (Gast)


Lesenswert?

Wie gesagt, das Ganze ist abgespeckt auf ein Testprogramm. Ich wollte 
damit testen, ob das Lesen eines Words klappt, was auch der Fall ist. 
Ein Byte schreiben klappt auch, ein Word schreiben hingegen nicht. Da 
das Ganze nur zum Testen dient habe ich mir nicht die Mühe gemacht, noch 
groß zu casten o.ä..

von Sven (Gast)


Lesenswert?

Sodele, ich habe weiter getestet und den Code zum Schreiben mal wie 
folgt geändert:
1
eeprom_busy_wait();
2
eeprom_write_byte((uint8_t*)EEPROM_SEED_ADDRESS, random);
3
eeprom_busy_wait();
4
eeprom_write_byte((uint8_t*)EEPROM_SEED_ADDRESS, random);

Das erste "eeprom_busy_wait" überspringt er quasi sofort (12 Takte im 
Simulator). Dann schreibt er den EEPROM (32 Takte im Simulator). Das 
zweite "eeprom_busy_wait" scheint dann aber niemals zurückzuspringen, 
selbst nach 8.000.000 Takten (= 1s) hängt der Simulator immer noch im 
"eeprom_busy_wait". Meines Wissens nach wird diese Funktion auch in den 
"eeprom_write_*" Funktionen verwendet, so dass dieser Umstand die 
Probleme erklären könnte. Die Frage ist jetzt, warum das EEPROM 
dauerhaft busy ist, hat da jemand eine Erklärung für?

von Sven (Gast)


Lesenswert?

So,

ich habe nun eigene EEPROM-Funktionen geschrieben und auch diese 
funktionieren nicht bzw. Schreiben funktioniert nur einmal. Das Problem 
ist, dass die Busy-Abfrage niemals terminiert.
1
static void eeprom_busy_wait() {
2
    while(EECR & (1 << EEPE)) {}
3
}

EEPE sollte ja eigentlich nach dem Schreibzugriff in EECR auf 0 gesetzt 
werden, dies scheint aber, auch im Simulator, nicht zu passieren. Hat 
jemand eine Ahnung, woran das liegen kann?

von Sven (Gast)


Lesenswert?

Letzter Versuch:

Wenn ich als Plattform für den Simulator den Attiny 25/45/85/2313/13 
usw. wähle funktioniert es, mit dem Attiny 44 hingegen nicht. 
Irgendjemand eine Idee, was da los sein kann?

von Martin (Gast)


Lesenswert?

Lass den Compiler doch das mit den Adressen übernehmen. Versuchs mal mit 
EEMEM.

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.