Hallo Leute,
ich möchte in meinem Programm bestimmte Variablen im EEPROM speichern,
um diese später wieder laden zu können. Ich kriege das irgendwie aber
nicht hin.
Arbeite mit der avr-libc (#include <avr/eeprom.h>).
Wenn ich jetzt aber was an eine Adresse schreiben möchte (siehe
Quelltext) wird immer an die Adresse 0x007A geschrieben, egal was ich
übergebe. Woran liegt das?
1
uint8_ti1;
2
uint16_ti;
3
4
// Anfangsadresse generieren
5
i=temp*5;
6
// Warten bis EEPROM bereit ist
7
eeprom_busy_wait();
8
// Word STEPS in EEPROM schrieben
9
eeprom_write_word(&i,STEPS);
10
// Adresse um 2 erhöhen (2Byte (1Word) weiter)
11
i1=(uint8_t)i+2;
12
// Warten bis EEPROM bereit ist
13
eeprom_busy_wait();
14
// Byte FREQ in EEPROM schreiben
15
eeprom_write_byte(&i1,FREQ);
16
// Adresse um 1 erhöhen (1Byte weiter)
17
i1++;
18
// Warten bis EEPROM bereit ist
19
eeprom_busy_wait();
20
// Byte VREF in EEPROM schreiben
21
eeprom_write_byte(&i1,VREF);
22
// Adresse um 1 erhöhen (1Byte weiter)
23
i1++;
24
// Warten bis EEPROM bereit ist
25
eeprom_busy_wait();
26
// Byte L297 in EEPROM schreiben
27
eeprom_write_byte(&i1,L297);
Ich bitte um eure Hilfe... Oder kann es auch einfach sein, dass der
Simulator im AVR-Studio das nicht ganz hinkriegt?
MfG
Muecke
Du veränderst den Inhalt von i und i1 übergibst der Funktion
eeprom_write_word aber nur die Adresse von i/i1. Diese wird aber mit der
Deklaration schon festgelegt und ändert sich dann nicht mehr.
Wenn Du also überall das '&'-Zeichen entfernst, sollte es klappen.
Also der Deklaration von eeprom_write_byte nach, wird die Adresse als
Zeiger übergeben. Warum auch immer. Demnach hättest Du es ursprünglich
richtig gemacht.
Offensichtlich muß aber doch die Adresse als Wert übergeben werden.
Sonst hätte er beim ersten Versuch nicht immer an die selbe Adresse
geschrieben.
Evtl. hilft ein Cast:
eeprom_write_word((uint16_t *)i, STEPS);
Kann aber echt nicht sagen, was hier das Zeigergeraffel soll...
OK. Danke...
Bei dem eeprom_write_word(...) funktioniert das mit dem cast zum pointer
(Keine Warnung mehr). Wenn ich dann den cast entsprechend so anwende
1
eeprom_write_byte((uint8_t*)i1,VREF)
bekomme ich folgende Warnung:
1
casttopointerfromintegertodifferentsize
Aber es wird laut Dolumentation doch ein Pointer vom typ uint8_t *
erwartet. Was hat denn da jetzt ne flasche Größe?
MfG
Muecke
Die Adresse muß in jedem Fall 16-Bit breit sein. Der M8 hat z.B. 512Byte
EEPROM. Mit einer 8-Bit-Adresse könnte man max. 256Byte adressieren.
Die Dokumentation sagt zwar:
1
voideeprom_write_byte(uint8_t*addr,uint8_tval)
aber ich glaube die ist Schrott...
Probiers mal so:
1
eeprom_write_byte((uint16_t*)i1,VREF);
Ich weiß schon, warum ich die Biester immer in Assembler programmiere...
;-)
Ja, ich habe mich auch schon gewundert, warum ich da ne 8bit-Adresse
übergeben muss... Naja, so ganz gibt das kein Sinn.
Danke für die Hilfe...
MfG
Muecke
Wie wäre es, wenn ihr beiden C Helden euch mal
im Tutorial anschaut wie man das richtig macht.
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#EEPROM> warum ich da ne 8bit-Adresse übergeben muss...
Ein uint8_t * ist keineswegs eine 8 Bit Adresse.
Die Adresse hat soviele Bits wie das System vorschreibt
das ein Pointer haben soll. Aber das worauf der Pointer
zeigt, das hat 8 Bit. Und nachdem ein Byte 8 Bit hat, ist
ein uint8_t * in
1
voideeprom_write_byte(uint8_t*addr,uint8_tval)
absolut ok und auch richtig. Du willst 1 Byte schreiben, also
brauchst du auch einen Pointer der auf 1 Byte zeigt.
Hallo Herr Buchegger,
danke für den Tip auf das Tutorium, aber das habe ich mir schon
angeschaut und steige da nicht wirklich durch.
Sag mir doch bitte mal konkret, was ich in dem obigen Quelltext
verändern muss, damit im EEPROM die Variablen STEPS (18bit), FREQ, VREF
und L297 (8bit) hintereinander geschrieben werden, ab einer bestimmten
Anfangsadresse?+
MfG
Muecke
> ab einer bestimmten Anfangsadresse?+
Ist es wichtig, dass die Anfangsadresse vergeben werden kann.
Wenn nicht, dann benutze den EEMEM Ansatz wie im Tutorial.
Wenn die Adresse allerdings wichtig ist, dann kannst du das
zb so machen:
Aber das Prinzip ist immer das gleiche:
Wenn ich das Zeugs auf eine bestimmte Adresse haben will, dann
nehme ich die Adresse als Zahlenwert und caste den Zahlenwert um
in den benötigten Pointertyp.
Danke für die Hilfe...
Mein Problem besteht darin, dass die Anfangsadresse erst über den
I2C-Bus übermittelt wird. Daraus berechnen sich dann die weiteren
Adressen.
Ich habe bei meinem uC 32 Speicherplätze vorgesehen, die über den
I2C-Bus angesprochen werden können...
Das höherweritge Nibble bestimmt ob gelesen, oder geschrieben werden
soll (0xC... und 0xD... laden, 0xE... und 0xF... speichern).
das untere Nibble bestimmt dann die Speicherstelle und somit auch die
Anfangsadresse. Da ich 5Bytes in das EEPROM schreibe, multipliziere ich
das niederwertige Nibble mit 5 und habe somit meine Anfangsadresse.
z.B.:
Es wird 0xE0 empfangen:
speichern, da oberes Nibble = E
Anfangsadresse = 0 * 5 = 0
Es wird 0xE2 empfangen:
speichern, da oberes Nibble = E
Anfangsadresse = 2 * 5 = 0xA
MfG
Muecke
Christian Schmalor wrote:
> Danke für die Hilfe...>> Mein Problem besteht darin, dass die Anfangsadresse erst über den> I2C-Bus übermittelt wird. Daraus berechnen sich dann die weiteren> Adressen.
OK. Dann muss die Adresse in eine Variable.
Danke dir für deine Hilfe....
Ich werde es jetzt in meinem Programm versuchen umzusetzen...
Wenn ich das Programm jetzt simuliere im avr-studio und mir das struct
in mein "Watch"-Window hole, kann ich alle Variablen ja ein Wert
zuweisen, nur nicht der letzten Variable im Struct, warum? Alle anderen
Variablen kann ich dort Werte zuweisen, ur nicht der letzten Variable im
Struct. Ich habe die Variablen im Struct vertauscht und es geht nicht
bei der letzten Variablke im Struct. Ich habe es so definiert:
struct config_t{
uint16_t STEPS;
uint8_t FREQ;
uint8_t VREF;
uint8_t L297;
}Config;
Christian Schmalor wrote:
> Wenn ich das Programm jetzt simuliere im avr-studio und mir das struct> in mein "Watch"-Window hole, kann ich alle Variablen ja ein Wert> zuweisen, nur nicht der letzten Variable im Struct, warum?
Keine Ahnung.
Fehler im AVR Studio
Fehler im Debugger