Forum: Compiler & IDEs while / Interrupt - Problem


von Markus Wentker (Gast)


Lesenswert?

Hallo!

Ich habe eine UART-Senderoutine, die abwarten soll, ob der vorherige
Befehl korrekt empfangen wurde.
Es gibt also im UART-Receive-Interrupt eine Überprüfung, ob ein "OK"
zurückempfangen wurde. Ist dies der Fall, so wird eine Variable auf 1
gesetzt. Außerdem wird ein Timer gestartet, der bei einem Overflow
ebenfalls die Variable auf 1 setzt, um den Programmablauf nicht
aufzuhalten.

In meiner Senderoutine warte ich zunächst darauf, dass die Variable 1
wird.
Ich habe
while (pc_answer == 0);   und
for (; pc_answer == 0;);

pc_answer ist natürlich als volatile deklariert.

Das Programm bleibt aber in der while- bzw. for-Schleife hängen und
wird nicht durch den Interrupt unterbrochen, so dass die Variable auf 1
gesetzt werden kann.

Was ist falsch? Oder gibt es schönere Lösungen, die auf eine korrekte
Antwort warten, bevor der nächste Befehl gesendet wird?

Gruß
Markus

von Wolfgang Horn (Gast)


Lesenswert?

Hi, Markus,

"Ich habe eine UART-Senderoutine, die abwarten soll, ob der vorherige
Befehl korrekt empfangen wurde.
Es gibt also im UART-Receive-Interrupt eine Überprüfung, ob ein "OK"
zurückempfangen wurde. "

In Interrupt-Routinen darf nicht gewartet werden.
Die sind nur wie der Postbote - die liefern die Post ab, und schon sind
sie wieder weg.
Das Warten muß in das Hauptprogramm verlegt werden.

Ciao
Wolfgang

von Markus Wentker (Gast)


Lesenswert?

Hi!

Oh, habe mich da vielleicht etwas umständlich ausgedrückt:

Ich warte in der Senderoutine, welche eine "normale" C-Funktion ist.
Diese Funktion hat als erste Zeile eben ein
while (!flag); oder eben die for-Variante.

Diese Endlosschleife soll eigentlich durch einen Timer-Overflow (oder
der Empfangsroutine) unterbrochen werden, der das flag setzt und damit
nach dem Rücksprung die Endlosschleife unterbrochen wird.

Gruß
Markus

von Karl heinz B. (heinzi)


Lesenswert?

Zeig doch mal etwas mehr Code.

von Markus Wentker (Gast)


Lesenswert?

volatile int pc_answer;

Sende-Funktion:
void send_PC(int E, int L, int W)
  while (!pc_answer);          //um diese Zeile geht es
  pc_answer=0;

  while (!(UCSR0A & (1<<UDRE0)));
  UDR0 = 'E';

        usw.

Die Timer-Overflow-Routine:
SIGNAL (SIG_OVERFLOW3)
{
  lcd_clrscr();
  lcd_command(LCD_DISP_ON);
  lcd_puts("PC CommError!");
  pc_answer=1;
  TCCR3B=(0<<CS32)|(0<<CS31)|(0<<CS30);  // Timer stoppen
  TCNT3H=TCNT3L=0;
};

Wenn ich die while-Schleife rausnehme, erscheint der Display-Text, d.h.
die Interrupt-Routine wird angesprungen, sonst nicht.

von Peter Fleury (Gast)


Lesenswert?

"In Interrupt-Routinen darf nicht gewartet werden."
Das kann ich nur bestätigen, deshalb keine zeitintensiven Funktionen
wie lcd_clrscr() in der Interrupt-Routine ausführen !

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.