Forum: Mikrocontroller und Digitale Elektronik Internes EEPROM beschreiben bei Atmega 644


von Schorsch (Gast)


Lesenswert?

Hallo Leute,

ich versuche vergeblich das interne EEPROM des Atmega 644 zu 
beschreiben.
Leider ohne Erfolg. Ich lese immer 0xFF aus. D.h. ja dass das Schreiben 
irgendwie nicht klappt.

So schreibe ich:

  // Wait for completion of previous write
  ui_TryCounter = 0;
  while(EECR & (1<<EEPE))
  {
    ui_TryCounter++;
    if (ui_TryCounter >= TRYS) return 1;
  }

  // Set up address and Data Registers
  EEAR = uiAddress;
  EEDR = ucData;
  // Write logical one to EEMPE
  EECR |= (1<<EEMPE);
  // Start eeprom write by setting EEPE
  EECR |= (1<<EEPE);

So lese ich:

  // Wait for completion of previous write
  ui_TryCounter = 0;
  while(EECR & (1<<EEPE))
  {
    ui_TryCounter++;
    if (ui_TryCounter >= TRYS) return 1;
  }
  // Set up address register
  EEAR = uiAddress;
  // Start eeprom read by writing EERE
  EECR |= (1<<EERE);
  // Return data from Data Register
  *uc_Data = EEDR;

  sei();

  return 0;

Kann mir jemand sagen was ich falsch mache?

Gruss
Georg.

von tobi (Gast)


Lesenswert?

1. Du zeigst nicht den ganzen Code
2. Du hast dir wohl die avr/eeprom.h nicht angeguckt 
http://www.nongnu.org/avr-libc/user-manual/group__avr__eeprom.html
3. Du benutzt keine Codetags

von pfft.. (Gast)


Lesenswert?

Im Datenblatt steht wie's geht. Es dauert etwas laenger. Machs doch 
einfach nach Datenblatt.

von Εrnst B. (ernst)


Lesenswert?

Und auch stur nach Datenblatt nachprogramieren führt nicht unbedingt zum 
Erfolg:

Manche dieser Bitfriemeleien müssen innerhalb weniger Takte (waren's 4?) 
abgeschlossen sein. Dauerts länger, wird der Schreib-Befehl nicht 
ausgeführt.

Und was der Compiler aus
1
 EECR |= (1<<EEMPE);
2
  EECR |= (1<<EEPE);
macht, bleibt ganz ihm überlassen.
=> Sowas besser in Inline-ASM machen, oder (noch besser) den 
vorgefertigten ASM-Code aus der avr/eeprom.h nutzen.

von Schorsch (Gast)


Lesenswert?

Nabend Leute,


ich hab jetzt mal die GCC Lib getestet (avr/eeprom.h).
Ich kann mit read_byte zwar was lesen. In meinem Fall 0xFF. Was ja klar 
ist da ja noch nichts drinn steht.

Schreiben kann ich leider immer noch nicht.

Gruss,
georg.

von Schorsch (Gast)


Lesenswert?

Hallo,

ich bins noch mal.
Ich kann Entwarnung geben.

Mein Debugger hat mich etwas hinters Licht geführt. Die Variablenwerte 
wurden nicht mehr aktualisiert. Ein Neustart hilft da manchmal Wunder ;)

Gruss,
Georg.

von Schorsch (Gast)


Lesenswert?

Nabend,


ich bins noch mal.

Ich verwende jetzt die Funktionen der GCC Lib.
Leider scheinen diese nicht immer zu funktionieren. Manchmal les ich den 
Wert den ich davor geschrieben habe und manchmal 0xFF. So als ob da nie 
was abgelegt wurde.
In der Lib vom GCC sind an sich ja schon Wartebedingungen enthalten.

Muss ich sonst noch was beachten?

Gruss,
Georg.

von Schorsch (Gast)


Lesenswert?

Morgen,


irgendwie krieg ichs nicht hin.
Auf folgende Weise versuche ich zu lesen und zu schreiben:

  ul_Adress = 0;
  ul_Data = eeprom_read_dword(&ul_Adress);

  eeprom_write_byte((uint8_t *)0x00, 0x69);
  eeprom_write_byte((uint8_t *)0x01, 0x50);

Leider kann ich beim Atmega 644 nicht immer aus dem EEPROM lesen.
Benutze die gcc-lib.

HAt jemand schon mit dieser Lib mit den Atmega644 gearbeitet?

Gruss,
Georg.

von nix (Gast)


Lesenswert?

Ohne die Funktionen zu kennen, bist du sicher dass du die Adresse der 
Variable übergeben willst?

eeprom_read_dword(&ul_Adress);

von Schorsch (Gast)


Lesenswert?

Morgen,

da hab ich nen schmarn geschrieben.
Hopla. Ne ich will natürlich nicht die Adresse der Variablen übergeben 
sondern den Variablenwert.

sollte eigentlich so heissen:

ul_Data = eeprom_read_dword(ul_Adress);

Ich hab das Problem dass das Lesen nicht immer funktioniert. Meistens 
lese ich immer 0xFF zurück. Quasi leeres EEPROM.

Gruss,
Georg.

von Schorsch (Gast)


Lesenswert?

Hallo,

irgendwie scheints bei mir mit der Bearbeitungsgeschwindigkeit zusammen 
zu hängen.

Wenn ich über die Funktionen einzeln drübersteppe dann klappt alles 
immer wunderbar. Spring ich aber über mehrere Funktionen z.B. von 
Breakpoint zu Breakpoint dann klappt das Lesen nur sporadisch.

Kann sich dass einer erklären?

Georg.

von Schorsch (Gast)


Lesenswert?

Mahlheit,

hat den keiner ne Idee?

Georg.

von Schorsch (Gast)


Lesenswert?

Nabend,

ich bin hier langsam am verzweifeln.
Ich verstehe es nicht.

Warum klappt es nur wenn ich über die Funktionen einzeln drüber steppe 
und
sonst nicht.

Weiss denn wirklich keiner Rat?

Georg.

von ANDY (Gast)


Lesenswert?

ACHTUNG JETZT DIE LÖSUNG

Stell den Optimierungsgrad des GCC Compiler auf 2 und schon gehts.
Hab drei Tage gebraucht. Bei Optimierung 0 benötiget man 6 assembler 
Befehle um ein Bit zu setzten. Bei Stufe 2 nur einen Befehl.
Das ist die kritische Stelle:
1
  // Write logical one to EEMPE
2
  EECR |= (1<<EEMPE);
3
  // Start eeprom write by setting EEPE
4
  EECR |= (1<<EEPE);

Das EEPE muss innerhalb vier Cycles nach dem Setzen von EEMPE gesetzt 
werden. Dann funzts.

mfg

ANDY

von Hc Z. (mizch)


Lesenswert?

Interrupts in dieser Zeit sperren nicht vergessen (sofern man welche 
hat).

Und warum hast Du nicht einfach eeprom_write_byte() genommen?

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.