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.
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
Im Datenblatt steht wie's geht. Es dauert etwas laenger. Machs doch einfach nach Datenblatt.
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.
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.
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.
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.
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.
Ohne die Funktionen zu kennen, bist du sicher dass du die Adresse der Variable übergeben willst? eeprom_read_dword(&ul_Adress);
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.
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.
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.
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.