Forum: Mikrocontroller und Digitale Elektronik Timer1 CTC Mode?


von Sebastian S. (rudimentor)


Lesenswert?

Hallo,
ich habe schon viele Beiträge gelesen komme aber nicht weiter!

Mein Problem:
Ich möchte den Timer1 eines ATmega8 im CTC Mode laufen lassen. Tut er 
aber nicht trotzt des Studiums der Beiträge und Datenblatt.
Im Datenblatt steht, das WGM13:0 4 sein muß, bzw. 0100. OCR1A habe ich 
bei einem Prescaler von 256 auf 0C34 gesetzt. Das entspricht dann bei 
einer Grundfrequenz von 31,25kHz einen Timer1 Overflow von 10Hz, 
vorrausgesetzt er fängt immer wieder bei 0 an zu zählen. Tut er aber 
nicht. Ich muß immer noch den Wert FFFF-0C34 in das TCNT1 Register 
schreiben, so dass der Timer das macht was ich möchte.

Laut Datenblatt sollte er doch TCNT1 selbstständig auf 0 setzen und bis 
OCR1A zählen. Jetzt zählt er ja die Differenz von F3CB bis FFFF? Was 
mache ich falsch?
Schon mal Danke im Vorraus....

Der Code:
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
 
4
volatile uint8_t Interruptflag;
5
 
6
int main() {
7
8
    DDRD = 0x00; //PortD als Ausgang definiert
9
 
10
    TCCR1A &= ~(1<<WGM10);
11
    TCCR1A &= ~(1<<WGM11);
12
    TCCR1B |= (1<<WGM12);
13
    TCCR1B &= ~(1<<WGM13);  //CTC-Mode TOP OCR1A
14
    TCCR1B |= 4;      //Prescaler 256
15
    TIMSK |= (1<<TOIE1);    //Timer Overflow Interrupt freischalten 
16
    OCR1A = 0x0C34;       //Top Wert gesetzt
17
    TCNT1 = 0xF3CB;
18
         
19
   sei(); // Interrupts aktivieren
20
21
    while(1) {
22
  
23
  
24
        if (Interruptflag == 1) { // Neuer Timerzyklus ?
25
            Interruptflag = 0;
26
            PORTD ^= (1 << PD7);    // LED toggeln
27
        } 
28
     
29
  } 
30
} 
31
 
32
33
34
// Timer1 overflow Interrupt
35
36
ISR( TIMER1_OVF_vect ) {
37
     TCNT1 = 0xF3CB;
38
     Interruptflag = 1;
39
40
}

von Justus S. (jussa)


Lesenswert?

Sebastian S. schrieb:
> DDRD = 0x00; //PortD als Ausgang definiert

öhm nö?

von Karl H. (kbuchegg)


Lesenswert?

Beim CTC MOdus hängst du dich nicht mehr an den Overflow Interrupt, weil 
der Timer technisch gesehen ja keinen Overflow mehr macht.

Du gehst an den Compare Match Interrupt.


    OCR1A = 0x0C34;       //Top Wert gesetzt
    TCNT1 = 0xF3CB;

Und die Tatsache, dass du den Zähler ausserhalb des 'erlaubten' Bereichs 
loslaufen lässt, stört dich nicht weiter?

Meine Vorgabe an dich lautet:
Du zählst jetzt von 0 bis 100. Jedesmal wenn du die 100 erreicht hast 
(und zwar exakt 100 und nur 100, nicht größer nicht kleiner, exakt 100) 
beginnst du wieder bei 0. Also los jetzt, fang bei 200 zu zählen an!

von Sebastian S. (rudimentor)


Lesenswert?

Oh ja sorry, falsche Portzuweisung. Denoch habe ich nur eine Frequenz, 
wenn ich TCNT1 setze. Und komischerweise auch mit der falschen 
Portzuweisung! Ich habe die Portzuweisung nun auf 0xFF gesetzt, was an 
meinem obigen Problem nix ändert.

von Sebastian S. (rudimentor)


Lesenswert?

@Karl Heinz:

Danke für den Hinweis! Das wars! Ich habe in TIMSK jezt anstelle TOIE1 
das OCIE1A Bit gesetzt, noch den ISR Vector geändert in 
TIMER1_COMPA_vect und schon kann ich TCNT1 weglassen.
Vielen Dank!

Und Danke für Eure Geduld mit Anfängern wie mir! Tolle Internetseite!

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.