Forum: Compiler & IDEs "Irgendwas" setzt meine globale volatile Variable zurück :(


von 2mkx (Gast)


Lesenswert?

Servus beinander,
ich hoffe Ihr könnt mir ein kleines bisschen weiterhelfen.

Meine Firmware hat sozusagen 2 StateMachines, eine sorgt dafür, dass der 
ADC nacheinander Burst-Messungen von den einzelnen Kanälen aufnimmt und 
schreibt sie in ein 2-Dimensionales Array für ein Moving-Average-Filter. 
Das funktioniert schon (davon abgesehen, dass er manchmal werte von 1080 
aus dem 10bit-ADC ausliest - obwohl ich sie mit 3FF verunde!)

So sollte es dann weiter laufen:
Die Tastenentprellung (int0) startet hald Timer und steuert so die 
Menüführung (langer Tastendruck, kurzer etc.) und der 1Hz Timerevent 
schaltet durch die Display-States durch (Anzeige:Messwert1 -> 2sec -> 
Anzeige:Messwert2...)
Die in der Main dann refreshed werden.
Die logik davon ansich sollte funktionieren ;)

Zum Wahnsinn treibt mich folgendes:
1
ISR(TIMER1_COMPA_vect)    // 1Hz eventrate
2
{
3
  // if not in menu the screen will be changed every DISP_DELAY
4
  // if in menu, the DispState isn't changed but the MenuDelay decremented
5
  if(iMenuDelay == 0)    // not in menu
6
  {
7
    iDispDelay++;  // Increment counter
8
    if(iDispDelay >= DISP_DELAY)
9
    {
10
      if(pDispState == Messwert7) pDispState = Messwert1;
11
      else pDispState++;
12
      iDispDelay = 0;  // restart counter
13
    }
14
  }
15
  else  // Menu entry selected
16
  {
17
    iMenuDelay--;
18
  }
19
}
iDispDelay sollte also bis z.B. 2 zählen und dadurch der nächste Screen 
ausgewählt werden.

Nachm ersten Aufruf hat iDispDelay wies sein soll den Wert 1.
In Einzelsteps weitergemacht bleibt der wert in der watch auch "1".
klick ich auf run oder lande per breakpoint das nächste mal in der ISR, 
ist der Wert wieder '0' sprich er kann nie bis 2 zählen!
Eine andere Funktion greift nie auf den Wert zu, der dient lediglich der 
ISR als zähler...
Hab ausprobiert in der Main die Variable zu benützen um ein 
"Wegoptimieren" zu verhindern
iDispDelay++;
iDispDelay--;
Trotzdem. plötzlich isse wech!

Der Ram meines mega169P is zwar zu 50% voll, aber das dürfte doch kein 
solches Problem darstellen - OOOODER?

Vielen Dank :)
vy73 de Benjamin - 2mkx

von Stefan E. (sternst)


Lesenswert?

> Das funktioniert schon (davon abgesehen, dass er manchmal werte von 1080
> aus dem 10bit-ADC ausliest - obwohl ich sie mit 3FF verunde!)

Dann ist dein Programm an dieser Stelle fehlerhaft.
Aber: Ohne den Code ist keine genaue Aussage möglich.

> Eine andere Funktion greift nie auf den Wert zu, ...

Vielleicht nicht mit Absicht. Ich tippe auf Out-Of-Bounds-Array-Zugriff.
Aber auch hier: Ohne den Code ist keine genaue Aussage möglich.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Vermutlich ist DISP_DELAY = 2 :-)

Oder nicht-atomarer Zugriff auf die asynchronen Objekte (das 
volatile-Zeug).

Johann

von Sven P. (Gast)


Lesenswert?

Evtl. auch Stacküberlauf.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Oder ein Interrupt, für den es keine ISR gibt.

von Andreas (Gast)


Lesenswert?

Ich vermute dasselbe wie Johann.
Vielleicht verrät uns der TO ja noch, welchen Wert DISP_DELAY nun hat.

Gruss
Andreas

von STK500-Besitzer (Gast)


Lesenswert?

>Die Tastenentprellung (int0) startet hald Timer

Warum stellen sich mir hier schon sämtliche Nackenhaare auf?

von 2mkx (Gast)


Lesenswert?

Boah, Respekt! guten Morgen :)
war gestern wohl nicht mehr die Zeit um das zu lösen, bin bis halb4 dran 
gesessen.
das mit dem ADC hab ich heut morgen aber noch gfunden. mein Fehler

@Jörg: ja, eine Interrupt war noch aktiviert, aber ohne ISR

@Johann: falls du meinst, dass ich nur "was falsches" im watch sehe: 
kann auch sein... an der FH konnte ich neulich beobachten, wie sich 
trotz schreibzugriff variablen nicht ändern (die bleiben bei 0 in der 
watch), die if(var==1) bedinung nachher schlägt aber an - quasi a 
Darstellungsfehler?!? nervt jedenfalls, weil man ewig sucht warum in die 
variable nix reingeschrieben wird.

@Andreas: "...vielleicht verrät der TO uns ja noch..." sorry, wer ist 
TO? *g klingt irgendwie nach Trace ;)

@STK500 Besitzer: wollt ja kein Roman schreiben, der Tasten-Interrupt 
setzt eine Variable auf !=0 (also 1 etc.), der 100Hz Timer frägt die 
variable ab und if(Var) Var++; - also inkrementiert den zähler nur falls 
er "aktiviert" ist. Wird die taste losgelassen schau ich mir den 
Zählerstand an und weis wie lange sie gedrückt wurde - kann entprellen 
und beliebig viele "anschlagzeiten" messen. also für >3sec == 
ausschalten, >50ms == tastentip und >1sec == menü etc. - is das wirklich 
so schlimm?

von 2mkx (Gast)


Lesenswert?

Ihr seid Gut!
@Jörg: ihc denk der aktivierte Interrupt wars (ich hatte von vorherigen 
tests noch einen Timerinterrupt laufen lassen).
...es wird immer besser das ganze :)
Vielen Dank schonmal soweit!
vy73!

PS:
Wenn jetz no wer a Idee hat, wie ich so enums watchen kann (also die 
state-variablen) - wenn ich die in die watch eintipp, oder "add to 
watch" mach, tut sich einfach nix. <- des würd des debuggen schon 
erleichtern, wenn man sieht was die für an Wert haben! - wenigstens als 
zahl 0...n

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.