logische Verknüpfung als Bedingung für Abbruch while-Schleife (Atmega / Atmel Studio 7)

OP #7443213
Lesenswert?

Hallo,

ich stehe momentan auf dem Schlauch und auch nach 3h habe ich meinen Fehler nicht gefunden vielleicht kann ja einer von euch mir sagen was ich falsch mache.

Ich möchte eine while-Schleife abbrechen wenn entweder PinC0 gedrückt wird oder die Schleife 2 mal durchlaufen wurde. Wenn ich das Ganze auf dem Atmega88 habe, wird aber nur wenn der Taster losgelassen wird (mit internen Pullup eingeschaltet daher die Negation) die Schleife verlassen. Die Durchläufe interessieren mein Progamm nicht. Ich habe schon verschiedene Klammern gesetzt aber keine brachte mich zum Erfolg.

Installiert ist das Studio 7.0 mit AVR GCC

1
  MAX7219_On();
2
  uint8_t i = 0;  
3
  
4
  while ( !(PINC & (1 << PC0)) && (i < 2) ){    
5
    _delay_ms(500);
6
    MAX7219_shutdown();
7
    _delay_ms(200);
8
    MAX7219_On();
9
    i++;}
10

11
Beste Grüße
OP #7443250
Lesenswert?

Hallo,

ich bin gerade außer Haus und kann nicht am Rechner sogleich testen, aber ich will doch eine "while" Schleife unterbrechen und das geht doch nur wenn die Bedingung NULL wird -> while (0)

Wenn ich jetzt wie vorschlagen die ODER-Verknüpung nehme heißt es doch -> while (0 || 1) Und das würde doch keinen Ausbruch aus der Schleife erzeugen außer ich lasse beide Bedingungen zu NULL werden.

Bitte korrigiert mich wenn ich falsch liege, ich bin erste gerade dabei mich wieder in AVR und GCC einzuarbeiten... ging in den Jahren einiges an Wissen den Berg hinunter.

#7443263
Lesenswert?

Man könnte den Kram natürlich auch anders formulieren:

1
  uint8_t i;  
2
  MAX7219_On();
3

4
  for (i = 0; i < 2; i++)
5
  {
6
    if (PINC & (1 << PC0))
7
      break;
8

9
    _delay_ms(500);
10

11
    MAX7219_shutdown();
12

13
    _delay_ms(200);
14

15
    MAX7219_On();
16
  }

aber das, was da eingangs steht, sollte auch funktionieren.

#7443294
Lesenswert?

In C hat der Operator ! laut Doku eine höhere Priorität als &&. In Python hat dein Konstrukt funktioniert.

Probier's mal mit: while ( (!(PINC & (1 << PC0))) && (i < 2) ){

Gruß klatschnass

Edit: Ok, das war Quatsch. Der while-Ausdruck funktioniert so, wie er ist. Das Problem liegt wohl eher daran, dass die Taste in der delay-Pause gedrückt und wieder losgelassen wird. Das bekommt die Schleife dann natürlich nicht mit. Deswegen hattest du auch den Eindruck, dass du die Taste langsam loslassen musst, damit es funktioniert. Da musst du wohl statt der Pause mit Interrupts arbeiten.

#7443380
Lesenswert?

Pilot P. schrieb:

Da musst du wohl statt der Pause mit Interrupts arbeiten.

Oder einfach mit freilaufendem Timer und einer kleinen Statemachine.

Pilot P. schrieb:

Das Problem liegt wohl eher daran, dass die Taste in der delay-Pause gedrückt und wieder losgelassen wird. Das bekommt die Schleife dann natürlich nicht mit.

Ja, das ist natürlich Quatsch. Da muss man ja jede nach dem bis zu 700ms den Taster drücken.

OP #7443713
Lesenswert?

Also der Code funktioniert so wie er soll, mein Problem lag eine Zeile weiter. Dort habe ich im prinzip ein Signal erhalten, deswegen gab es immer wieder einen Rücksprung in die while Schleife.

Danke für eure Unterstützung.

Und die 700ms machen für mich schon Sinn da ich erst nach kurzem halten der Taste in ein Menü gelangen möchte.

Grüße

Moderator (Firma: Titel) Persönliche Seite #7443831
Lesenswert?

Hugo H. schrieb:

Wegstaben V. schrieb:

Wie geht denn ein "Rücksprung in eine While-Schleife?"

Kennst Du keine Funktionsaufrufe? MAX7219_...(); scheinen SPI-Kommunikation "durchzuführen" ...

Und wieso würde da dann irgendwas "springen"? Die Funktionen geben ja nicht mal einen Wert zurück.

Zi P. schrieb:

Und die 700ms machen für mich schon Sinn

Für mich sind die 700ms delay() ein Programmfehler, weil sie nur nutzlos Rechenzeit vergeuden.

Gast #7444091
Lesenswert?

Der Fehler ist (wie so oft) nicht im gezeigten Stück Code. Das heißt, du konzentrierst dich auf die falsche Stelle.

Denn folgendes Testprogramm läuft auf meinem PC nämlich tadellos:

1
#include <stdio.h>
2
#include <stdint.h>
3

4
void _delay_ms(int ms)
5
{
6
    printf("_delay_ms(%d)\n", ms);
7
}
8

9
void MAX7219_On()
10
{
11
    puts("MAX7219_On()");
12
}
13

14
void MAX7219_shutdown()
15
{
16
    puts("MAX7219_shutdown()");
17
}
18

19
#define PC0 0
20
#define PINC 0
21

22
int main()
23
{
24
    MAX7219_On();
25
    uint8_t i = 0;
26

27
    while ( !(PINC & (1 << PC0)) && (i < 2) )
28
    {
29
      _delay_ms(500);
30
      MAX7219_shutdown();
31
      _delay_ms(200);
32
      MAX7219_On();
33
      i++;
34
    }
35
}

Ausgabe:

1
MAX7219_On()
2
_delay_ms(500)
3
MAX7219_shutdown()
4
_delay_ms(200)
5
MAX7219_On()
6
_delay_ms(500)
7
MAX7219_shutdown()
8
_delay_ms(200)
9
MAX7219_On()

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