Hi, ich bin gerade dabei mich mit den Timer/Counter Funktionen des ATmega8 zu beschäftigen. Mein Ziel war es, ein 1 Sekundentakt zu erzeugen. Dies ist mir nun auch nach langem Kopfzerbrechen gelungen. Allerdings ist da noch etwas unklar. Nachdem der Interrupt aufgerufen wurde, wird TCNT1 nicht automatisch resettet, sondern zählt fröhlich weiter nach oben. Ist dies normal? Wäre doch dumm, wenn man TCNT1 nach jedem auftreten des Interrupts auf 0 setzen muss. Es funktioniert zwar dann, aber würde mir das nich um 3 Takte die Sekunde verfälschen?: ldi temp, 0xFF out TCNT1H, temp out TCNT1L, temp Oder ist es ein Bug im AVRStudio? Den Code hab ich mal mit angehangen. Gruß Daniel
also ich kenne assembler nicht aber bei c macht man es so , das wenn der interrupt aufgerufen wird man den tcnt1 auf null setzt wenn es erwünscht ist und soweit ich weis verfälscht das deine zählung auch nicht
Nutze statt dem TimerOverFlow den TimerCompare CTC (Mode 4), der resetet den Timer automatisch nach dem Erreichen des Wertes in OCR1A. Das Register musst Du nur einmal setzen und dann nie wieder (Beim Reset endet diese Welt...). Denke daran das Du dann einen anderen Vektor für den Interrupt nutzen musst. MooseC
hey, danke für die schnellen Antworten. Aber Moment mal! :) Ich nutze doch den compare mode, oder nicht? mit ldi temp, 1<<OCIE1B out TIMSK, temp Habe ich doch das richtige Bit gesetzt. Das Datenblatt sagt: Bit 3 OCIE1B: Timer/Counter1, Output Compare B Match Interrupt Enable Was ist also der Fehler? :(
Immer mit der Ruhe! Ich hatte gar nicht in Deinen Code geschaut, da ich annahm Du verwendest den normalen Timerinterrupt und Mode. Bei den erwähnten zusätzlichen Takten lag das nahe. Der CTC verwendet meines Wissens nur den OCR1A (oder ICR1 im MODE 12) als Limit für den Zählwert, Du verwendet aber OCR1B. MooseC
Du mußt TimerCompare CTC aktivieren (siehe Datenblatt PDF) und Deine ISR über den Timer Overflow laufen lassen statt Output Compare B Match Interrupt ansonsten werden Pins für PWM geschaltet (high/low-Wechsel). Gruß Andi
Ach ja, CTC heißt übrigens "Clear Timer on Compare" wodurch der Timer auf 0 gesetzt wird und ein Overflow entsteht was wiederum den Timer Overflow Interrupt auslöst. Gruß Andi
Das stimmt nicht ganz, denn der Overflowinterrupt TOV1 wird als 17te Bit beim Überlauf des 16 Bit Countregister gesetzt und löst so einen Interrupt aus. Für den CTC gibt es den OCF1A, der natürlich auch seinen eigenen Vektor hat, Der CTC hat keinen Überlauf auf das 17te Bit MooseC
Hi, tut mir leid, aber jetzt bin ich noch mehr durcheinander. Soviel Register wie es da gibt :( Also ich hab den Code jetz mal geändert. Es funktioniert aber leider immernoch nicht. Könnte vielleicht einer von euch, den Code grad so ändern, das es richtig ist? Ich denke viel kann da ja jetzt nicht mehr falsch sein :( Danke! Daniel
Alles wichtige wurde bereits gesagt, verstehen und umsetzen mußt Du es schon selber. Das Teil viele Register, ja, und nur Du kannst es für Dich entdecken.. Fertiger Code nützt Dir da garnichts MooseC
Hallo Daniel, "ldi temp, 1<<CS11|1<<CS10|1<<WGM13" Du mußt das WGM12-Bit setzen, nicht das WGM13-Bit. Siehe Datasheet.
Hallo! Ich habe hier den Compare-Match Mode gewählt(ATMEGA8535 mit 8Mhz Takt). Leider läuft der Timer1 noch zu schnell. Was könnte ich da falsch gemacht haben? TCCR1A=0x00; TCCR1B=0x0B; TCNT1H=0x00; TCNT1L=0x00; ICR1H=0x00; ICR1L=0x00; OCR1AH=0x04; OCR1AL=0xE2; OCR1BH=0x00; OCR1BL=0x00; TIMSK=0x10; // Timer 1 output compare A interrupt service routine interrupt [TIM1_COMPA] void timer1_compa_isr(void) { PORTB = ~PORTB; if (zehntelsek < 9) ++zehntelsek; else { zehntelsek = 0; if (sekunden < 59) ++sekunden; else { sekunden = 0; if (minuten < 59) ++minuten; else { minuten = 0; if (stunden < 23) ++stunden; else { stunden = 0; } } } } }
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.