Timer und TCNT1

Gast #130456
Lesenswert?
• ▲
▼
Hi,

ich bin gerade dabei mich mit den Timer/Counter Funktionen des ATmega8
zu beschäftigen.
Mein Ziel war es, ein 1 Sekundentakt zu erzeugen.
Dies ist mir nun auch nach langem Kopfzerbrechen gelungen.
Allerdings ist da noch etwas unklar.

Nachdem der Interrupt aufgerufen wurde, wird TCNT1 nicht automatisch
resettet, sondern zählt fröhlich weiter nach oben.
Ist dies normal? Wäre doch dumm, wenn man TCNT1 nach jedem auftreten
des Interrupts auf 0 setzen muss. Es funktioniert zwar dann, aber würde
mir das nich um 3 Takte die Sekunde verfälschen?:
ldi temp, 0xFF
out TCNT1H, temp
out TCNT1L, temp

Oder ist es ein Bug im AVRStudio?

Den Code hab ich mal mit angehangen.

Gruß
Daniel
Angehängte Dateien:
Gast #130457
Lesenswert?
• ▲
▼
also ich kenne assembler nicht aber bei c macht man es so , das wenn der
interrupt aufgerufen wird man den tcnt1 auf null setzt wenn es erwünscht
ist und soweit ich weis verfälscht das deine zählung auch nicht
Gast #130458
Lesenswert?
• ▲
▼
Nutze statt dem TimerOverFlow den TimerCompare CTC (Mode 4), der resetet
den Timer automatisch nach dem Erreichen des Wertes in OCR1A.
Das Register musst Du nur einmal setzen und dann nie wieder (Beim Reset
endet diese Welt...).
Denke daran das Du dann einen anderen Vektor für den Interrupt nutzen
musst.

MooseC
Gast #130459
Lesenswert?
• ▲
▼
hey, danke für die schnellen Antworten.
Aber Moment mal! :)

Ich nutze doch den compare mode, oder nicht?

mit
ldi temp, 1<<OCIE1B
out TIMSK, temp

Habe ich doch das richtige Bit gesetzt.
Das Datenblatt sagt:
Bit 3   OCIE1B: Timer/Counter1, Output Compare B Match Interrupt
Enable

Was ist also der Fehler? :(
Gast #130460
Lesenswert?
• ▲
▼
Immer mit der Ruhe!
Ich hatte gar nicht in Deinen Code geschaut, da ich annahm Du
verwendest den normalen Timerinterrupt und Mode. Bei den erwähnten
zusätzlichen Takten lag das nahe.

Der CTC verwendet meines Wissens nur den OCR1A (oder ICR1 im MODE 12)
als Limit für den Zählwert, Du verwendet aber OCR1B.

MooseC
Gast #130461
Lesenswert?
• ▲
▼
Du mußt TimerCompare CTC aktivieren (siehe Datenblatt PDF) und Deine ISR
über den Timer Overflow laufen lassen statt Output Compare B Match
Interrupt ansonsten werden Pins für PWM geschaltet (high/low-Wechsel).

Gruß
Andi
Gast #130463
Lesenswert?
• ▲
▼
Das stimmt nicht ganz, denn der Overflowinterrupt TOV1 wird als 17te Bit
beim Überlauf des 16 Bit Countregister gesetzt und löst so einen
Interrupt aus. Für den CTC gibt es den OCF1A, der natürlich auch seinen
eigenen Vektor hat, Der CTC hat keinen Überlauf auf das 17te Bit

MooseC
Gast #130464
Lesenswert?
• ▲
▼
Hi,
tut mir leid, aber jetzt bin ich noch mehr durcheinander.
Soviel Register wie es da gibt :(

Also ich hab den Code jetz mal geändert.
Es funktioniert aber leider immernoch nicht.

Könnte vielleicht einer von euch, den Code grad so ändern, das es
richtig ist?
Ich denke viel kann da ja jetzt nicht mehr falsch sein :(

Danke!
Daniel
Angehängte Dateien:
Gast #130465
Lesenswert?
• ▲
▼
Alles wichtige wurde bereits gesagt, verstehen und umsetzen mußt Du es
schon selber.
Das Teil viele Register, ja, und nur Du kannst es für Dich entdecken..

Fertiger Code nützt Dir da garnichts

MooseC
Gast #130468
Lesenswert?
• ▲
▼
Hallo!

Ich habe hier den Compare-Match Mode gewählt(ATMEGA8535 mit 8Mhz Takt).
Leider läuft der Timer1
noch zu schnell. Was könnte ich da falsch gemacht haben?

TCCR1A=0x00;
TCCR1B=0x0B;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x04;
OCR1AL=0xE2;
OCR1BH=0x00;
OCR1BL=0x00;

TIMSK=0x10;

// Timer 1 output compare A interrupt service routine
interrupt [TIM1_COMPA] void timer1_compa_isr(void)
{
PORTB = ~PORTB;
if (zehntelsek < 9) ++zehntelsek;
else
    {
     zehntelsek = 0;
     if (sekunden < 59) ++sekunden;
     else
        {
        sekunden = 0;
        if (minuten < 59) ++minuten;
        else
           {
           minuten = 0;
           if (stunden < 23) ++stunden;
           else
              {
              stunden = 0;
              }
           }
        }
    }
}

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