Variable mit merkwürdigem Verhalten

OP #2566417
Lesenswert?

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;
#2566420
Lesenswert?

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.
OP #2566428
Lesenswert?

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?
#2566433
Lesenswert?

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.
OP #2566459
Lesenswert?

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)
#2566463
Lesenswert?

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.
OP #2566492
Lesenswert?

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.
OP #2566507
Lesenswert?

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.
Gast #2566514
Lesenswert?

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.
OP #2566536
Lesenswert?

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.
Gast #2566542
Lesenswert?

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.
OP #2566550
Lesenswert?

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?
Gast #2566571
Lesenswert?

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.
OP #2566854
Lesenswert?

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.
#2566860
Lesenswert?

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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren