Guten Tag Habe ein Problem mit dem zugriff auf den internen EEPROM. Dort will ich ein Long integer Wert reinschreiben und ihn später wieder auslesen auch wenn der AVR aus war soll der wert auslesbar sein. Das Project ein Streckenzähler in cm. beispiel ich zähle alle 1 cm und der wert zb 10(10cm) soll im EEPROM abgelegt werden usw. D.h es wird immer der vorletzte wert mit dem letzten überschrieben. nun habe ich imm eeprom noch FONT werte abgelegt zur Anzeige auf ein GLCD. Wie wird sowas gemacht schreiben scheint zu gehen habe es so wie im GCC TUTorial gemacht und das lesen auch wies dort steht aber beim lesen macht mein AVR ein reset. AVR TYP MEGA128 #include <avr/eeprom.h> #ifndef EEMEM // alle Textstellen EEMEM im Quellcode durch _attribute_ ... ersetzen #define EEMEM _attribute_ ((section (".eeprom"))) #endif uint8_t myByte=3969; uint32_t eeFooWord EEMEM = 1; void schreibe(long int wert) { eeFooWord=wert; eeprom_write_byte(&eeFooWord, myByte); } void lese() { uint32_t stand= eeprom_read_byte(&eeFooWord); //hier resettet er. printf(stand); }
> Das Project ein Streckenzähler in cm.
Dieser Satz kein Verb ;-)
Warum ist eeFooWord als uint32_t definiert und nicht als long, so wie
das, was du reinschreibst? Das ist zwar nicht das Problem, aber unschön
ist es trotzdem. Ein Problem könnte sein, daß du eeprom_write_byte
benutzt, welches genau ein Byte ins EEPROM schreibt, aber eine Variable
hast, die vier Bytes groß ist. Beim Lesen dasselbe. Einen Reset sollte
das aber nicht auslösen. Hast du vielleicht versehentlich den
EEROM-Interrupt eingeschaltet oder so?
Ich habe festgestellt das bis 1024 es geht ohne das der Mega resettet aber alles drüber macht er einen reset. Habe schon viel ausprobiert auch was hier so im Forum zu finden ist aber immer das gleiche er resettet warum weiß ich aber nicht.
eeprom_read_byte und eeprom_write_byte dienen dazu EIN BYTE zu schreiben oder zu lesen. Such mal in der avrlibc doku nach eeprom_read_buffer und eeprom_write_buffer. Gruß Ich selbst
Ich seh da grad noch was:
1 | void schreibe(long int wert) |
2 | {
|
3 | eeFooWord=wert; |
4 | eeprom_write_byte(&eeFooWord, myByte); |
5 | }
|
Das ist so mal ganz daneben. eeFooWord kannst du nichts zuweisen. Genau deshalb existiert ja eeprom_write_*(). Du schreibst hier im RAM in eine Variable, die eigentlich nicht im RAM, sondern im EEPROM steht. Dabei überschreibst du irgendwas anderes, was eben zufälligerweise an dieser Stelle im RAM steht. Was soll eigentlich myByte sein und wie kommst du auf die Idee, 3969 passe in ein einzelnes Byte? Ich glaube, du willst einfach sowas wie:
1 | void schreibe(long int wert) |
2 | {
|
3 | eeprom_write_block(&eeFooWord, &wert, sizeof(long int)); |
4 | }
|
habe folgendes Probiert long int eememory[10] EEMEM; static long int adresse=1; alle 10 sec. { .... adresse+=512; eeprom_write_block(eememory, adresse, sizeof(eememory)); .... } long int ende[10]; eeprom_read_block(ende,eememory,sizeof(eememory)); nun habe ich das Problem das er mir die EEPROM Daten für das Display FONT Daten überschreibt bekomme teilweise nur müll aus dem FONTDATEN. ICh denke ich werde mir einen externen I2C EEPROM zulegen und dort die Wegstrecke abspeichern.
Das ist recht Simpel: War long beim AVR 64 oder 32Bit? Hier für 64 bit: typedef union { struct { unsigned char a; unsigned char b; unsigned char c; unsigned char d; unsigned char e; unsigned char f; unsigned char g; unsigned char h; } bytes; long int value; } mytype; mytype eememory; eememory.value=<Dein Wert>; Dann eememory.bytes.a..h ins eeprom schreinben. Das ganze Umgedreht zum zurück lesen. Gruss Sven
Hallo Wie ich es richtig verstehe schreibe ich z.b eememory.value=51201; in a=5 b=1 c=2 d=0 e=1 und dann??? mit write_byte oder write_block?????
Keine Ahnung worauf Sven in seinem Beitrag aus ist. Scheint er präsentiert eine Lösung für ein Problem das du gar nicht hast.
> EEPROM Daten für das Display FONT Daten überschreibt
Für die Organisation, welche Daten wo im EEProm abgelegt
werden, bist du selbst zuständig. Es ist deine Aufgabe
die Adressen so zu wählen, dass sich nichts überschneidet.
ich dachte es geht so ich definiere wie auch die Fontdaten dort habe ich mehrer arrays static uint8_t char2[] EEMEM = { 0x3C,0x00, /* [ **** ] */ 0x66,0x00, /* [ ** ** ] */ 0x66,0x00, /* [ ** ** ] */ 0x06,0x00, /* [ ** ] */ 0x0C,0x00, /* [ ** ] */ 0x18,0x00, /* [ ** ] */ 0x30,0x00, /* [ ** ] */ 0x60,0x00, /* [ ** ] */ 0x60,0x00, /* [ ** ] */ 0x7E,0x00 /* [ ****** ] */ }; static uint8_t char3[] EEMEM = { 0x3C,0x00, /* [ **** ] */ 0x66,0x00, /* [ ** ** ] */ 0x06,0x00, /* [ ** ] */ 0x06,0x00, /* [ ** ] */ 0x1C,0x00, /* [ *** ] */ 0x06,0x00, /* [ ** ] */ 0x06,0x00, /* [ ** ] */ 0x06,0x00, /* [ ** ] */ 0x66,0x00, /* [ ** ** ] */ 0x3C,0x00 /* [ **** ] */ }; static uint8_t chard[] EEMEM = { 0x7F, 0x00, /* [ ******* ] */ 0x61, 0x80, /* [ ** ** ] */ 0x60, 0xC0, /* [ ** ** ] */ 0x60, 0xC0, /* [ ** ** ] */ 0x60, 0xC0, /* [ ** ** ] */ 0x60, 0xC0, /* [ ** ** ] */ 0x60, 0xC0, /* [ ** ** ] */ 0x60, 0xC0, /* [ ** ** ] */ 0x61, 0x80, /* [ ** ** ] */ 0x7F, 0x00, /* [ ******* ] */ }; daraus wird ja eine eep datei erzeugt die ins eeprom beim programmen geschrieben wird habe ich das richtig verstanden??? nun definiere ich einen long wert der hat ja auch ein maximum an platz. und dieser wird ebenfals wie auch die font daten in die eep datei geschrieben und dann in den eeprom. da ich mich innerhal der long definition bewege dürfte ich doch auch nicht über diese hinwegkommen. oder reserviert er mir nur ein byte?? wie kann ich die adressen festlegen mein AVR 128 MEga hat ja 4KB EEPROM SPEICHER.
Ich hatte verstanden das es sich um Long Werte handelt die in das EEprom geschrieben werden sollen und nicht um Fonts die Schon auf das Bildschirm Format gerendert wurden. Bei mir must du nur die einzelnen Bytes ins EEprom Schreiben. Du kannst das auch per Block write machen dann must du nur die einzel Chars durch eine Reihung ersetzen. Gruss Sven
Ich habe ein ähnliches Problem, wenn ich ein ARRAY ins EEPROM schreiben will, setzt er nur den ersten Wert an einer willkürlichen Adresse. Hab es schon mit Schleifen probiert (damit er den nächsten Wert vom Array in die nächste Adresse im ROM schreibt), aber meine gewünschten Zieladressen im EEPROM nimmt er nicht. z.B. ... uint8_t Stream[] = {1, 2, 3, 4}; //soll in den EEPROM ... muss ich Blockweise schreiben?? steh grad aufn Schlauch
> wenn ich ein ARRAY ins EEPROM schreiben will, setzt er nur den > ersten Wert an einer willkürlichen Adresse. Wie machst du den Schreibzugriff denn? Welche Adresse gibst du an?
Morgen, allein wenn ich das Beispiel aus dem Tutorial nehme bekomme ich diese Fehlermeldung: #ifndef EEMEM #define EEMEM _attribute_ ((section (".eeprom"))) #endif uint8_t eeFooByte EEMEM = 123; uint8_t myByte; myByte = 66; eeprom_write_byte(&eeFooByte, myByte); // schreiben test.c:133: error: section attribute cannot be specified for local variables Lasse ich das "EEMEM" weg, schreibt er immer nur an eine Adresse im ROM. Was könnte das sein, kann die Errormeldung nicht zuordnen.
> test.c:133: error: section attribute cannot be specified for local > variables eeFooByte muss eine globale Variable sein, keine funktionslokale. Poste bitte nächstesmal dein komplettes Program und nicht nur Ausschnitte. Vor allem bei solchen Sachen ist es wichtig wo Variablen deklariert werden. Und das sieht man nur im kompletten Program. Ich weiss: Das ist im Tutorial auch nicht gut gelöst.
Ja, du hast recht. Das alles steckt nähmlich in einer Funktion und ist nicht global. Danke, und das nächste mal gibts mehr Info...
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.