Hallo habe eine Frage wie ich den Teimer0 benutzen kann? Ich habe den teimer0 initialisiert dass er alle 16 ms einen Overflow erzeugt. Ich möchte eine Diode alle 3 Sekunden an und wider aus schalten. Nun ist meine Frage wie kriege ich das hin? Habe hier im Tutorium gelesen dass wenn ein Overflow kommt dann wird in TIFR Register T0V0 auf Null gesetzt. Bedeutet für mich der Teimer0 ist wieder aus. Muss ich den Timer jetzt 3s/16ms=187,5 mal neu starten. Nun habe ich das auch gemacht und die Diode leuchtet und leuchtet. kann mir jemand sagen was ich falsch mache ? hier mein Quelltext #include "avr/io.h" #include "iom128.h" #define _AVR_ATMEGA128_ 1 #define OSCSPEED 16000000 /* in Hz */ void PORT_Init() { PORTA = 0b00000000; DDRA = 0b01000000; //Relay set as output (Bit6 = 1) PORTB = 0b00000000; DDRB = 0b00000000; PORTC = 0b00000000; DDRC = 0b11110111; PORTD = 0b11000000; DDRD = 0b00001000; //TX set as output (Bit3 = 1) PORTE = 0b00000000; DDRE = 0b00110000; //Buzzer set as output (Bit4 = 1, Bit5 = 1) PORTF = 0b00000000; DDRF = 0b00000000; PORTG = 0b00000000; DDRG = 0b00000000; } void init_timer0() { TCCR0 |= 0b00000111; TCNT0 = 6; TIMSK |= 0b00000001; } int main() { while(1) { int i,j; for (i=0; i<175; i++) { init_timer0(); PORTA = PORTA | 0b11000000; } for (j=0; j<175; j++) { init_timer0(); PORTA = PORTA & 0b00000000; } } }
Wojtek Szopieraj wrote: > Hallo habe eine Frage wie ich den Teimer0 benutzen kann? > Ich habe den teimer0 initialisiert dass er alle 16 ms einen Overflow > erzeugt. Ich möchte eine Diode alle 3 Sekunden an und wider aus > schalten. > Nun ist meine Frage wie kriege ich das hin? > Habe hier im Tutorium gelesen dass wenn ein Overflow kommt dann wird in > TIFR Register T0V0 auf Null gesetzt. Bedeutet für mich der Teimer0 ist > wieder aus. nein..wo liest du denn das bitte raus?? und im Moment machst du mit dem Timer auch gar nichts, außer ihn am laufenden Band eine "Initialisierung"...
habe das gelesen in "http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Timer-Bitzahlen_verschiedener_AVR.27s" Bei den Timer "Um nun also den Timer0 in Betrieb zu setzen und ihn mit einer Frequenz von 1/1024-tel des CPU-Taktes zählen zu lassen, schreiben wir die folgende Befehlszeile: TCCR0 |= (1<<CS00)|(1<<CS02); Der Zähler zählt nun aufwärts bis 255, um dann wieder bei 0 zu beginnen. Der aktuelle Zählerstand steht in TCNT0. Bei jedem Überlauf von 255 auf 0 wird das Timer Overflow Flag TOV0 im Timer Interrupt Flag TIFR-Register gesetzt und, falls so konfiguriert, ein entsprechender Timer-Overflow-Interrupt ausgelöst und die daran gebundene Interrupt-Routine abgearbeitet. Das TOV Flag lässt sich durch das Hineinschreiben einer 1 und nicht wie erwartet einer 0 wieder zurücksetzen. " Habe ich da etwas falsch verstanden. wie starte ich den Timer dan? Es reicht ja 1 mal den timer zu initialisieren.
Wojtek Szopieraj wrote: > habe das gelesen in > "http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Timer-Bitzahlen_verschiedener_AVR.27s" > Bei den Timer > > "Um nun also den Timer0 in Betrieb zu setzen und ihn mit einer Frequenz > von 1/1024-tel des CPU-Taktes zählen zu lassen, schreiben wir die > folgende Befehlszeile: > > TCCR0 |= (1<<CS00)|(1<<CS02); > > Der Zähler zählt nun aufwärts bis 255, um dann wieder bei 0 zu beginnen. > Der aktuelle Zählerstand steht in TCNT0. Bei jedem Überlauf von 255 auf > 0 wird das Timer Overflow Flag TOV0 im Timer Interrupt Flag > TIFR-Register gesetzt und, falls so konfiguriert, ein entsprechender > Timer-Overflow-Interrupt ausgelöst und die daran gebundene > Interrupt-Routine abgearbeitet. Das TOV Flag lässt sich durch das > Hineinschreiben einer 1 und nicht wie erwartet einer 0 wieder > zurücksetzen. " > > Habe ich da etwas falsch verstanden. ja > wie starte ich den Timer dan? Es reicht ja 1 mal den timer zu > initialisieren. Der Timer wird durch das setzen von TCCR0 automatisch gestartet. Und wenn man sonst wweiter nichts einstellt, würde er ewig im Hintergrund weiterlaufen. Beim Erreichen des Maximalwerts (bei 16Mhz und Prescaler 1024 1/61 s) wird dann das Interruotflag gesetzt. Das tut erstmal nichts, nur wenn das der Overflow-Interrupt aktiviert ist. Dann springt er in die zugehörige Interrupt-Routine (siehe Tut), wo du dann darauf reagieren kannst (der Timer läuft in der Zwischenzeit weiter). In dieser Routine könntest du zB eine selbst definierte Zählvariable hochzählen lassen und die dann in der Hauptroutine auswerten, zB um die 3 Sekunden zu messen...
Wojtek Szopieraj wrote: > Nun ist meine Frage wie kriege ich das hin? > Habe hier im Tutorium gelesen dass wenn ein Overflow kommt dann wird in > TIFR Register T0V0 auf Null gesetzt. Bedeutet für mich der Teimer0 ist > wieder aus. Erstens wird es nicht auf 0 gesetzt, sondern auf 1. Auf 0 wird es erst wieder gesetzt, wenn der dazugehörige Interrupt Handler ausgeführt wird. Wenn ohne Interrupt gearbeitet wird, dann muss das Flag von Hand gelöscht werden. Zweitens geht dadurch nicht der Timer aus. Der läuft so lange weiter, bis er über die CS-Bits im TCCR0 anghalten wird. > Muss ich den Timer jetzt 3s/16ms=187,5 mal neu starten. Nein. Siehe oben. > #include "iom128.h" Was soll dieses #include? Was für eine Datei soll das sein? Du hast doch oben schon die avr/io.h eingebunden. Die genügt völlig. > #define _AVR_ATMEGA128_ 1 Und was soll das? > #define OSCSPEED 16000000 /* in Hz */ Wenn schon, dann bitte F_CPU nennen. Damit können dann auch eventuelle Header was anfangen. > void init_timer0() > { > TCCR0 |= 0b00000111; > TCNT0 = 6; > TIMSK |= 0b00000001; > } Bitte schau Dir mal den Artikel zum Thema Bitmanipulation an und benutze die Bitnamen. Das kann so keiner vernünftig lesen. Außerdem ist ein Timer-Vorladen keine gute Idee. Für solche Dinge haben die Timer den CTC-Modus. Aber OK, für den Anfang kann man es so machen... > int main() > { > while(1) > { > int i,j; > for (i=0; i<175; i++) > { > init_timer0(); > PORTA = PORTA | 0b11000000; > } > for (j=0; j<175; j++) > { > init_timer0(); > PORTA = PORTA & 0b00000000; > } > } > } Wie oben schon gesagt, es ist Unsinn, den Timer ständig neu zu initialisieren. Aber das größte Problem ist, dass Du nirgends etwas mit dem Timer machst! Das Überlauf-Ereignis wird nirgends ausgewertet. Wie soll denn auf die Weise irgendetwas passieren? Die LED geht zwar vermutlich ständig aus und an, aber so schnell, dass Du es nicht sehen kannst. Es wird jedes Mal 175 mal der Timer initialisiert und dann die LED umgeschaltet.
wass muss ich dann noch machen um den timer zu benutzen, gibt es irgendowo ein einfaches beispiel ??
> wass muss ich dann noch machen um den timer zu benutzen, In der Init: - Timer einschalten (Vorteiler wählen) - Timer-Interrupt freigeben - Interrupts global freigeben (I-Flag setzen, SEI) In der ISR: - Zählvariable herunterzählen - bei Zählerstand 0 Aktion ausführen und Zählvariable auf Startwert setzen - falls die Aktion etwas umfangreicher ist, dann stattdessen einen Merker setzen, den die Mainloop abfragt, löscht und die Aktion ausführt - ISR möglichst kurz halten, also keine komplexen Funktionen aufrufen > gibt es irgendowo ein einfaches beispiel ?? Von mir nicht, ich werkele nur in ASM. ...
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.