Forum: Mikrocontroller und Digitale Elektronik ATmega Timer CompareMatch


von Maddin (Gast)


Lesenswert?

Hallo, ich arbeite mit einem ATmega64A und will zwei unterschiedliche 
Interrupttaktquellen definieren. Die Initialisierung habe ich so 
gemacht:
1
TCCR1B = (1<<CS10) + (1<<CS12) + (1<<WGM12);  // /1024 CTC-Mode
2
OCR1A = 39;    // 8MHZ/1024/39=200Hz
3
OCR1B = 2;    // 8MHz/1024/2=3906Hz
4
TIMSK |= (1<<OCIE1B) + (1<<OCIE1A); //Compare Match A&B

Die Interrupt handle ich mit
1
ISR(TIMER1_COMPA_vect)
und
1
ISR(TIMER1_COMPB_vect)

Beide ISR´s werden jedoch im 200Hz Takt aufgerufen. Woran könnte das 
liegen. Wenn mehr Infos benötigt bitte fragen.

Gruß

Maddin

von spess53 (Gast)


Lesenswert?

Hi

> Woran könnte das liegen.

An der Tatsache, das das nicht funktionieren kann.

Angenommen der Timer läuft bei 0 los, erreicht er irgenwann OCR1B und 
löst den Interrupt aus. Dann zählt er weiter bis er bei OCR1A angelangt 
ist. Der passende Interrupt wird ausgelöst und bei Null wieder 
angefangen.

MfG Spess

von Karl H. (kbuchegg)


Lesenswert?

Maddin schrieb:

> Beide ISR´s werden jedoch im 200Hz Takt aufgerufen. Woran könnte das
> liegen. Wenn mehr Infos benötigt bitte fragen.

Die Aufruffrequenz wird so wie du das machst immer dadurch festgelegt, 
wie weit der Zähler zählt.
Mit dem OCR1B Wert bestimmts du nur die 'Phasenlage' der Interrupts 
innerhalb eines Zählzykluses.

Anders ausgedrückt:
Wenn dein einer 'Wecker' immer dann klingelt, wenn der Sekundenzeiger 
auf 10 steht, und der andere dann, wenn der Sekundenzeiger auf 25, dann 
werden beide Wecker trotzdem jede Minute nur 1 mal klingeln. Allerdings 
zu unterschiedlichen Zeitpunkten innerhalb dieser Minute.

(Bei dir ist es dann halt so, dass der Wecker nach 25 Sekunden wieder 
bei 0 anfängt, das ändert aber nichts daran, dass der 10 Sekunden 
Klingler innerhalb der 25 Sekunden nur 1 mal kommt)

Allerdings:
Es spricht nichts dagegen, in einer ISR sich den nächsten OCR Wert 
auszurechnen und zu setzen. Dann kann man tatsächlich unterschiedliche 
Frequenzen erreichen.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Sie werden aber nicht zum gleichen Zeitpunkt aufgerufen?

TIMER1_COMPB_vect wird wesentlich früher aufgerufen und erst wieder, 
nachdem TIMER1_COMPA_vect aufgerufen wurde.

Ein Match TCNT1 mit OCR1B kann erst wieder treffen, nachdem TCNT1 
zurückgesetzt wurde, d.h. nach dem Match TCNT1 mit OCR1A.

Du könntest in der schnelleren ISR den Matchwert erhöhen

ISR(TIMER1_COMPB_vect)
{
  OCR1B += 2;    // 8MHz/1024/2=3906Hz
}

Und in der langsameren ISR resetten

ISR(TIMER1_COMPA_vect)
{
  OCR1B = 2;    // 8MHz/1024/2=3906Hz
}

Der ISR-Overhead in Verbindung mit dem Prescalerwert entscheidet, ob das 
funktioniert. Schwierig (unmöglich?) wird es, wenn beide Frequenzen 
keine Teiler voneinander sind, so wie in deinem Fall.

von Maddin (Gast)


Lesenswert?

Ich muss mir das jetz erstmal alles durch den Kopp gehen lassen was ihr 
so geschrieben habt. Danke euch.


Stefan B. schrieb:
> Sie werden aber nicht zum gleichen Zeitpunkt aufgerufen?

Nein nein, beide haben gleiche Periode, werden aber zu deutlich (ca 
0.5ms) unterschiedlichen Zeiten aufgerufen. So wie ichs beim Überfliegen 
eurer Antworten bis jetz verstanden habe macht das auch Sinn.

Nun werd ich mir das mal genauer anschauen, ich denke ihr seit meinem 
Wochen-Problem auf die Spur gekommen.

Gruß

Maddin

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.