Noch ein kleines Programm, was euch eventuell einmal hilfreich sein könnte:
AVR-Timer-Calculator
Kurzbeschreibung:
Das Programm ermittelt die Reload- und Compare-Werte für eine vorgegebene Zeit bei unterschiedlichen Prescalern. Zur Berechnungen werden Prescaler von 2 bis 4096 zu Grunde gelegt.
Hinweis:
Nicht alle Timer der AVR-Mikrocontroller besitzen alle zur Berechnung genutzten Prescaler. Ihr solltet also prüfen, welche Prescaler das Timermodul eures AVRs besitzt.
Revision 1.2
Dirk
Kurze Erläuterung zu Overflow- und Compare-Interrupts:
Wenn du in bestimmten periodischen Zeitintervallen Programmteile ausführen möchtest, eignet sich zum Beispiel ein Overflow-Interrupt oder ein Compare-Interrupt eines Timers.
Overflow-Interrupt
Bei dem Overflow-Interrupt läuft der Timer ab einem bestimmten Wert los. Erreicht er das Ende (0xFF bei 8bit, 0xFFFF bei 16bit Timer), wird der Overfllow-Interrupt ausgelöst. In der Interruptroutine muss man den Timer wieder selbst auf den Anfangswert (Reloadwert) stellen (das muss möglichst zu Begin der Interruptroutine erfolgen).
Compare-Interrupt
Bei dem Compare-Interrupt läuft der Timer ab 0x00 los. Erreicht er den Wert, der zuvor in einem Compare-Register festgelegt wurde, wird der Compare-Interrupt ausgelöst, der Timer wird automatisch wieder auf 0x00 zurückgesetzt (CTC-Mode = Clear Timer on Compare Event).
Die Periodendauer des Interrupts läßt sich nun bei gegebener Oszillatorfrequenz (fosc) einerseits durch den Prescaler und andererseits durch den Reloadwert oder den Comparewert beeinflussen.
Die Taktzeit für den Timer ergibt sich folgendermaßen: tclk = Prescaler/fosc.
Beispiel:
8bit Timer, fosc = 16MHz, Interrupt-Periodendauer = 1ms
Overflow-Interrupt:
Prescaler = 128, Reloadwert = 131
1ms = (256-Reloadwert) x Prescaler / fosc
1ms = (256-131) x 128 / 16MHz
Compare-Interurpt:
Prescaler = 128, Comparewert = 124
1ms = (Comparewert+1) x Prescaler / fosc
1ms = (124+1) x 128 / 16MHz
Um den Overflow-Interrupt des Timers zu nutzen, musst du
Compare, fosc = 16MHz, Periodendauer = 1ms
CodeBox C
Der Autor dieses Programms haftet nicht für Schäden an Soft- oder Hardware oder Vermögensschäden, die durch das Benutzen des Programms entstehen, es sei denn diese beruhen auf einem grob fahrlässigen oder vorsätzlichen Handeln des Autors, seiner Erfüllungsgehilfen oder seiner gesetzlichen Vertreter.
AVR-Timer-Calculator
Kurzbeschreibung:
Das Programm ermittelt die Reload- und Compare-Werte für eine vorgegebene Zeit bei unterschiedlichen Prescalern. Zur Berechnungen werden Prescaler von 2 bis 4096 zu Grunde gelegt.
Hinweis:
Nicht alle Timer der AVR-Mikrocontroller besitzen alle zur Berechnung genutzten Prescaler. Ihr solltet also prüfen, welche Prescaler das Timermodul eures AVRs besitzt.
Revision 1.2
Dirk
Kurze Erläuterung zu Overflow- und Compare-Interrupts:
Wenn du in bestimmten periodischen Zeitintervallen Programmteile ausführen möchtest, eignet sich zum Beispiel ein Overflow-Interrupt oder ein Compare-Interrupt eines Timers.
Overflow-Interrupt
Bei dem Overflow-Interrupt läuft der Timer ab einem bestimmten Wert los. Erreicht er das Ende (0xFF bei 8bit, 0xFFFF bei 16bit Timer), wird der Overfllow-Interrupt ausgelöst. In der Interruptroutine muss man den Timer wieder selbst auf den Anfangswert (Reloadwert) stellen (das muss möglichst zu Begin der Interruptroutine erfolgen).
Compare-Interrupt
Bei dem Compare-Interrupt läuft der Timer ab 0x00 los. Erreicht er den Wert, der zuvor in einem Compare-Register festgelegt wurde, wird der Compare-Interrupt ausgelöst, der Timer wird automatisch wieder auf 0x00 zurückgesetzt (CTC-Mode = Clear Timer on Compare Event).
Die Periodendauer des Interrupts läßt sich nun bei gegebener Oszillatorfrequenz (fosc) einerseits durch den Prescaler und andererseits durch den Reloadwert oder den Comparewert beeinflussen.
Die Taktzeit für den Timer ergibt sich folgendermaßen: tclk = Prescaler/fosc.
Beispiel:
8bit Timer, fosc = 16MHz, Interrupt-Periodendauer = 1ms
Overflow-Interrupt:
Prescaler = 128, Reloadwert = 131
1ms = (256-Reloadwert) x Prescaler / fosc
1ms = (256-131) x 128 / 16MHz
Compare-Interurpt:
Prescaler = 128, Comparewert = 124
1ms = (Comparewert+1) x Prescaler / fosc
1ms = (124+1) x 128 / 16MHz
Um den Overflow-Interrupt des Timers zu nutzen, musst du
- Timer auf Reloadwert setzen
- Overflow-Interrupt des Timers freigeben, eventuell zuvor Interrupt-Request-Flag löschen
- Prescaler festlegen (jetzt läuft der Timer)
- nicht vergessen global die Interrupts freizugeben
- In der Interrupt-Routine selbst den Timer wieder mit Reloadwert beschreiben (bei 16Bit hier auf die Schreib-Reihenfolge von low und high achten)
- Compareregister mit Comparewert beschreiben
- Timer auf 0x00 setzen
- Compare-Interrupt freigeben, eventuell zuvor Interrupt-Request-Flag löschen
- Prescaler festlegen (Timer läuft nun)
- globale Interrupts freigeben.
Compare, fosc = 16MHz, Periodendauer = 1ms
CodeBox C
void InitTimer0CompareAInt(void) { TIFR0 |= (1<<OCF0A); // Interrupt Request loeschen TIMSK0 |= (1<<OCIE0A); // Enable Output Compare A Interrupt OCR0A = 249; // CompareTime ist 1ms TCNT0 = 0; TCCR0A |= 1 << WGM01; // CTC Mode 2 TCCR0B |= (1<<CS01) | (1<<CS00); // 64 prescaler, Timer0 Start } ISR(TIMER0_COMPA_vect) { // Compare-Interrupt: // hier etwas tun, möglichst nur zeitkritische // Sachen erledigen }Rechtlicher Hinweis:
Der Autor dieses Programms haftet nicht für Schäden an Soft- oder Hardware oder Vermögensschäden, die durch das Benutzen des Programms entstehen, es sei denn diese beruhen auf einem grob fahrlässigen oder vorsätzlichen Handeln des Autors, seiner Erfüllungsgehilfen oder seiner gesetzlichen Vertreter.
Anhänge
Zuletzt bearbeitet: