Hallo und einen schönen guten Tag zusammen... Ich möchte mit Hilfe eines Timers eine 10 sekündige Warteschleife programmieren... [Atmega8, benutzen möchte ich den 16bit Timer] folgendes habe ich bis jetzt verstanden....bzw. nicht verstanden //---------------------------------------------------------------------- TIMSK |= _BV(TOIE1); //aktivieren des Überlaufinterrupts von Timer1 --> wozu dient mir der Interrupt ? irgendwo wird doch eine "1" reingeschrieben, wenn ich bei 2^16 bin ? wie kann ich diese 1 dann benutzen, um z.b eine Led anzuschalten ? TCCR1B = _BV(CS12) | _BV(CS10); //Prescaler definieren(aus Datenblatt: 101 cs12,cs11,cs10) = 1024 Prescaler --> das ist soweit klar TCNT1 = 55771; //Zählregister vorladen für 10sek. --> zählt also noch bis 2^16...meiner rechnung nach müssten dann 10 sek. vorvbei sein ! --> also ich möchte eigentlich jetzt nur nach 10 sekunden etwas ausführen...um genauer zu sein möchte ich jetzt nicht unbedingt eine led anschalten, sondern es soll sich ja um eine warteschleife handeln. Deswegen möcht ich nach 10 sekunden wieder weitermachen mit meinem programmcode.... wie kann ich das realisieren ? Vielen dank für eure hilfe mfg hans
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.
Hi Hans, Wenn der Timer0 deines µC "überläuft" wird das Programm unterbrochen und eine Interrupt Routine aufgerufen. in C kann man das folgendermaßen schreiben:
1 | interrupt [TIM0_OVF] void timer0_int(void) |
2 | {
|
3 | // hier dein Code
|
4 | }
|
Mit welcher Taktfrequenz arbeitest du?
ok..erstmal danke für eure antworten... Ich arbeite mit dem 16 bit Timer des atmega8 und einer taktfrequenz von 1MHz. Ich habe einen Fehler in meiner Beschreibung gemacht...sorry... 1) warum kann ich für ne einfache wartezeit nicht einfach... #include <util/delay.h> ... _delay_ms(100); ... benutzen ? 2) Ich möchte das es folgendermaßen funktioniert: ES soll ein 10 sek timer laufen. Wenn ich innerhalb !!dieser 10 sek. keine aktion ausführe, soll das Programm irgendwas machen. Wenn ich jedoch innerhalb der 10 sek. eine aktion ausführe, soll dann das Programm auch wieder irgenwas anderes machen.... hört sich irgendwie dämlich an...soll aber so laufen... @ Karl heinz Buchegger (kbuchegg) - Ich fange gerade an mit der Micro-programmierung.... -also ich möchte tatsächlich einfach nur warten....das hat den hintergrund dass es sich um eine art Sperre handelt, wenn man etwas falsches eingibt... was ist so schlecht an der routine _delay_ms() ? könnte ich doch benutzen oder? Ja ich gebe dir recht, für umfangreiche Programme wäre dein Vorschlag natürlich sehr sinnvoll.... @max die routine wird also automatisch aufgerufen, wenn deruc überläuft ? danke für eure hilfe
...also nicht, dass ihr verwirrt seit. Ich brauche einmal eine Routine für das Warten, (evtl mit _delay_ms()) und einmal eine Routine, dass ich innerhalb der 10 sek. noch eingaben tätigen kann.(siehe punkt2) danke
Dann programmiere Dir doch einen Timeout-Zähler, den Du bei jeder Aktion wieder auf Startwert setzt und der (durch einen Timer-Interrupt synchronisiert) heruntergezählt wird, solange er nicht schon (oder noch) 0 ist. Erreicht er 0, geht es mit der Abarbeitung weiter (über ein Job-Flag). In ASM eine ganz einfache Sache, in C kann ich es nicht formulieren... ...
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.