Hi, ich habe einen Atmega 16 und möchte den Timer0 im CTC Modus laufen lassen. Ich habe mir auf sämtlichen Internetseiten durch gelesen wie man den Timer0 im CTC Modus laufen lässt und hab alles beachtet was dort steht, aber trotzdem funktioniert der unten stehende code nicht. Kurz zur Erklärung was der code tun sollte: Also es wird wie gesagt der Timer0(8 bit Timer) verwendet den ich aber mit dem OCR0 nur bis 100 zählen lassen will und bei jedem Overflow wird die ISR ausgeführt. Die If befehle und die Zählvariable sind dafür da das die LED's die an den PINs angeschlossen sind ganz langsam blinken, damit ich die Zeit stoppen und überprüfen kann, ob alle Zeiten richtig sind. Ich hoffe mir kann jemand sagen was ich falsch gemacht habe. Danke schon mal im Voraus. #include <avr/io.h> #include <avr/interrupt.h> //Zählvariable deklarieren int i=0; ISR(TIMER0_COMP_vect) { //Bei jedem Overflow Zählvariable um eins erhöhen i++; //Nach 10.000 Overflows PINs auf high setzen entsprich einer sekunde if(i == 10000) { PORTD = 0b01100000; } //10.000 overflows später PINs auf low setzen entspricht einer sekunde if(i == 20000) { PORTD = 0b00000000; //Zählvariable auf null setzen damit das ganze von vorn beginnt i=0; } } int main() { //Datenrichtung definieren DDRD = 0b01100000; //Timer 0 initialisieren TCCR0 = (1<<CS01), (1<<WGM00); //Interrupts aktivieren TIMSK |= (1<<TOIE0); //Überlaufwert bei 100 OCR0 = 100; //Globale Interrupts aktivieren sei(); while(1) { //hier könnte ihr programm stehn!!! } }
terminator schrieb: > Ich habe mir auf sämtlichen Internetseiten durch gelesen wie man > den Timer0 im CTC Modus laufen lässt Aber die beiden tatsächlich maßgebenden Dokumente hast du dabei außer Acht gelassen, nämlich das Datenblatt und dein C-Buch.
1 | TCCR0 = (1<<CS01), (1<<WGM00); |
Nein, diese Zeile setzt nicht die beiden Bits in dem Register. Und selbst wenn sie es tun würde: nein, WGM00 aktiviert nicht den CTC-Modus bei Timer0 beim Mega16. Und als Ergänzung: Nein, "TOIE0" und "TIMER0_COMP_vect" passen nicht zusammen.
Hi Stefan, erst mal danke für die schnelle Antwort. Ich hab den Timer vorher im normalen Modus laufen lassen, also das er immer bis 256 zählt und dann die ISR aufgerufen wird und der Timer von vorne beginnt. Das hat auch wunderbar funktioniert. Erst als ich probiert hab den Overflow Wert herab zu setzen mit hilfe des OCR0 Registers hat es nicht mehr funktioniert. Also das die Register falsch gesetzt sind und das ganze nicht zusammen passt weis ich selbst, denn sonst würde der Mikrocontroller ja das tun was ich will. Ich hatte eher gehofft mir könnte jemand sagen wie ich es besser machen kann. Außerdem besitze ich leider kein C-Buch und kann somit nur mit den Internetseiten arbeiten. Mithilfe dieser Seiten bekomm ich es aber einfach nicht hin.
Ich meine mich zu erinnern, es den Compareinterrupt beim Mega8/16 nur beim 16bit Timer.
Schiko schrieb: > Ich meine mich zu erinnern, es den Compareinterrupt beim Mega8/16 nur > beim 16bit Timer. Das stimmt nicht siehe Datenblatt TIMER/COUNTER0: TIMSK Bit 1 – OCIE0: Timer/Counter0 Output Compare Match Interrupt Enable TIFR Bit 1 – OCF0: Output Compare Flag 0
Ist dein Simulator in der Entwicklungsumgebung kaputt? Damit kannst du den Programmablauf Schritt für Schritt simulieren und dabei alle Register verfolgen.
terminator schrieb: > Ich hatte eher gehofft mir > könnte jemand sagen wie ich es besser machen kann. Die drei Probleme deines Codes hatte ich dir genannt. Jetzt musst du dich daran machen diese zu lösen. Klar könnte ich dir eben auf die Schnelle den richtigen Code hinschreiben, aber der Lerneffekt für dich wäre dabei nahe Null. terminator schrieb: > Außerdem besitze ich leider kein C-Buch Du kannst eine Programmiersprache aber nicht durch Anschauen von Beispielen und Raten erlernen. Denn dann kommen genau solche Unsinnigen Zeilen dabei raus:
1 | TCCR0 = (1<<CS01), (1<<WGM00); |
Wenn du dir kein Buch anschaffen möchtest, kannst du dir auch eines in der nächsten Bibliothek ausleihen. Oder zumindest ein Tutorial im Internet suchen und durcharbeiten. terminator schrieb: > kann somit nur mit den > Internetseiten arbeiten. Mithilfe dieser Seiten bekomm ich es aber > einfach nicht hin. Die Internetseiten mit ihren Beispielen sind nicht relevant. Die vermitteln dir höchstens ein paar Grundlagen. Wenn es darum geht, ein konkretes Programm für einen konkreten Controller zu schreiben, ist das Datenblatt zu genau diesem Controller die maßgebende Instanz. Dort musst du schauen, wie der CTC-Modus aktiviert wird.
So sollte es gehen, habe es auch getestet :-) Gruß JOY #include <avr/io.h> #include <avr/interrupt.h> //Zählvariable deklarieren volatile int i=0; ISR(TIMER0_COMP_vect) { //Bei jedem Overflow Zählvariable um eins erhöhen i++; //Nach 10.000 Overflows PINs auf high setzen entsprich einer sekunde if(i == 10000) { PORTD = 0b01100000; } //10.000 overflows später PINs auf low setzen entspricht einer sekunde if(i == 20000) { PORTD = 0b00000000; //Zählvariable auf null setzen damit das ganze von vorn beginnt i=0; } } int main() { //Datenrichtung definieren DDRD = 0b01100000; //Timer 0 initialisieren TCCR0 = (1<<CS01)|(1<<WGM01); //Interrupts aktivieren TIMSK |= (1<<OCIE0); //Überlaufwert bei 100 OCR0 = 100; //Globale Interrupts aktivieren sei(); while(1) { //hier könnte ihr programm stehen!!! } }
Hey JOY, Ein großes DANKESCHÖN an dich. Der Code funktioniert wunderbar. Ich seh auch schon was falsch war. Da Schiko geschrieben hat das es den Compareinterrupt nur beim 16bit timer gibt hab ich den CTC-Modus beim timer1 programmiert. Der geht aber auch. Aber trotzdem bin ich jetzt froh das es auch beim timer 0 geht. Nochmals vielen Dank für die Hilfe.
Hallo Gast(terminator), ich habe noch eine Frage, warum lässt Du den
1 | OCR0 = 100; |
bis 101 zählen ?
Hi Uwe, wird zu dem eingegebenen Wert immer noch 1 dazu gezählt? Ich hab mich nämlich schon gewundert warum bei vielen Beispiel Codes im Internet z.b OCR0 = 125-1 steht. Ich schätze jetzt weis ich warum. Aber wieso heißt 100 eingentlich 101. Naja wenn mans weis kann man es ja berücksichtigen und immer -1 dahinter schreiben. Auf jeden Fall danke für den Hinweis.
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.