Forum: Compiler & IDEs Frage zu Timer1 CTC ATmega32 WinAVR


von (Gast)² = (Gast) * (Gast)


Lesenswert?

Hallo,

kleines Problem bzw. Frage zum Timer1.

Der Timerinit sieht wie folgt aus:

void init_T1( void )
{
   TCCR1A = 1<<WGM12;          //CTC mit TOP=OCR1A
   TCCR1B = 1<<CS12;           //prescale=256
   OCR1A = (F_CPU  256  64); //64 Überläufe/sek.
   TIMSK |= 1<<OCIE1A;         //Int Enable
}

Dann noch sei(); in main()...

Die Timer1-ISR:

SIGNAL (TIMER1_COMPA_vect){
   TCNT1 = 0; //sollte im CTC-Mode automatisch passieren grübel
   //TuIrgendwas;
}

Frage: Sollte TCNT1 nicht automatisch auf null gesetzt werden beim 
Eintritt in die ISR?

von Michael U. (Gast)


Lesenswert?

Hallo,

beinahe richtig. ;)
Der Timer wird auf 0 gesetzt, wenn der Comparewert erreicht ist.
Parallel dazu wird das Compare-IRQ-Flag gesetzt und wenn die IRQs global 
freigegeben sind, die IRQ-Routine angesprungen. Dabei wird auch das Flag 
im TIFR wieder glöscht. Der Timer zählt inzwischen schon wieder fleißig 
weiter, je nach Prescaler hat er also nicht mehr unbedingt 0 beim 
Eintritt in die IRQ.

Gruß aus Berlin
Michael

von (Gast)² = (Gast) * (Gast)


Lesenswert?

Ups, ja, beim erreichen des Comparewertes - danke schonmal!

Aber das macht er in meinem Fall ja nicht, deshalb brauch ich das
TCNT1 = 0;
in der ISR.

Also irgendwas mach ich doch noch falsch?!?

Frank

von kosmonaut pirx (Gast)


Lesenswert?

hallo,
wie der Michael schon gesagt hat: der Timer läuft unabhängig von der 
Interruptbearbeitung von neuem los.

lass dir doch einfach in der ISR den counter ausgeben. der sollte dann 
in einem niedrigem bereich rumschwirren.

ok, deine timer-init:

warum WGM12 in TCCR1A? steht doch da gar nicht drin grübel
du willst CTC ( == Clear Timer on Compare)? lt. doku:
1
   TCCR1A &= ~(1<<WGM11 | 1<<WGM10); //CTC mit TOP=OCR1A
2
   TCCR1B = (1<<WGM12 | 1<<CS12;     //CTC mit TOP=OCR1A, prescale=256
usw.
bye kosmo

von Michael U. (Gast)


Lesenswert?

Hallo,

@kosmonaut pirx: das endet jetzt unendschieden. ;)

CTC mit OCR1A ist nur WGM12 = 1
Deine 3x 1 ist irgendein PWM-Mode.

Recht hast Du damit, daß WGM12 in TCCR1B ist. :)

Also nur
TCCR1B = 1<<WGM12 | 1<<CS12 ;CTC mit TOP=OCR1A, prescale=256
sollte passen. TCCR1A bleibt komplett 0.

Gruß aus Berlin
Michael

von kosmonaut pirx (Gast)


Lesenswert?

hallo michael,

na da hast du doch sicher übersehen, dass ich die bits WGM10 und WGM11 
explizit ausgechaltet habe :)

also passt das schon. ja gut, die übrigen bleiben auf default, 
vielleicht nicht ganz sauber. und eine schliessende klammer fehlt.

aber sonst.
bye kosmo

von Michael U. (Gast)


Lesenswert?

Hallo,

ja, habe ich übersehen... Default ist das Register sowieso komplett 0 
solange nach dem Reset nicht dran rumgedreht wurde, ich setze es deshalb 
meist garnicht (ich kenne ja meine Programme... ;)))), deshalb habe ich 
wohl garnicht genau auf Deine Zeile geschaut.

Außerdem war es bei Schwager am Grill sowieso heute zu warm...

Gruß aus Berlin
Michael

von (Gast)² = (Gast) * (Gast)


Lesenswert?

Dankeschön Euch allen!

WGM12 hatte ich versehentlich im falschen Register (TCCR1B) gesetzt. 
Witzigerweise läßt sich damit trotzdem/zufällig der Interrupt auslösen, 
ohne daß TCNT1 davon berührt wird.

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
Noch kein Account? Hier anmelden.