Hallo Zusammen
Ich bin etwas verwirrt über den Vorteiler vom Timer0 und Timer1 bei
einem Atmega8. Gemäss Datenblatt wird dieser ja von beiden Timern
geteilt. Stelle ich den Vorteiler von Timer1 ein, verstellt es mir
allerdings auch den Takt von Timer0.
Ich verwende den internen 1MHz Takt.
Vom Code ist es folgendermassen:
Timer0 init:
TCCR0 = (1 << CS02); //clkIO wird durch 256 geteilt
TIMSK |= (1 << TOIE0); //Aktiviert Interrupt beim Überlauf
In der ISR von Timer0 lade ich den Timer vor mit:
TCNT0 = 236;
So erhalte ich in etwa alle 5ms einen Interrupt, welchen ich dazu nutze
verschiedene regelmässige Abfragen zu machen. Soweit läuft alles
einwandfrei.
Timer1 init: (Timer1 möchte ich als PWM verwenden)
TCCR1B |= (1 << CS10); //Vorteiler =1 Timertakt gleich clkIO Takt
Sobald ich hier den Vorteiler einstelle, ändert mir der Timer0, dass er
anstatt alle 5ms alle 6.7ms ausgelöst wird.
Weiss jemand von euch an was das liegen könnte? Nur weil Timer0 und
Timer1 den Vorteiler teilen, sollte es doch möglich sein,
unterschiedliche Teiler zu verwenden.
Besten Dank schon mal für allfällige Tips.
Gruss Phil
Welcher Vorgang im Vorteiler sollte das Verhältnis 5 / 6,7 bewirken?
Der teilt nur in (nicht lückenlosen) ganzzahligen 2er-Potenzen.
25% Änderung des internen Takts bekommt man weder mit Temperatur noch
mit Spannungsänderung zustande, allerdings per OSCCAL-Register.
Wie wurden die Zeiten gemessen?
Klingt mir jedenfalls so, als würdest du da einen Interrupt auslösen,
der den Mega aus Versehen resettet - sprich, ein Interrupt ohne Service
Routine.
Zeig doch mal das Programm.
Man stellt ja nicht wirklichen einen Teiler ein, sondern legt nur fest,
welcher Abgriff des eh vorhandenen Teilers (der tatsächlich für alle
Timer der gleiche ist) als Eingangstakt benutzt wird. Eine scheinbar
gegenseitige Beeinflussung ist ein Softwarefehler.
Hier mal noch den Code.
@Stefan E.: Nein Timer1 hat keine ISR nur der über OCR1A/B verstellt
wird.
@ H.Joachim S.: Das sehe ich genau so.
@ Matthias S.: Könntest du das etwas genauer erklären, wie es zu soetwas
kommen kann? Ich messe am Pin PB0 nähmlich ein Rechteck, obwohl dieser
ja konstant auf high sein sollte.
Hier wie gewünscht noch den Code
1
ISR(TIMER0_OVF_vect)
2
{
3
/*Achtung ! Durch verzögerter Aufruf dieser ISR kann das Vorladen des Timers zu Jetter führen.
4
* Ist nicht geeignet für Anwendungen bei der ein exaktes Mittel von 5ms erreicht werden soll.
Der Compare Interrupt Vector heisst nicht TIMER0_OVF_vect, damit
resettet Dein Programm regelmäßig.
Das erklärt auch das Rechteck auf PB0.
Schau Dir mal in der Doku an wie die ganzen Timer interrupts heissen und
wann sie aktiv werden.
Arduino Fanboy D. schrieb:> Oder ist das hier nicht nötig, und wenn, warum nicht?
Gute Frage. Das Programm hat zwar mindestens zwei IRQs, die ins Leere
zeigen
1
TIMSK|=((1<<OCIE1A)|(1<<OCIE1B));//Interrupts Enable von Compare A und B
aber eigentlich sollte ohne sei() gar nichts passieren.
Mmm, ja da habt ihr natürlich recht. Das sei()ist vorhanden, habs nur in
eine inlinefunktion im header und diesen beim kopieren nicht
mitgenommen, damit alles im main ist. sei() wird also schon aufgerufen
Gruss Phil
Problem gelöst:
- Das sei() brauchts natürlich, damit überhaupt eine ISR läuft, das war
mir jedoch klar.
- Das Problem war (wie Matthias S. schon sehr früh vermutete), dass die
ISR für den Timer1 nicht vorhanden waren.
1
TIMSK|=((1<<OCIE1A)|(1<<OCIE1B));//Interrupts Enable von Compare A und B
Ich dachte, dass man diese aktivieren muss, damit sich die Outputs bei
einem Match umschalten. Dem ist nicht so, wie ich nun herausgefunden
habe.
Danke euch viel mals für den Tip und die Unterstützung.
Gruss Phil
Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.
Wichtige Regeln - erst lesen, dann posten!
Groß- und Kleinschreibung verwenden
Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang