Forum: Mikrocontroller und Digitale Elektronik Problem mit Variablen auf einem Mega324


von Tim (Gast)


Lesenswert?

Hallo,

ich habe bei mir das Problem, dass wenn ich eine Variable außerhalb der 
main deklariere, er die While-Schleife nicht verlässt:
[ ATMega324PA | avr-gcc | Atmel Studio 7 ]

Dieser Code funktioniert:
1
int main(void)
2
{
3
  bool Zeit_eingestellt    = false;  // Variable innerhalb der main deklariert.
4
5
  do // Belichtungszeit einstellen
6
  {
7
    _delay_ms(50);
8
9
    // Inkrementalgeber auslesen:
10
    Belichtungszeit += (uint16_t)Drehgeber_lesen();
11
12
    if (Belichtungszeit > 999)
13
    {
14
      Belichtungszeit = 999;
15
    }
16
    if (Belichtungszeit < 1)
17
    {
18
      Belichtungszeit = 1;
19
    }
20
21
    Anzeige.Anzeigen(Belichtungszeit);
22
    I01 = Belichtungszeit;
23
    
24
    if (!Taster_entprellt && flanke1)
25
    {
26
      Zeit_eingestellt = true;
27
      UART_senden((int32_t)Zeit_eingestellt, true);
28
    }
29
30
    flanke1 = Taster_entprellt;
31
  } while (!Zeit_eingestellt);
32
}


Dieser Code funktioniert hingegen NICHT:
1
bool Zeit_eingestellt    = false;  // Variable außerhalb der main deklariert.
2
3
int main(void)
4
{
5
  Zeit_eingestellt    = false;  // hier nochmal auf false gesetzt.
6
7
  do // Belichtungszeit einstellen
8
  {
9
    _delay_ms(50);
10
11
    // Inkrementalgeber auslesen:
12
    Belichtungszeit += (uint16_t)Drehgeber_lesen();
13
14
    if (Belichtungszeit > 999)
15
    {
16
      Belichtungszeit = 999;
17
    }
18
    if (Belichtungszeit < 1)
19
    {
20
      Belichtungszeit = 1;
21
    }
22
23
    Anzeige.Anzeigen(Belichtungszeit);
24
    I01 = Belichtungszeit;
25
    
26
    if (!Taster_entprellt && flanke1)
27
    {
28
      Zeit_eingestellt = true;
29
      UART_senden((int32_t)Zeit_eingestellt, true);
30
    }
31
32
    flanke1 = Taster_entprellt;
33
  } while (!Zeit_eingestellt);
34
}


Weiß jemand, woran das liegen kann? Was mache ich hier falsch?

LG
Tim

von holger (Gast)


Lesenswert?

Was soll dieser Unsinn?

int main(void)
{
  do // Belichtungszeit einstellen
  {
  } while (!Zeit_eingestellt);
}

Was glaubst du was nach main() passiert wenn die Bedingung nicht
erfüllt ist? Nichts passiert dann mehr.

von Tim (Gast)


Lesenswert?

Kleiner Nachtrag:

Da ich die Info, ob die Belichtungszeit nun gesetzt wurde, außerhalb in 
einer Funktion brauche, habe ich einfach eine zweite Variable angelegt, 
mit Unterstrich davor und beschreibe diese ebenfalls, wenn der Taster 
losgelassen wird. Auch hier wird die While-Schleife nicht verlassen.

Warum??

1
bool _Zeit_eingestellt = false;  zweite Variable, siehe unten
2
3
int main(void)
4
{
5
  bool Zeit_eingestellt    = false;  // Variable innerhalb der main deklariert.
6
7
  do // Belichtungszeit einstellen
8
  {
9
    _delay_ms(50);
10
11
    // Inkrementalgeber auslesen:
12
    Belichtungszeit += (uint16_t)Drehgeber_lesen();
13
14
    if (Belichtungszeit > 999)
15
    {
16
      Belichtungszeit = 999;
17
    }
18
    if (Belichtungszeit < 1)
19
    {
20
      Belichtungszeit = 1;
21
    }
22
23
    Anzeige.Anzeigen(Belichtungszeit);
24
    I01 = Belichtungszeit;
25
    
26
    if (!Taster_entprellt && flanke1)
27
    {
28
      Zeit_eingestellt = true;
29
      _Zeit_eingestellt = true;  // Wenn ich das hier einfüge, verlässt er die While-Schleife ebenfalls nicht.
30
      // Die "UART_Senden"-Funktion war nur zum debuggen
31
    }
32
33
    flanke1 = Taster_entprellt;
34
  } while (!Zeit_eingestellt);
35
}

von Tim (Gast)


Lesenswert?

holger schrieb:
> Was soll dieser Unsinn?
>
> int main(void)
> {
>   do // Belichtungszeit einstellen
>   {
>   } while (!Zeit_eingestellt);
> }
>
> Was glaubst du was nach main() passiert wenn die Bedingung nicht
> erfüllt ist? Nichts passiert dann mehr.

Es ist eine Art Schrittkette, mit mehreren While-Schleifen 
hintereinander.
Er bleibt definitiv in der ersten Schleife hängen, wenn ich am Drehgeber 
drehe, kann ich den Wert ändern. Wenn er sie überspringen würde, würde 
er ja in die nächste Anweisung gehen, das würde ich auf dem Display 
sehen.

von Nico W. (nico_w)


Lesenswert?

Volatile?

von Tim (Gast)


Lesenswert?

Nico W. schrieb:
> Volatile?

Habe ich schon versucht, ohne Erfolg.

von Felix Adam (Gast)


Lesenswert?

Probiere mal

static bool Zeit_eingestellt    = false;

(ist aber geraten, weil ich so einen ähnlichen Effekt auch mal hatte).

von Yalu X. (yalu) (Moderator)


Lesenswert?

Wie stellst du fest, dass Zeit_eingestellt tatsächlich auf true gesetzt
wird? In deinem Eröffnungsbeitrag hast du dafür vermutlich den
UART_senden-Aufruf genutzt. Im Beispiel von 00:45 fehlt dieser Aufruf
aber.

Prinzipiell sollte es keinen Unterschied machen, ob die Variable lokal
oder global definiert ist. Wenn doch, wird die Variable vermutlich auf
Grund eines Fehlers an anderer Stelle des Programms überschrieben.

von Dieter F. (Gast)


Lesenswert?

Praktisch wäre der komplette Code oder ein lauffähiges - 
reproduzierbares - eingeschränktes Beispiel mit gleichem Verhalten.

von Tim (Gast)


Lesenswert?

Ich habe den Fehler beseitigt.

Als erstes habe ich die Flanke als volatile bool global deklariert.
Dann hat er sich immer aufgehängt, wenn ich den Taster losgelassen hab.

Ich hab nen Timer mit CTC alle 1ms laufen. Darin zähle ich bis 500 und 
immer wenn die 500 erreicht sind (also alle 500ms) schaue ich auf 
_Zeit_eingestellt und sende Infos bei Änderung auf den UART. Wenn ich 
das senden auskommentiere, hängt er sich nicht auf, also bleibt er in 
der UART_senden-Funktion (nur bei Änderung von "_Zeit_eingestellt" 
aufgerufen in der ISR) hängen, oder beendet diese nicht rechtzeitig.

Ich habe diese Funktion nun in die If-Abrage, welche die While-Schleife 
beendet reingepackt und es geht, ist vermutlich auch sauberer so.

Danke für die guten Anregungen und Tipps. :)

Schönes WE
Tim

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.