Hallo, ich hab ein Problem mit einer Variablen. Also ich hab den Fehler nach langem suchen eingrenzen können. Es liegt an der Variablen in meinem Programm, die die Anzahl der ADC-Messungen, über die ein Mittelwert gebildet wird, angibt. Ich setze den Wert z.Z. auf zwei. Wenn das Programm aber auf dem µC gespielt wird, lass ich mir z.Z. die Variable auf den LCD anzeigen, sie ist null. Ich hab im Programm geschaut, aber rufe diese Variable nur beim auslesen des ADCs auf. Deklariert ist sie in einer C-Datei in der alle veränderbaren Variablen stehen. Witzig ist, dass wenn ich die Variable umbenenne (Rename in AVR-Studio5), funktioniert es und sie wird auf dem LCD als 2 angezeigt. Woran kann sowas liegen? Ich benutze unteranderem long long Zahlen. Kann dies zu instabilitäten führen. (Benutzten sollte man sie ja nicht unbedingt, aber ich hab Zeitdruck und bin froh wenn es erstmal läuft. Im zweiten Anlauf möchte ich die long long Variablen aus dem Programm nehmen) Vielleicht kann mir jemand einen Tipp geben. Vielen Dank. Kai µC: AT90CAN128 Software: AVR-Studio 5 (zum kompilieren) AVR-Studio 4.19 (zum flashen mit JTAGer Nachbau) Ausschnitte aus dem Programm: In h-Datei: unsigned int quantity_readout; In C-Datei: quantity_readout=2; In ADC: for( i=0; i<quantity_readout; i++ ) { ADCSRA |= (1<<ADSC); while ( ADCSRA & (1<<ADSC) ) { ; } result += ADCW; } ADCSRA &= ~(1<<ADEN); result /= quantity_readout;
Es gibt bei Fehlersuche via Forum eine Daumenregel: Ziemlich oft liegt der Fehler nicht in den 10 Zeilen, in denen man ihn nach tagelanger Suche selbst vermutet aber nicht findet, oder ist darin jedenfalls für Dritte nicht erkennbar. Es ist daher oft nicht zielführend, nur exakt diese Zeilen aus dem Kontext zu reissen und zu posten. Verschärfend kommt manchmal hinzu, dass nicht der Code selbst sondern ein erdachtes Äquivalent gepostet wird, in dem genau das Problem nicht mehr enthalten ist.
Ja das stimmt sicher. Aber wie kann sowas sein, dass eine Variable funktioniert, wenn ich sie zum Beispiel quantity_readout2 nenne und ohne die 2 funktioniert sie nicht. Ich kenne mich mit der tieferen Materie was beim kompilieren passiert nicht aus.kann es dort zu solchen fehlern führen? ICh wollte auch nicht das jemand den Fehler findet. Ich kann sie ja umbenennen (dann funktioniert es) , aber ich hoffe, dass die Profis hier einfach mehr verständnis haben und sofort diesen Fehler erkennen, anhand des Verhaltens. Kann es sein, dass AVR-Studio 5 beim kompilieren was überschreibt? Kommt sowas vor?
Das
1 | unsigned int quantity_readout; |
gehört in die .c, nicht in die .h in die .h gehört dann ein
1 | extern unsigned int quantity_readout; |
Kai Krestegal schrieb: > die 2 funktioniert sie nicht. Ich kenne mich mit der tieferen Materie > was beim kompilieren passiert nicht aus.kann es dort zu solchen fehlern > führen? Ich kenne mich auf der Ebene etwas besser aus und ja, so etwas kann das Verhalten eines fehlerhaften Programmes verändern. > Kann es sein, dass AVR-Studio 5 beim kompilieren was > überschreibt? Ja selbstverständlich. Da werden ein paar Dateien auf deinem PC überschrieben.
DirkB schrieb: > in die .h gehört dann ein > extern unsigned int quantity_readout; Nur führt das entweder zu einer Fehlermeldung des Compilers oder es ist nicht das eigentliche Problem.
Wie A.K. schon schrieb hat das dazu geführt, dass der Kompiler Fehlermeldungen auswirft. Ich werd die Variable erstmal umbenennen. Aber sinn macht das ja eigentlich nicht,oder??
Da meckert nicht der Compiler. Das sollte zu einer Meldung des Linkers führen.
Bei mir kamen aber Fehlermeldungen. Aber ich glaub ich hab sicher soviel saukram in meinem Programm, es ist ein wunder, dass es läuft. Aber danke für eure Hilfe. Ich hab die Variabel jetzt readout_quantity genannt. Komisch ist ja, das das Programm mit dem vorher genannten Namen lief, als ich noch beim schreiben des Programms war. (immer mal wieder getestet)
Variable ist 0, obwohl sie 2 sein sollte? Problem verschwindet, wenn anderer Name? => Ich setzte mein Geld auf ein String-Array, welches um 1 zu kurz ist. Es sind aber noch andere Szenarien denkbar, z.B. Stack-Überlauf.
Kai Krestegal schrieb: > Wie A.K. schon schrieb hat das dazu geführt, dass der Kompiler > Fehlermeldungen auswirft. <seufz> Wer sowas ignoriert, bei dem ist Hopfen und Malz verloren. Gibts noch weitere "völlig unwichtige" Fehlermeldungen und Warnungen? > Ich werd die Variable erstmal umbenennen. Aber sinn macht das ja > eigentlich nicht,oder?? Damit löst du nicht das Problem, du deckst es nur zu. Du solltest das tun, was Dirk geschrieben hat.
Kai Krestegal schrieb: > Aber danke für eure Hilfe. Ich hab die Variabel jetzt readout_quantity > genannt. Das behebt aber mit Sicherheit nicht dein ursprüngliches Problem. Du hast es nur an eine Stelle verlagert, wo es im Augenblick keine sichtbaren Symptome hat.
Ja ich sollte die Ursache bekämpfen und nicht nur das Symptom. Es wird sicher zufällig grad diese Variable gewesen sein. Beim nächsten mal eine Andere. Ich werd es nochmal mit dem extern versuchen.
Error 62 undefined reference to `quantity_readout' (adc.c) Error 2 expected 'const uint16_t *' but argument is of type 'unsigned int' (eeprom.h) Error 54 expected 'const char *' but argument is of type 'unsigned char *' (lcd-routine.h) Error 2 und 54 kommen häufiger in der eeprom.h und lcd-routine.h vor.
DirkB schrieb: > unsigned int quantity_readout;gehört in die .c, nicht in die .h > > in die .h gehört dann einextern unsigned int quantity_readout; hab es wie oben geändert
Mach nur weiter so und lüg dir selber in die Tasche. M.a.W: Komm wieder, wenn du sämtliche Fehler und vorzugsweise auch sämtliche Warnungen los bist. Und sie nicht bloss zugedeckt hast. Bis dahin ist das völlig witzlos.
Variablen definitionen gehören in die .c Variablen deklarationen kommen in die .h Aus wievielen Modulen besteht denn dein Programm?
A. K. schrieb: > lüg dir selber in die Tasche. Ich hab doch grad angefangen das Problem (Ursache) zu suchen. Hol doch dann nicht gleich die verbale Brechstange raus. Bin ja gewollt zu lernen.
DirkB schrieb: > Variablen definitionen gehören in die .c > Variablen deklarationen kommen in die .h > > Aus wievielen Modulen besteht denn dein Programm? So hab ich es auch bis jetzt aufgebaut. Und Variablen die auch in anderen Funktionen stehen, werden im Header deklariert. Meint Module die Funktionen? 12 C-Dateien 14 H-Dateien Im Programm benutz ich Timer,ADC,LCD,IO-PORTS,EEPROM,einige Berechnungen. Wo ich noch einen Fehler vermute sind diese long long Variablen. Könnten die zu solchen Fehlern führen? Oder meine dermaßen deletantische EEPROM Speicherung mit fester Adresse.
Kai Krestegal schrieb: > So hab ich es auch bis jetzt aufgebaut. Und Variablen die auch in > anderen Funktionen stehen, werden im Header deklariert. So bekommt jede .c Datei (die ja alle seperat compiliert werden) eine eigene Variable mit dem selben Namen. Der Linker versucht nun die unter einen Hut zu bekommen. Das sollte eine Meldung geben. Das willst du so nicht haben. Darum werden die Variablen nur einmal in einer .c deklariert. Für die anderen .c erfolgt die Deklaratin über das extern.
Mist. Es muss heißen: Darum werden die Variablen nur einmal in einer .c definiert. Für die anderen .c erfolgt die Deklaration über das extern.
DirkB schrieb: > So bekommt jede .c Datei (die ja alle seperat compiliert werden) eine > eigene Variable mit dem selben Namen. > Der Linker versucht nun die unter einen Hut zu bekommen. Das sollte eine > Meldung geben. Also ich deklariere die Variable nur in einer Header-Datei. Nicht in mehreren. Vielleicht hab ich mich blöd ausgedrückt oder hab es falsch verstanden.
Du inkludierst diese Headerdatei doch sichelich in mehreren C-Dateien. Da das #include des Preprozessors aber nur reiner Textersatz ist, steht dann in jeder C-Datei (in der der Header eingebunden wird) auch diese Definition.
Ich werd das morgen weiter machen. Vielleicht seh ich dann wieder mehr. Danke euch für die Hilfe! Wünsch allen noch einen schönen Abend. Kai
DirkB schrieb: > Du inkludierst diese Headerdatei doch sichelich in mehreren C-Dateien. Ja genau. Ich hab eine große includes.h in der stehen alle Header, die dann in jeder Funktion eingebunden werden. Aber ich beginne und ende die Header mit folgendem Zusatz: Beispiel: #ifndef PORTS_H_ #define PORTS_H_ void init_ports(void); #endif /* PORTS_H_ */ Dadurch sollte es doch nur einmal eingebunden werden oder?
Kai Krestegal schrieb: > Dadurch sollte es doch nur einmal eingebunden werden oder? Schon, aber in jeder C-Datei. Jede C-Datei wird für sich compiliert. Dabei hat der Compiler kein Wissen aus anderen Compilerläufen. Es läuft erst der Preprozessor über die Datei. Diesee ersetzt die #includes durch den Inhalt der entsprechenden Datei und expandiert noch die Makros/defines. Du kannst dir den Preprozessor-Output auch anschauen (Du musst die Compileroption setzten, die diese Datei erzeugt, bzw. nicht löscht) Der Compiler erzeugt dann aus den .c die Objectdateien (.o oder .obj) Diese werden dann vom Linker zu einem ausführbaren Programm gebunden.
Okay, tausend dank schon mal. Das schau ich aber morgen. Werd nun erstmal an der Matratze horchen. Wünsch einen schönen Abend.
So mal ein Update hab die Ursache auf ein String Array eingrenzen können. Wenn ich diese aus dem Programm nehme, wird die Variable richtig angezeigt. Stefan Ernst schrieb: > Autor: Stefan Ernst > (sternst) > Datum: 25.02.2012 20:59 > > Variable ist 0, obwohl sie 2 sein sollte? > Problem verschwindet, wenn anderer Name? > => Ich setzte mein Geld auf ein String-Array, welches um 1 zu kurz ist. > > Es sind aber noch andere Szenarien denkbar, z.B. Stack-Überlauf. Ich habe das Array wie folgt deklariert: char supply_price_string[5]; In der Funktion wird folgendes gemacht: /* supply price -> int to string */ supply_price_string[0]=(supply_price_int/1000)+48; supply_price_string[1]=46; supply_price_string[2]=((supply_price_int%1000)/100)+48; supply_price_string[3]=((supply_price_int%100)/10)+48; supply_price_string[4]=((supply_price_int%10)/1)+48; supply_price_string[5]='\0'; Wenn ich diese Funktion entferne, läuft alles wieder.
Mit einer länge von 6 geht es auch wieder? char supply_price_string[6];
Ein Array aus 5 Elementen in das du 6 Elemente reinschreibst findest du normal?
Nicht? Sry, aber jetzt nicht anfangen rum zu meckern. Ich dachte da ist immer noch die 0 am Anfang ein Element
Kai Krestegal schrieb: > Ich dachte da ist immer noch die 0 am Anfang ein Element Ja, da schon, aber das Element [5] exitiert nicht, nur 0..4. Besorg dir ein ordentliches C Buch. Interessanterweise haben sich beide Prophezeihungen bestätigt. Der Fehler lag nicht in den von dir geposteten Zeilen und es war ein Array-Überlauf. > Sry, aber jetzt nicht anfangen rum zu meckern. Meine Antwort bezog sich auf dein vorheriges Posting. Dass dir in gleicher Minute selber der Groschen fiel war mir da noch nicht bekannt.
Eine Kleinigkeit am Rande: Aus supply_price_string[0]=(supply_price_int/1000)+48; machst du besser supply_price_string[0]=(supply_price_int/1000)+'0';
A. K. schrieb: > supply_price_string[0]=(supply_price_int/1000)+'0'; Ah okay danke. Man jetzt kann ich doch froh sein, dass ich den Fehler gefunden hab und nicht wie gestern Abend den Fehler nur verschieben wollte. Danke euch allen für die große Hilfe! Wünsch euch noch einen schönen Sonntag. Kai
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.