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
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
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
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.
"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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.