Hallo Ich bekomme mein Timer0 mit dem CTC nicht zum laufen. Kann mir jemand sagen wo hier das Problem ist. Laut Datenblatt sind die Register und der Interrupt-Vector richtig wenn ich es verstanden habe :) Der Port B sollte nach ~ 7,8 sek auf 1 gehen. #define F_CPU 4000000UL #include <stdio.h> #include <avr\io.h> #include <avr\interrupt.h> int Teiler; // ISR( TIMER0_OVF_vect ) // Interrupt Overflow Aufruf Timer 0 ISR( TIMER0_COMPA_vect ) // Interrupt Compare A Aufruf Timer 0 { Teiler++; if( Teiler == 1000 ) { Teiler = 0; PORTB = 0xFF; } } int main() { DDRB = 0xff; // Setze Port B als Ausgang PORTB = 0x00; // Port B auf 0 setzen Teiler = 0; TCCR0A |= (1<<WGM01); // Aktiviere CTC zum OCR0A Werte vorgeben TCCR0B |= (1<<CS00 | 1<<CS02); // Setze Counter 0 prescaler 1024 TIMSK |= (1<<TOIE0); // Aktiviere Overflow Interrupt für Counter 0 OCR0A = 128; // Wert für CTC sei(); // Aktiviere Interrups allgemein while( 1 ) { } }
Otto wrote: > Hallo Thomas, > > das "volatile" für "Teiler" fehlt z.B. > > Gruss Otto Hallo Otto, habe jetzt "volatile int Teiler;" eingefügt aber es möchte noch immer nicht funktionieren. Gruss Thomas
kannnicht
> TIMSK |= (1<<TOIE0); // Aktiviere Overflow Interrupt für
Du musst den Comparematch Interrupt aktivieren
Gruß
/XlR.
Axel Rühl wrote: > kannnicht > >> TIMSK |= (1<<TOIE0); // Aktiviere Overflow Interrupt für > > Du musst den Comparematch Interrupt aktivieren > > Gruß > /XlR. Upps, danke das wars. Hatte davor den Timer mit Overflow versucht und das total übersehen. Mir fehlt aber auch noch ein bisschen die Erfahrung. Sind momentan meine ersten Versuche. Ab wann muss man den seine Variablen mit "volatile" deklarieren ? Gruss Thomas
> Ab wann muss man den seine Variablen mit "volatile" deklarieren ?
volatile musst du dann nehmen, wenn Gefahr besteht, dass
der Compiler einen Zugriff auf die Variable wegoptimieren
könnte. Grob gesagt: Immer dann, wenn es für den Compiler
nicht ersichtlich ist, dass eine Variable auf anderen
Wegen als die die dem Compiler bekannt sind einen neuen
Wert kriegt.
volatile macht nichts anderes, als einfach nur mögliche
Optimierungen auf dieser Variablen abzuschalten.
Bsp:
du hast folgende Schleife
unsigned char i;
unsigned char a;
void foo()
{
i = 0;
while( i == 5 ) {
a = 8;
}
}
Wenn der Compiler diese Funktion übersetzt, dann findet die
Datenflussanalyse heraus, dass i zu Beginn der Schleife
den Wert 0 hat. Weiters findet die Analyse heraus, dass
es innerhalb der Schleife keine Möglichkeit für i gibt,
je verändert zu werden. Da i daher immer den Wert 0 hat,
kann die Schleife niemals betreten werden und kann damit
komplett wegfallen.
Nur: Jetzt kommt dein Programmund installiert einen Interrupt-
handler, welcher - Überraschung - sehr wohl i irgendwann mal
auf 5 setzt.
Nur: Das weis der Compiler nicht, wenn er foo() übersetzt.
Also muss man ihm mitteilen: Spar dir Optimierungen, die über
i laufen. i ändert seinen Wert auf Wegen die für dich nicht
einsehbar sind.
Und genau das macht das volatile
volatile unsigned char i;
Jetzt trifft der Compiler keinerlei Annahmen mehr über i.
Er speichert den Wert der Variablen auch nicht in einem
CPU Register zwischen, wie zb hier:
j = i + i;
sondern liest bei jeder Erwähnung von i den Wert tatsächlich
aus dem Speicher aus. (Im obigen wäre das ja eigentlich unsinnig.
Speicher auslesen kostet Zeit. Wenn der Compiler i einmal holt
und dann verdoppelt kommt das gleiche raus)
Leider verkommt volatile bei vielen Programmierern zu:
Wenn du in einem ISR eine Variable benutzt, muss diese
volatile sein.
Unsinn. Jetzt weist du was wirklich dahinter steckt.
In deinem Pgm hast du den Fall aber nicht, selbst wenn
der ISR-Vektor richtig gestellt ist. Da Teiler eine globale
Variable ist, wird die vom Compiler sowieso mit 0 initialisiert.
Die Zuweisung von 0 in main() bewirkt also im Grunde genommen
gar nichts. Damit kommt Teiler aber nur noch in der ISR vor
und damit besteht die Gefahr gar nicht.
@Karl heinz Buchegger Danke, eine bessere Erklärung für "voaltile" habe ich no nie bekommen.... Respekt
Tach ich bin Hier neu und Wollte Fragen wie ich meinen Counter Aktiviere also das man ihn sieht und er auch schön Zählt
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.