Timer INT sofort auslösen

OP #454288
Lesenswert?
• ▲
▼
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
Gast #454329
Lesenswert?
• ▲
▼
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.
Gast #454342
Lesenswert?
• ▲
▼
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.
#454414
Lesenswert?
• ▲
▼
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
OP #454415
Lesenswert?
• ▲
▼
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.
Gast #454446
Lesenswert?
• ▲
▼
@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...
Gast #454516
Lesenswert?
• ▲
▼
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?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren