Forum: Mikrocontroller und Digitale Elektronik EEPROM Probleme


von Michael K. (mmike)


Lesenswert?

Hallo Leute,
ich bin dabei einen Drehzahlmesser für den Modellbau zu bauen. Die 
optischen Sachen funktionieren schon wunderbar, nur leider habe ich 
Probleme beim speichern von Werten in den EEPROM. Momentan verwende ich 
einen ATMega16 mit 16MHz externem Quarz und avrgcc als Compiler. Hier 
kurz das Code - Fragment was Probleme macht:


#include <avr/io.h>
#include <inttypes.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <avr/eeprom.h>

#define EEPROM_CONTRAST   0x01
#define EEPROM_OTHERVALUE 0x02


...

eeprom_write_byte ((uint8_t *) EEPROM_CONTRAST, LCDContrast);
eeprom_write_byte ((uint8_t *) EEPROM_OTHERVALUE, OtherValue);

...

uint8_t val1 = eeprom_read_byte ((uint8_t *) EEPROM_CONTRAST);
uint8_t val2 = eeprom_read_byte ((uint8_t *) EEPROM_OTHERVALUE);

...

Ausgabe von val1 und val2 auf LCD ...

Wenn ich die oberen Anweisungen ausführe, dann funktionierts auch 
wunderbar. Die richtigen Werte werden auf dem LCD angzeigt. Wenn ich 
dann die Schreib - Kommandos auskommentiere und neu programmiere, dann 
werden die falschen Werte aus dem EEPROM gelesen (Die Fuse ist gesetzt, 
daß der EEPROM nicht beim programmieren gelöscht wird ! Preserve EEPROM 
....)

Geht das so nicht, daß die Speicheradressen der Werte per #define 
gesetzt werden ?
Muss der Cast für die Adresse vielleicht uint16_t * sein, da der Mega 16 
ja 512 bytes EEPROM hat und mit 8bit nur die ersten 256 Bytes 
adressierbar sind ?

Grüße,
Michael

von Karl H. (kbuchegg)


Lesenswert?

Michael K. wrote:
> dann die Schreib - Kommandos auskommentiere und neu programmiere, dann
> werden die falschen Werte aus dem EEPROM gelesen (Die Fuse ist gesetzt,
> daß der EEPROM nicht beim programmieren gelöscht wird ! Preserve EEPROM
> ....)
>
> Geht das so nicht, daß die Speicheradressen der Werte per #define
> gesetzt werden ?

Doch das geht.

> Muss der Cast für die Adresse vielleicht uint16_t * sein,

Nein. Du liest/schreibst ein Byte. Der Datentyp dafür
ist nun mal uint8_t, und der Pointertyp dafür ist nun mal
uint8_t*


Du hast irgendein anderes Problem entweder im Code oder
im Handling wenn du das Programm brennst. Anscheinend wird
das EEPROM doch jedesmal neui beschrieben. Oder aber du
brennst nicht das Programm, welches du denkst das du brennst
(ist mir auch schon ein paar mal passiert).

von Michael K. (mmike)


Lesenswert?

Hallo Karl-Heinz,
der EEPROM wird definitiv nicht überschrieben (kann ich durch auslesen 
des EEPROMs nach dem Brennen verifizieren und bestätigen!). Und 
programmiert wird das Ding sicherlich auch, da bin ich mir sicher (nutze 
das STK500) mit der neuesten Version vom WinAVR.
Nochmals eine Frage zum Datentyp. Wie würde denn der Befehl aussehen 
wenn ich Adresse 277 im EEPROM mit einem 8bit Wert beschreiben will ? 
Die Adressangabe muss ja dann ein 16bit Wert sein, sonst kann ich's ja 
nicht adressieren, oder?

von Michael K. (mmike)


Lesenswert?

Nachtrag: Das komische auch ist, daß z.B. der LCDContrast Wert immer 
sauber ausgelesen wird, auch wenn nur aus dem EEPROM gelesen wird ... 
nur die Nachfolgenden Werte stimmen dann nicht mehr .....

von Karl H. (kbuchegg)


Lesenswert?

> Wie würde denn der Befehl aussehen
> wenn ich Adresse 277 im EEPROM mit einem 8bit Wert

  eeprom_write_byte( (uint8_t*)277, Wert );

Was mir auch schon passiert ist:
Ich habe im Programm was verändert, habe aber nicht gemerkt,
dass ich einen Fehler ein gebaut habe. Programm gebrannt
und es verhielt sich so wie vor der Änderung. Minutenlang
gesucht, bis ich gemerkt habe, dass der Linker aufgrund
der Fehler nicht durchgelaufen ist.

Wenn dein Programm stimmt, dann wird es wohl sowas sein.
Oder du hast nicht alle write_byte Aufrufe auskommentiert.

von Karl H. (kbuchegg)


Lesenswert?

Michael K. wrote:
> Nachtrag: Das komische auch ist, daß z.B. der LCDContrast Wert immer
> sauber ausgelesen wird, auch wenn nur aus dem EEPROM gelesen wird ...
> nur die Nachfolgenden Werte stimmen dann nicht mehr .....


Speck dein Programm auf das absolut Notwendige ab um den Fehler
zu zeigen und dann zeig mal her.

von Thilo M. (Gast)


Lesenswert?

Vielleich solltest du vor dem Schreiben bzw. Lesen warten bis das EEPROM 
'ready' ist?
Z.B.
1
eeprom_busy_wait();

von Michael K. (mmike)


Lesenswert?

Hm. Ich check das heute abend nochmals genauer ab! Das mit der 
Adressierung ist irgendwie komisch. Es sträubt sich ein wenig in mir 
(uint8_t *)277 zu schreiben ... Da der 8bit Wert diese 277 ja gar nicht 
annehmen kann .... (nicht dass ich so viele Werte schreiben wollte)
Danke aber schonmals für die Hilfe. Ich melde mich heute abend dann 
nochmals ....

von Michael K. (mmike)


Lesenswert?

Werde heute abend mal nur nen kleines Prog mit den EEPROM Anweisungen 
schreiben !
@Thilo: Soweit ich weiß sollte die Routine eeprom_write_byte das schon 
intern regeln, oder irre ich da ?

von Johannes M. (johnny-m)


Lesenswert?

Thilo M. wrote:
> Vielleich solltest du vor dem Schreiben bzw. Lesen warten bis das EEPROM
> 'ready' ist?
Das machen die eeprom_write_irgendwas-Funktionen automatisch.

Michael K. wrote:
> Es sträubt sich ein wenig in mir (uint8_t *)277 zu schreiben ... Da der 8bit
> Wert diese 277 ja gar nicht annehmen kann .... (nicht dass ich so viele
> Werte schreiben wollte)
Du verwechselst immer noch "Zeiger auf 8-Bit-Wert" mit "8-Bit-Adresse"! 
Dein Cast auf uint8_t* macht lediglich dem Compiler klar, dass er den 
Ausdruck danach als Zeiger auf einen 8-Bit-Wert verwursten soll. Das hat 
aber nichts mit dem Adressraum zu tun...

von Karl H. (kbuchegg)


Lesenswert?

Michael K. wrote:
> @Thilo: Soweit ich weiß sollte die Routine eeprom_write_byte das schon
> intern regeln, oder irre ich da ?

Nein, du irrst nicht.
eeprom_write_byte macht das bereits.

von Michael K. (mmike)


Lesenswert?

Hab grad meine Mittagspause geopfert, weil ichs einfach wissen wollte 
und bin ins E-Labor gestapft und habs ausprobiert.... Du hast 
wahrscheinlich Recht Karl-Heinz, daß in meine Programm noch ein Fehler 
ist .... Ich werde heute abend mal suchen ...
Die Test hier in der Arbeit haben wunderbar geklappt!
Besten Dank an alle,
Grüße,
Michael

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.