Forum: Compiler & IDEs Variablen haben kein statisches Verhalten


von Christian W. (werni)


Angehängte Dateien:

Lesenswert?

Hallo liebe Controller-Freaks,

bin wegen meiner Diplomarbeit fleißig am Controller programmieren
(Programmiersprache C).
Möchte dort nichts weiter machen als in einer ISR eine Variable
hochzählen zu lassen.
Habe festgestellt dass bei jedem Betreten der ISR sie aber immer wieder
auf 0 gestezt wird, extrem flüchtiges Verhalten also.
Ich vermute, dass man für solche Angelegenheiten diese Variablen im
SRAM (oder ähnliches) des Controllers abspeichern muss.
Nun weiß ich aber nicht wie sowas im C zu realisieren ist.
Übrigens habe ich mich auf ein Beispiel-Programm gestüztzt, welches mit
Savvy (chip45) mitgeliefert wurde, dieses funzt natürlich auch nicht.
Kann mir jemand helfen? Ich wäre euch sehr verbunden und dankbar.

LG, Werni

von Karl H. (kbuchegg)


Lesenswert?

Ich würde mal sagen, dein Hauptproblem liegt darin,
dass du die Interrupts überhaupt nicht eingeschaltet
hast:

int main(void)
{
  ...

  sei();   // Interrupts generell zulassen

  while(1)//Endlos-Schleife; Interrupt macht den Rest
  {

von Christian W. (werni)


Lesenswert?

Hi Karl,

du hast zwar recht, ich hab das vorhin nochmal schnell vereinfacht und
das sei(); dabei vergessen.
das ist aber nicht das problem, denn die LED toggelt auch nach 5 jahren
noch (was sie ohne Interrupt-Erlaubnis gar nicht tun würde).
ich erwarte ja wie schon gesagt, ein einmaliges umschalten, kein
unendliches, das heißt, so oft die ISR auch aufgerufen wird, die
if-condition sollte ja nur einmal erfüllt sein.
Weiterhin danke für deine bemühungen.

von A.K. (Gast)


Lesenswert?

"Habe festgestellt dass bei jedem Betreten der ISR sie aber immer
wieder auf 0 gestezt wird"

Womit festgestellt?

"die if-condition sollte ja nur einmal erfüllt sein."

Genauer gesagt, 1mal alle 256 Interrupts.

von Karl H. (kbuchegg)


Lesenswert?

Ich hab dein Pgm in den AVR-Simulator gestopft,
den sei() ergänzt, den Prescaler mall etwas runter gesetzt
und siehe da: alles funzt so wie es sein soll:
Der Timer zählt hoch
Wenn er 255 erreicht hat wird der Interrupt ausgelost
Im Interrupt wird count um eins hochgezählt
jedesmal wenn count wieder den Wert 1 erreicht hat (nach
dem Oberflow von count), wird die Led getoggelt.

Die if condition ist nicht nur ein einziges mal erfüllt.
Du machst einen
  count++
d.h. bei jedem Aufruf der ISR zählst du count um 1 hoch.
d.h. count zählt: 1, 2, 3, 4, 5, 6, 7, ... usw. bis 255
erreicht ist. Mehr geht nicht, da count eine 8 Bit Variable ist
und ein Überlauf passiert. Danach beginnt count wieder bei 0
und in den nächsten ISR Aufrufen gehts weiter
 1, 2, 3 ... 254, 255, 0, 1, 2, 3, ..., 254, 255, 0, 1, 2, 3

Wie du siehst, kommt da immer wieder eine 1 vor. Und bei jeder
1 toggelst du die Led.

Der µC macht genau das was du programmiert hast. Und auch die
Variable hat ihr 'statisches Verhalten'. Alles genau so wie es
sein soll. Wenn du eine falsche Logik programmierst ist das
nicht das Problem des Compilers :-)

von Anselmo (Gast)


Lesenswert?

Die LED toggelt deshalb, weil count immer wieder überläuft und danach
auch wieder 1 wird.

von Anselmo (Gast)


Lesenswert?

Upsi, da war Karl-Heinz wohl schneller, meint aber das gleiche...

von Christian W. (werni)


Lesenswert?

Das dachte ich auch zwischendurch, habs dann mal mit ner 16 Bit Variable
versucht, ergab keine Frequanzsenkung um den Faktor 256, sondern
haargenau das gleiche Verhalten.
Selbst wenn man schreiben würde if(i<2){i=2}, dürfte die if-Bedingung
ja nie wieder erfüllt werden, aber meine LED bleibt scharf auf
rumblinken verzweifel, bin mir also wirklich fast 100% sicher, dass
die variable immer wieder auf 0 initialisiert wird, selbst wenn man sie
bei der obigen Deklaration gleichzeitig mit einem höheren Wert als 1
initialisiert.
Wenn ihr die Möglichkeit habt, dann probiert es doch bitte einmal aus,
aber wenn dann eben nur im C (Ich verwende Programmer's Notepad von
WinAVR).

von Christian W. (werni)


Lesenswert?

Ups, ich sehe grad, ich meine selbst wenn man vor der if-Bedingung
schreiben würde if(i>2){i=2},also natürlich nicht i<2.

von Karl H. (kbuchegg)


Lesenswert?

Ich habe es ausprobiert!
Und es läuft exakt so ab, wie ich es beschrieben
habe.

von Karl H. (kbuchegg)


Lesenswert?

Nachtrag:
Und das ist genau das Verhalten das sich aus dem
Source-Code ergibt: die Led toggelt.

Von einem Diplomanden sollte man schon erwarten
können, dass er einen Debugger benutzen kann.

von Karl H. (kbuchegg)


Lesenswert?

> Ich verwende Programmer's Notepad von
> WinAVR).

Hol dir von Atmel das AVR-Studio.
WinAvr integriert sich dort wunderbar hinein und du hast
dort dann einen Simulator samt Source Code Debugger zur
Verfügung.

von Christian W. (werni)


Lesenswert?

Das mit dem AVR Studio habe ich erst heute entdeckt, zeigt aber (noch)
merkwürdiges Verhaltem beim Debugging, naja werde dem problem am Ball
bleiben, vielleicht krieg ichs ja noch hin. Danke euch erstmal und
wünsche euch ne schöne nacht.

von Wolfram (Gast)


Lesenswert?

Wahrscheinlich brauchst du eine neue Version von WinAVR um mit AVRStudio
zu arbeiten.
Die verwendeten Makros legen sehr nahe, dass du eine alte Version von
WinAVR benutzt. Es gabe Änderungen bezüglich Interrupt Deklaration und
Makros, steht alles in der Dokumentation.
Es wäre sauberer count von Anfang an zu initialisieren.

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.