Forum: Mikrocontroller und Digitale Elektronik ATmega8a Timer1: Umstellen von Overflow auf Output-Compare


von ForumsGast380042 (Gast)


Angehängte Dateien:

Lesenswert?

Hallo allerseits

Folgendes Problem:

Mein Programm soll folgendes machen (was es nur bedingt macht):

Timer1 auf Overflow einstellen, nach dem 10. Overflow wird Timer1 in der 
ISR auf Output-Compare umgestellt (ca. halbe Dauer zwischen zwei 
Overflows). Sobald ein Compare-Match stattfindet, wird in dieser ISR 
wiederum auf Overflow umgestellt und das ganze beginnt von vorne.

Jetzt die Frage: So wie es aussieht, funktioniert das nur wenn man 
zuerst den ersten Compare-Match abwartet und erst beim zweiten 
Compare-Match wieder auf Overflow umstellt. Weiss jemand, ob diese 
Annahme meinerseits so richtig ist und wenn ja, wieso?

Wie ich es programmiert habe, seht ihr im Anhang.

Gruss

von Karl H. (kbuchegg)


Lesenswert?

Kleiner Tip:

WEnn du Code einfach als Textfile anhängst, dann
* hast du weniger Arbeit
* kann man sich als Antworter viel einfacher auf den Code beziehen,
  weil man den relevanten Teil einfach in die Antwort einkopieren
  kann
* kann man zur Not auch schon mal den Code rauskopieren um das auf
  seinem Heimsystem mal auszuprobieren.

Ergo hast du weniger Arbeit, wir haben wir weniger Arbeit, die Hilfe 
geht effizienter und du kriegst schneller eine Analyse. BWL-Studenten 
würden sagen: eine Win-Win Situation.

Code einfach nur als File anhängen.
Und das Bild ebenso.

von ForumsGast380042 (Gast)


Angehängte Dateien:

Lesenswert?

No problem...

von Thomas E. (thomase)


Lesenswert?

ForumsGast380042 schrieb:
> Jetzt die Frage: So wie es aussieht, funktioniert das nur wenn man
> zuerst den ersten Compare-Match abwartet und erst beim zweiten
> Compare-Match wieder auf Overflow umstellt. Weiss jemand, ob diese
> Annahme meinerseits so richtig ist und wenn ja, wieso?


1
void initTimer1OutComp(void)
2
{
3
  togglePinC4();
4
  OCR1A = 0x8000;
5
  TIMSK = 0x00;
6
  TIMSK = (1<<OCIE1A); // Interrupts akivieren:  Oupt Compare Match A
7
  TCCR1B = (1<<WGM12) | (1<<CS10);             // Outputcompare with TOP = OCR1A, kein PreScaler
8
  sei();
9
}
1
void initTimer1OV(void) // Timer 1 auf Overflow einstellen
2
{
3
  TIMSK = 0x00;
4
  TIMSK = (1<<TOIE1); // Interrupts akivieren:  Overflow Timer1
5
  TCCR1B = (1<<CS10); // PreScaler = 1
6
  sei();
7
  
8
}

Das "sei();" in diesen beiden Funktionen ist kapitaler Bockmist. Denn 
diese werden jeweils in einer ISR aufgerufen und geben die globalen 
Interrupts zu früh frei. Und das führt dann in 99,99999% aller Fälle, so 
auch in deinem, zu Fehlverhalten, bei dem man sich die Haare raufen 
kann.
Lässt sich wunderschön debuggen, also richtig in Hardware. Natürlich 
nicht auf dem 8er. Aber auf einem Controller, der das kann.

Mach das richtig. Einmal "sei();" freigeben und gut ist. Und oben die 
Prototypen für die Funktionen rein. Dann klappt das auch.
0(!) Warnings.

Eine Frage aber noch: Wozu braucht man sowas?

mfg.

von ForumsGast380042 (Gast)


Lesenswert?

Hallo

Danke für die Tipps, sehe ich ein.

Aber: Habs jetzt so programmiert und es ändert nichts. Ich muss immer 
noch den zweiten Compare-Match abwarten und erst dann die Umstellung auf 
Overflow vornehmen..

Gruss

von Spess53 (Gast)


Lesenswert?

Hi

>Aber: Habs jetzt so programmiert und es ändert nichts. Ich muss immer
>noch den zweiten Compare-Match abwarten und erst dann die Umstellung auf
>Overflow vornehmen.

Warum schaltest du überhaupt ständig zwischen den Interrupts um? Ein 
Compare-Interrupt bei einem OCR-Wert von 0xFFFF ist identisch mit einem 
Overflow-Interrupt.

MfG Spess

von Thomas E. (thomase)


Lesenswert?

Spess53 schrieb:
> Warum schaltest du überhaupt ständig zwischen den Interrupts um? Ein
> Compare-Interrupt bei einem OCR-Wert von 0xFFFF ist identisch mit einem
> Overflow-Interrupt.
Die Frage habe ich mir auch gestellt.

ForumsGast380042 schrieb:
> Aber: Habs jetzt so programmiert und es ändert nichts. Ich muss immer
> noch den zweiten Compare-Match abwarten und erst dann die Umstellung auf
> Overflow vornehmen..
Natürlich. Das macht genau, was es soll. Setzt du allerdings 
"secondCompMatch" in der Overflow-ISR auf true. Dann macht die Comp-ISR 
nur einmal. Das hat sie mit den "sei();" in den ISRs nicht getan.

Aber wie Spess schon schrieb, ein OCR1A = 0xffff hat den gleichen Effekt 
wie ein Overflow.

mfg.

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.