Hallo!
Ich habe das folgende Problem: Ich will beim Initialisieren bereits im
EEPROM abgelegten Daten nacheinander in ein Array einlesen, um sie im
weiteren Programmverlauf zu verwenden, habe aber ein Problem mit der
Adresse der einzulesenden Bytes. Der Code dazu sieht folgendermaßen aus:
1
voidinit(void)/* Initialisiert den Mikrocontroller*/
Der Compiler bringt eine Warnung, und wenn ich das Programm auf dem
Mikorcontroller übertrage, bleibt er beim Initialisieren hängen. Ich
weiß, dass eeprom_read_byte() eine Adresse als Parameter benötigt,
dennoch müsste es so auch ohne Typecast funktionieren. Ich habe schon
alles abgesucht und es scheint alles richtig zu sein. Vielleicht habe
ich etwas übersehen? Für Eure Hilfe wäre ich sehr dankbar!
Es handelt sich um den ATMEGA16 Controller
Für den ATmega16 wird in der avr-libc ein Workarount für einen bekannten
Silicon-Bug nicht implementiert, möglicherweise ist's das? (der µC löst
eine IRQ aus, was zu einem RESET führt, wenn die entsprechende ISR nicht
implementiert ist)
Beitrag "Re: Riesige Änderungen zwischen WinAVR 030913 und der aktuellen Version?"
BTW: wie wär's mit eeprom_read_block?
Die Warnung lautet:
warning: passing argument 1 of 'eeprom_read_byte' makes pointer from
integer without a cast
Habe es bereits probiert mit eeprom_read_block(). Die dazugehörige Zeile
müsste dann so heißen, oder?
Das Ergebnis ist aber das Gleiche, der Mikrocontroller kommt über das
Auslesen nicht hinaus.
Eine andere interessante Sache, die ich festgestellt habe: Das Programm
läuft wenn ich mit Optimierungsstufen "s" oder "3" kompiliere. Ich
brauche es aber ohne Optimierung, da mir ansonsten die eingebauten
Warteschleifen wegopitmiert werden. Die sind aber notwendig, da der
Mikrocontroller einen Flachbildschirm ansteuern muss, der da nicht
mitziehen würde.
>Ich>brauche es aber ohne Optimierung, da mir ansonsten die eingebauten>Warteschleifen wegopitmiert werden. Die sind aber notwendig, da der>Mikrocontroller einen Flachbildschirm ansteuern muss, der da nicht>mitziehen würde.
Das ist kein Argument für delay! Dafür gibt es Timer.
PS: Damit Warteschleifen nicht wegoptimiert werden, must du die
Zählvariable volatile deklarieren.
Mal ne Frage:
>warning: passing argument 1 of 'eeprom_read_byte' makes pointer from>integer without a cast
Die Fehlermeldung bekomme ich immer, wenn ich eine Variable übergebe, wo
eigentlich die Adresse derselben Variable hin soll.
Da du hier aber den Inhalt der Variablen als Adresse haben willst,
könnte das evtl der Grund sein warum das nicht geht.
Der Compiler könnte (durch die Warnung angezeigt) da die (SRAM)Adresse
der Variablen eepr_addr übergeben. Somit wird mit einer SRAM-Adresse
im EEPROM gesucht.
Mach das mal richtig, so wie es gedacht ist:
Ich kann es zwar anders probieren mit den Warteschleifen, aber das tut
ja nichts zur Sache. Fakt ist, dass ein Befehl, der funktionieren
sollte, einfach nicht funktioniert, obwohl die Syntax richtig zu sein
scheint.
Also einfach nur "long volatile warten"? Damit funktioniert es nicht
>Die Fehlermeldung bekomme ich immer, wenn ich eine Variable übergebe, wo >eigentlich die Adresse derselben Variable hin soll.
Eben, bei mir ist es nicht so, dass ich die Adresse der Variable
"eepr_addr" haben will, da diese Adresse sich irgendwo im RAM befindet
und in meiner Ausleseschleife der Wert von "eepr_addr" zwar erhöht wird,
aber die Adresse bleibt ja gleich. Demnach würde so in das ganze Array
die gleiche Bitfolge eingeschrieben werden, falls ich "&eepr_adr"
verwenden würde. So würde es zwar der Compiler ohne wenn und aber
schlucken, aber es müsste ohne "&" richitg funktionieren. Ich versuche
es aber gliech mal mit
>Also einfach nur "long volatile warten"? Damit funktioniert es nicht
1
volatilelongwarten
>Eben, bei mir ist es nicht so, dass ich die Adresse der Variable>"eepr_addr" haben will, da diese Adresse sich irgendwo im RAM befindet>und in meiner Ausleseschleife der Wert von "eepr_addr" zwar erhöht wird,>aber die Adresse bleibt ja gleich.
Wenn die (zu lesende EEPROM) Adresse immer gleich bleibt, könnte das ja
die ursache sein.
Vielleicht solltest du es doch mit einem Cast (des Wertes auf Adresse)
probieren:
@ Matthias
Die Adresse würde nur dann gleich bleiben, wenn ich ein "&" davor
verwende. Deshlab wäre ohne schon richtig. Den von Dir vorgeschlagenen
Typecast habe ich bereits vor dem Post ausprobiert. Bringt aber nichts.
Habe Deinen Vorschlag mit
uint8_t VarImEE[40][8] EEMEM;
uint8_t letter[40][8];
...
eeprom_read_block( letter, VarImEE, sizeof(VarImEE) );
nun ausprobiert.
Auch damit ist es so, dass es ohne Optimierung nicht funktioniert. Ganz
nebenbei gefragt: es müsste ja egal sein, ob sich das Array
"VarImEE[40][8]" im EEMEM befindet oder nicht? Denn die einzige
Verwendung davon ist nur die Abfrage der Arraygröße mit
"sizeof(VarImEE)". Da ich weiß, dass ich ab der Adresse 0 auslesen will,
klappt es bei mir auch in der Form:
>Die Adresse würde nur dann gleich bleiben, wenn ich ein "&" davor>verwende. Deshlab wäre ohne schon richtig.
Nein eben nicht. Deine oben gepostete Warnung sagt doch aus, dass der
Compiler ein Pointer draus gemacht hat. Also macht er von allein ein &
davor!
>es müsste ja egal sein, ob sich das Array...
Sollte so sein.
Ich habe es jetzt hinbekommen. Es handelt sich bei dem Problem ganz
offensichtlich um einen Bug des Compilers. Ein Kollege hatte
glücklicherweise eine ältere Version von WinAVR mit der GCC Ver. 3.4.5.
Mit dieser Version hat er auch seinerzeit sein Programm compiliert,
welches gelaufen ist und auf dem ich meins aufgebaut habe. Nachdem ich
mir die alte Compiler-Version draufgespielt habe, hat es auf ein Mal
funktioniert, auch mit dem von mir anfangs geposteten Code. Wobei ich
mich dann für die von Matthias vorgeschlagene Methode mit
eeprom_read_block() entschieden habe, da dann auch der Compiler
zufrieden ist und ohne Warnung wegen der Parameterübergabe auskommt.
Schon ärgerlich das Ganze, dnen ich habe drei Tage lang nichts Anderes
gemacht als diese eine Zeile angestarrt und alles Mögliche ausprobiert,
ohne Aussicht auf Erfolg.