Atmel AVR Mikrocontroller
8 Bit-Timer im Output-Compare-Mode
Im Output Compare Modus können Sie dem Timer mitteilen, bis zu welchem Wert er hochzählen soll.
In dieser Betriebsart müssen Sie also nicht mehr auf einen Timerüberlauf (bei einem 8-Bit-Timer 255 bzw. bei einem 16-Bit-Timer 65535) warten, sondern können bereits früher, zu jedem Zeitpunkt, einen Interrupt auslösen.
Output Compare Flag und Compare Register
Der Timer zählt auch in dieser Betriebsart hoch, vergleicht aber der Zählwert ständig mit einer Obergrenze.
Wird die Obergrenze erreicht, wird z.B. ein Interrupt ausgelöst oder das Output Compare Flag abgefragt. Diese Obergrenze steht im Output Compare Register (z.B.: OCR0A) und ist ein Wert zwischen 0 und 255.
Da der Timer ständig vergleicht, wird dieser Modus auch Compare-Mode genannt.
Einstellung des Compare-Mode
- TCCR Register für den compare match modus einstellen
- Prescaler auf den gewünschten Wert setzen
- Output-Compare-Register (OCR) auf den gewünschten Vergleichswert stellen
- Compare match Interrupt aktiviern
- Alle Interrupts aktivieren sei();
Programmbeispiel, welches alle 100us einen Output Compare Interrupt auslöst:
// Controller: ATMEL AT90PWM316
// Date: 26.08.2012
// Author: Heimo Gaicher
#include <avr/io.h>
#include <avr/interrupt.h>
#define F_CPU 8000000 // T system clock = 8MHz
int main(void)
{
DDRB |= (1<<PB2); // PB2 = Ausgang
TCCR0A |= (1<<COM0A1); // Clear OC0A on compare match
TCCR0A |= (1<<WGM01); // Mode = CTC
TCCR0B |= (1<<CS01); // Prescaler = 8 --> T system clock = 1Mhz --> T = 1us pro Zyklus
OCR0A = 99; // Output Compare Register mit 99 vorladen. Das ergibt alle 100 us einen Interrupt
TIMSK0 |= (1<<OCIE0A); // Compare match interrupt aktivieren
sei(); // Alle Interrupts aktivieren
while(1)
{
asm ("NOP");
}
return 0;
}
ISR (TIMER0_COMP_A_vect)
{
PORTB ^= (1 << PB2); // PB2 toggeln
}
Portpin PB2
Wie dieses Oszilloskopbild zeigt, toggelt der Portpin PB2 nun alle 100us.
Wird der Vergleichswert im OCR-Register verändert, so verändert sich die Zeit, in der ein neuer Interrupt ausgelöst wird.
Wird das OCR0A-Register mit 19 vorgeladen, so werden 19 Zykluszeiten gezählt und danach ein Interrupt generiert. D.h., nach 20 Zykluszeiten wird der Interrupt ausgelöst.
Eine Zykluszeit beträgt bei einer Taktfrequenz von 8MHz und einen Prescaler von 8 genau 1us.
8000 000 / 8 = 1000 000 Hz
T = 1 / 1000 000 --> Eine Zykluszeit = 1us
Im folgenden Bild wird alle 20us ein Interrupt ausgelöst (OCR0A = 19;):