Das versucht er ja, Frank, funktioniert nur so nicht.
Guido, erstens werden do-nothing Schleifen vom avr-gcc zu übereifrig
optimiert, die taugen also nicht als Verzögerungsschleifen. Greif
zu den Makros in <avr/delay.h>, wenn Du etwas Zuverlässiges haben
möchtest.
Zweitens ist es generell keine gute Idee, so eine riesige Aufgabe
in eine Interruptroutine zu legen. Mach Dir eine kleine Variable
(kann auch ein bitfield sein), »volatile« nicht vergessen!, und
laß die Interruptroutine nur das Notwendigste machen und dann diese
Variable setzen. Die Hauptschleife in main() kann das dann auswerten,
die Variable rücksetzen und entsprechend reagieren.
Eine Variante, die sich bei mir bewährt hat für eine ähnliche Aufgabe
sieht etwa so aus:
SIGNAL(SIG_INTERRUPT_0)
{
diesen Interrupt hardwaremäßig abschalten
timer für Entprellung starten
Merkvariable setzen
}
int
main(void)
{
...
for (;;) {
if (merkvariable) {
merkvariable abklemmen
bearbeiten
}
if (timeout erreicht) {
externes Interruptflag löschen
externen Interrupt wieder zuschalten
}
}
/* NOTREACHED */
return 0;
}
In Wirklichkeit ist das noch etwas komplizierter, da ich noch Taste
kurz gedrückt vs. Taste lange gedrückt unterscheiden möchte, so daß
ich den Interrupt abwechselnd auf beiden Flanken aktiviere, aber
das geht jetzt hier zu weit.