Hallo, Ich habe einen ATMega 8 bei dem der Timer 1 wie folgt initialisiert wurde: TCCR1A = 0; TCCR1B = ((1<<WGM12) | (1<<CS10)); // CTC - No Prescaler OCR1A = 4915; // 1 ms TCNT1 = 0; TIMSK |= (1<<OCIE1A); // Interrupt aktivieren Wenn ich nun im Programm TCNT1 = 4915; schreibe, wird dann sofort der Timer Interrupt ausgeloest? MfG H:V
Der Timer 1 Output Compare A-Interrupt wird ausgelöst, sobald TCNT1 und OCR1A übereinstimmen, also sollte er in dem Fall ebenfalls ausgelöst werden.
Ich mein mich zu erinnern im Datenblatt gelesen zu haben es muss mindestens ein Zählwert abstand sein sonst wird der Comparematch nicht ausgeführt.
Seh ich das richtig, dass Du ein 4,9152 Mhz Crystal hast? Für was braucht man die Dinger? Ist das ein "Baudratencrystal"? Ansonsten schließ ich mich der Meinung von Johnny m an. Denn ob der Timer von sich aus hochzählt und übereinstimmt, oder mit einem geladenen Wert mit dem OCR1A übereinstimmt ist denke ich latz.
Habe mal einen Blick ins Datenblatt geworfen und nichts gefunden, was darauf hindeutet, dass da ein Unterschied sein muss. Wenn ein Compare Match-Ereignis eintritt (und das bedeutet nur, dass TCNTx gleich OCRx ist), wird mit dem nächsten Timer-Takt (wahrscheinlich ist es das, was Läubi meinte) das Flag gesetzt. Der Interrupt wird also tatsächlich nicht sofort ausgelöst, sondern mit einem Timer-Zyklus verzögert.
Der Interupt wird nur ausgelöst, wenn der Timer in den Comparewert reinläuft, steht jedenfalls so im Datenblatt. Als mußt Du den Timer auf Compare - 1 setzen. Peter
johnny.m wrote: > @Peter: > Wo steht das? Ich habs jedenfalls nicht gefunden... All CPU writes to the TCNT1 Register will block any Compare Match that occurs in the next timer clock cycle, even when the timer is stopped. This feature allows OCR1x to be initialized to the same value as TCNT1 without triggering an interrupt when the Timer/Counter clock is enabled. Peter
Hallo, Peter hat scheinbar wirklich recht. Wenn ich: while(1){ if (!(PINB&(1<<PB5))&& bit.POWERLED_OLD) TCNT1 = 4915; } Schreibe wird der Int NICHT angesprungen. Auch ein while(1){ if (!(PINB&(1<<PB5)) $$ bit.POWERLED_OLD) TCNT1 = 4914; } erreicht den Interrupt nicht, da TCNT durch die while Schleife in Main auf 4914 gehalten wird. bit.POWERLED_OLD wuerd im Interrupt sowieso 0 gesetzt. Was kann ich da wo im moment TCNT1= xy steht verwenden, dass der ISR(SIG_OUTPUT_COMPARE1A) sofort aufgerufen wird? Gruss H:V @H:A Ja ist ein Baudratencrystal da ich UART mache.
@Peter: Danke. Das hatte ich auf die Schnelle nicht gefunden. @H.V: Dass er sofort aufgerufen wird, ist in dem Fall gar nicht möglich, da das Compare Match Interrupt Flag erst mit dem nächsten Timertakt gesetzt wird. Wenn der Prescaler also auf einen großen Wert eingestellt ist, dauert es bis zu 1024 CPU-Zyklen nach erreichen des Wertes, bis das Flag gesetzt wird (siehe Timing-Diagramme im Datenblatt). Wenn der Prescaler auf 1 (also "keine Teilung") steht, und Du das TCNT1 mit "OCR1A - 1" beschreibst, brauchts zwei CPU-Takte, bis das Flag gesetzt wird. Schneller gehts anscheinend nicht...
Du könntest Dir Deine Frage auch leicht direkt vom Controller beantworten lassen! Schreib ein winziges, nur das Nötigste [*] bewirkendes Testprogramm, und lass es ganz langsam ausführen, indem Du den µC mit einem externen Takt der Frequenz 1 Hz betreibst. [*] - Timer konfigurieren - Portpin mit grüner LED dran schalten - TCNT1 setzen - Portpin mit roter LED dran in der Timer-Interruptroutine schalten --> Wie lange dauert es, bis die rote LED aufleuchtet?
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.