Hallo Ihr guten Menschen,
ich habe da mal ein Problem mit der ablage meiner Programmeinstellung
ins Eprom.
Ziel ist die Konfiguration meines Programmes ins Eprom abzulegen um nach
einen Stromausfall/ Reset nicht wieder alles neu einstellen zu müssen.
Hier mal ein Teil meines Programms:
Wenn ich die Speierung von IO_Feld weg lasse funktioniert alles soweit,
erst wenn ich IO_Feld ins eprom schreibe überschreibt er glaube meine
vorherigen werte!
Warum?
Habt Ihr eine Idee?
gruß
Matthias und danke schon mal für eure hilfe.
solltest du nicht
lesen(); //Eprom lesen
i2c_init(); //I2C-Bus einrichten
tauschen
i2c_init(); //I2C-Bus einrichten
lesen(); //Eprom lesen
in der Annahme es ist ein I2C EEprom
Gruß
Andi
Hallo,
es handelt sich bei den Eprom um den internen 4K Byte Eprom von einen
ATmega2560.
Aber du hast recht es wäre schöner erst die Init's fertig zu machen und
dann zu lesen.
So hab's mal in einer anderen Reihenfolge geschrieben:
void schreiben(void)
{
eeprom_busy_wait ();
eeprom_update_block (IO_Feld, eeprom_def_IO_Feld, sizeof(IO_Feld));
eeprom_busy_wait ();
eeprom_update_byte(&eeprom_def_EEProm_beschrieben, 1);
eeprom_busy_wait ();
eeprom_update_word(&eeprom_def_Rel_out_mask, Rel_out_mask);
eeprom_busy_wait ();
eeprom_update_word(&eeprom_def_Rel_auto_mask, Rel_auto_mask);
}
jetzt geht es!?! aber warum? Warum überschreibt IO_Feld die ersten Eprom
Speicherzellen?
Ich glaube nicht daß es jetzt geht. Durch die andere Reihenfolge werden
jetzt halt nur andere Daten überschrieben. Hast du denn mal ins mapfile
geschaut, auf welche Adressen deine EEMEM Variablen gemappt werden?
Randbemerkungen:
1. es heißt EEPROM, nicht EPROM. Das ist ein himmelweiter Unterschied!
2. das ganze busy_wait() Getue kannst du dir sparen. Lies die Doku!
3. zwischen Funktionsname und öffnende Klammer gehört kein Leerzeichen.
XL
Hallo und DANKE erst mal für deine Unterstützung.
Ich bin mir nicht sicher aber ich glaube du meinst diesen eintrag aus
der *.map:
.eeprom 0x00810000 0xce
*(.eeprom*)
.eeprom 0x00810000 0xce lcd_menu.o
0x00810000 eeprom_def_Licht_GW
0x00810001 eeprom_def_IO_Feld
0x008100c9 eeprom_def_Rel_auto_mask
0x008100cb eeprom_def_Rel_out_mask
0x008100cd eeprom_def_EEProm_beschrieben
0x008100ce __eeprom_end = .
sehe ich das richtig, mein EEprom fängt bei Adresse 0x00810000.
und eeprom_def_Licht_GW (uint8_t) liegt da.
eeprom_def_IO_Feld (uint16_t eeprom_def_IO_Feld[20][5]) fängt bei
0x00810001 an und geht bis 0x008100c8 also besitzt 0Xc8 Adressen => 200.
Mein IO_Feld in der *.h mit "extern uint16_t IO_Feld[20][6];" deklariert
und da ist schon der erste Fehler (einmal [20][5]und einmal [20][6])!
Warum aber bei IO_Feld[20][5] 200 Adressen und bei IO_Feld[20][6] 240
Adressen?
0-20=21 und 0-5=6 =>21*6=126 Adressen ?!? oder Gedanken Fehler.
So ich glaube der Fehler ist weg war wohl die IO_Feld[20][5] Sache. Aber
das mit der anzahl der Adressen würde ich auch ganz gerne mal wissen.
gruß
Matthias
LaserBrenner schrieb:> Warum aber bei IO_Feld[20][5] 200 Adressen und bei IO_Feld[20][6] 240> Adressen?
Dann frag dich mal wieviele Bytes dein Array "IO_Feld[20][5]" mit dem
Datentyp "uint16_t" im EEPROM wohl belegt.
gruß
Cecky
na hab ich doch schon versucht
0-20=21 und 0-5=6 =>21*6=126 Adressen ?!? oder Gedanken Fehler.
wenn es stimmt das 2 Byte pro Adresse Platz haben!
126 Felder mal 2Byte = 252 Byte - macht doch 126 Adressen?!?
gruß
LaserBrenner schrieb:> 0-20=21 und 0-5=6 =>21*6=126 Adressen ?!?
??? Da kommt bei meiner Rechnung aber was anderes raus:
IO_Feld[20][5] = 100 Elemente * uint16_t = 200 Byte
LaserBrenner schrieb:> wenn es stimmt das 2 Byte pro Adresse Platz haben!
Wie kommst du da drauf?
gruß
Cecky
LaserBrenner schrieb:> Warum aber bei IO_Feld[20][5] 200 Adressen und bei IO_Feld[20][6] 240> Adressen?> 0-20=21 und 0-5=6 =>21*6=126 Adressen ?!? oder Gedanken Fehler.
Öh,
Ein Array
1
inttest[5];
hat 5 Elemente.
test[0], test[1], test[2], test[3], test[4]
Zähl nach, es sind genau 5 Elemente.
Bei der Definition gibst du die Länge an und nicht den höchsten Index!
[20][5] sind daher 20*5 gleich 100 Arrayelemente und wenn jedes
Array-Element 2 Bytes gross ist, dann sind das 200 Bytes.
> So ich glaube der Fehler ist weg war wohl die IO_Feld[20][5] Sache. Aber> das mit der anzahl der Adressen würde ich auch ganz gerne mal wissen.
Du solltest dir zumindest das erste Drittel eines ordentlichen C Buchs
durcharbeiten. Das sind ziemliche Basics.
LaserBrenner schrieb:> Mein IO_Feld in der *.h mit "extern uint16_t IO_Feld[20][6];" deklariert> und da ist schon der erste Fehler (einmal [20][5]und einmal [20][6])!
Jetzt hast du auch rausgefunden, warum man derartige Konstanten (sog.
magische Konstanten) nicht direkt in den verwendenden Code schreibt,
sondern sich einen #define dafür macht. Denn dann passiert einem sowas
nicht
Jetzt kann es dir per Defintion nicht mehr passieren, dass dir die
Zahlen auseinanderlaufen. Denn die konkrete Zahl steht nur an EINER
EINZIGEN Stelle im ganzen Programm und alle verwendenden Stellen
beziehen sich darauf. Ändert sich die Anzahl, dann ändert man das an
EINER Stelle und der Rest des Codes (inklusive von zb. for-Schleifen,
die zur Abarbeitung der Arrays benutzt werden) werden durch den
Präprozessor angepasst ohne dass du dich groß darum kümmern musst.
Hallo Ihr guten,
vielen vielen Dank für eure Erklärung, auch den Tip von Karl Heinz werde
ich zukünftig beherzigen :-) und mir auch nochmal ein paar Grundlagen
aneigenen.
also nochmal Danke, toll das es Menschen wie euch gibt...
gruß
Matthias
LaserBrenner schrieb:> Hallo Axel,> kannst du mir nochmal einen Link geben, wegen der Busy_wait Sache - find> nur Erklärungen wo es verwendet wird.http://www.nongnu.org/avr-libc/user-manual/group__avr__eeprom.html
"All of the read/write functions first make sure the EEPROM is ready to
be accessed. Since this may cause long delays if a write operation is
still pending, time-critical applications should first poll the EEPROM
e. g. using eeprom_is_ready() before attempting any actual I/O."
XL