Ich geh da jetzt mit gemischten Gefühlen in die Beantwortung
deiner Frage. Der Grund ist der, dass man solche Warteschleifen
eigentlich vermeiden möchte. Der µC soll eigentlich überhaupt
nie auf etwas warten, sondern es entstehen Ereignisse und
diese Ereignisse lösen Aktionen aus.
Eine Systematik die sich in der Praxis gut bewährt, ist
folgende Vorgehensweise:
Es gibt in main() die sog. Hauptschleife. Diese Hauptschleife
überprüft ständig ob ein Ereignis eingetreten ist. Ob
ein Ereignis eingetreten ist, oder nicht, wird durch
globale Variablen angezeigt, die zb. den Wert 0 haben, wenn
das Ereignis nicht eingetreten ist und 1 wenn das Ereignis
eingetreten ist.
Konkret sieht das zb so aus:
uint8_t Abgelaufen10Sek;
uint8_t irgendeinAnderesEreignis;
int main()
{
.....
while( 1 ) {
if( Abgelaufen10Sek == 1) {
// mache was immer nach der 10 Sekunden Wartezeit
// passieren soll
Abgelaufen10Sek = 0;
}
if( irgendeinAnderesEreignis ) {
// Start einen Vorgang. Teil dieses Vorgangs
// ist es zwischendurch mal 10 Sekunden zu warten
// also wird hier der erste Teil (vor der Wartezeit)
// erledigt
// danach wird ein Timer aktiviert, der die Zeit
// runterzählt. Hat der Timer die 10 Sekunden
// überbrückt, so löst er einen Interrupt aus
// und in der Interruptfunktion wird dann die Variable
// Abgelaufen10Sek auf 1 gesetzt.
// Dies sorgt dann dafür, dass der 2-te Teil der
// Berechnung beim nächsten Durchlauf der while Schleife
// hier in Angriff genommen wird.
irgendeinAnderedEreignis = 0;
}
if( ( PINC & 0x01 ) = 0x01 ) {
// löse die Berechnung aus indem irgendeinAnderes
// auf 1 gesetzt wird. Beim nächsten Durchlauf durch
// die while Schleife beginnt dann die Kette der
// Berechnungen
}
}
Mittels setzen von irgendeinAnderesEreignis auf 1 (zb. durch
das Drücken eines Tasters, unterbrechen einer Lichtschranke,
was auch immer), beginnt der erste Teil der Berechnung. Ist
diese soweit erledigt, dass gewartet werden müsste, so wird
der Timer gestartet. In der Zwischenzeit läuft das Programm
weiterhin brav durch seine while Schleife und erledigt was es
sonst noch so alles zu erledigen gibt.
Wenn der Timer abgelaufen ist, so löst der Timer einen Interrupt
aus, welcher in seiner ISR wiederrum die globale Variable so
setzt, dass beim nächsten Durchlauf durch die while Schleife
der 2te Teil der Berechnung durchgeführt wird.
Auf diese Weise, wartet das Programm nirgends auf irgendetwas
sondern es steht immer Rechenzeit zur Verfügung um in der
'Wartezeit' auch andere Dinge zu tun (zb. Messwerte auslesen,
Anzeigen auf den neuesten Stand bringen, etc ...)
Der springende Punkt um den es eigentlich geht, ist der,
dass man Warteschleifen von vorneherein vermeiden möchte.
Mit obiger grundsätzlicher Struktur ist sowas möglich.