Forum: Mikrocontroller und Digitale Elektronik Mega32 C - Problem


von zaydo (Gast)


Lesenswert?

Moin,

ich verzweifele ;-)
Gegeben ist eine Schleife, in der eine Funktion aufgerufen wird:

void konfiguration_Standheizung (void)
   {
   // Darstellung auf LCD
   SH.Steuern = konfiguration_JaNein (SH.Steuern,
                KONFIG_STEUERN_POSITION, txtSteuern);
   // Tastenabfrage mit Rücksprung
   }

Die Struktur SH ist global definiert; alle Typen passen zueinander.
KONFIG_STEUERN_POSITION enthält die x-Koordinate, txtSteuern den Text
für das Display.
In konfiguration_JaNein wird über eine Tastenabfrage der Wert von
SH.Steuern zwischen 0 und 1 umgeschaltet.

unsigned char konfiguration_JaNein (unsigned char frage,
                                    unsigned char pos, char *text)
   {
   ...
   frage = KONFIG_JA;  // 1
   ...
   oder
   frage = KONFIG_NEIN; // 0
   ...
   return frage;
   }

Es laufen derzeit mit Ausnahme der Tastaturabfrage keine Interrupts,
die irgendwelche Werte verändern.

Mit ca. 8 Strukturen, die sehr ähnlich wie SH aufgebaut sind,
funktioniert dieses Konstrukt einwandfrei. Nur mit SH nicht.
SH.Steuern wechselt ohne erkennbares Muster seinen Wert :-(
Ist der z.B. vor dem Aufruf von konfiguration_JaNein 1, wird ab und an
1 übergeben, meist hat frage jedoch einen anderen Wert. Das Gleiche
passiert beim return; es ist in SH.Steuern ein anderer Wert als von
konfiguration_JaNein zurückgegeben.

Wie gesagt, mit allen anderen Strukturen passiert das nicht. Auch nicht
mit einer identischen, mit der ich das testweise probiert habe.
Es gibt keine die Werte manipulierenden Interupt-Routinen, es wird auch
sonst nirgends auf SH zugegriffen!

Ich habe 2 µCs ausprobiert, den Compiler (ICC) mal mit und mal ohne
Komprimierung laufen lassen; es gibt keinerlei Warnungen. Hat alles
nicht geholfen.

Warum passiert das nur bei der einen Struktur?

Mir ist klar, dass es irgendwo im Programm einen Fehler geben kann, der
dafür verantwortlich ist. Ich finde ihn aber nicht. Und ich kann hier
natürlich nicht 30K Code posten ;-)
Deswegen die Frage:

Welcher typischer Fehler könnte dafür verantwortlich sein?


Danke, zaydo

von Karl H. (kbuchegg)


Lesenswert?

typische Fehler für Variablen die scheinbar
ohne Grund ihre Werte verändern sind:

* zu 90%: irgendwo wird ein Array überlaufen. zb.
  Du hast ein Array mit 4 Elementen definiert, beschreibst
  aber munter das Element Nr. 5, 6, use.
* Besonders interressant wird dieses Verhalten, wenn das
  Array am Stack existiert (also funktionslokal ist) und
  dabei zufällig die Returnadresse beschädigt wird.
* Die restlichen typischen Fehlerfälle basieren auf einem
  ähnlichem Prinzip, nur erfolgt der schreibende Zugriff über
  einen Pointer. Entweder wieder ein Array 'out of bounds'
  beschreiben oder aber der Pointer war von vorne herein
  schon ungültig und zeigte 'In den Wald'.

Viel Spass beim Suchen
(OK: Der war gemein. Den nehme ich zurück)

von zaydo (Gast)


Lesenswert?

Moin Karl,

danke. Und kein Problem mit dem "Viel Spass" ;-)

An ein Array hatte ich auch gedacht, weil ich doch einige verwende.
Das hatte ich aber dann ausgeschlossen, weil a.) alles gut aussah und
b.) während des Abarbeiten der Funktion konfiguration_Standheizung (in
einer Schleife) keine anderen Werte/Strukturen/Arrays verändert werden.
Das einzige Array, das genutzt wird, ist txtSteuern, das 16 chars halten
soll und als char [17] definiert ist.

Das Verhalten hängt definitiv mit konfiguration_JaNein() zusammen.

Ich kenne mich mit der Struktur bzw. den internen Vorgängen (Stack
etc.) nicht sonderlich aus, daher die ev. naive Frage, ob ggf. beim
Aufruf/Rücksprung von konfiguration_JaNein Daten 'irgendwo' hin- und
hergeschaufelt werden, was dann den Fehler verursacht?

Aber warum tritt das nur bei der einen Struktur auf?

typedef struct
   {
   unsigned char  Steuern;
   unsigned char  Position;
   unsigned char  Name1;
   unsigned char  Name2;
   unsigned char  Status;
   unsigned char  Sensor_AT;
   unsigned char  Sensor_IT;
   unsigned char  Sensor_KT;
   int            Temperatur_KT;
   unsigned char  Tage_Programm;
   } struct_SH;

Wie gesagt, die anderen, mit denen es funktioniert, sehen vergleichbar
bis fast identisch aus.

zaydo

von Rahul (Gast)


Lesenswert?

"volatile" wird auch gerne vergessen...und manche Compiler
"entsorgen" (auch "wegoptimieren" genannt) solche Variablen dann
einfach mal so...

von zaydo (Gast)


Lesenswert?

Moin Rahul,

[...]
>"volatile" wird auch gerne vergessen...

Ja, hatte ich auch schon dran gedacht. Hatte aber keinen Unterschied
gemacht :-(


zaydo

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
Noch kein Account? Hier anmelden.