www.mikrocontroller.net

Forum: Mikrocontroller und Elektronik Tiny2313: Timer0 - Seltsames Interruptproblem

Important announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: Michael H. (overthere)
Datum: 04.07.2009 10:51

Hallo zusammen,

ich habe einen Servocontroller 8-Servo Servokontroller aufgebaut und bin
zur Zeit noch in der Entwicklungsphase.
Ein großes Problem macht mir Timer0 mit dem A-Interrupt: Die Bedingung
vom B-Interrupt gesetzt. Das komische dabei ist, dass wenn ich als
Compare-Match-Wert für den B-Interrupt OCR0A=138 verwende geht es,
drunter nicht mehr.
Wie kann ich das ohne Workaround fixen? Was mache ich falsch?

Die ganzen Sources findet ihr hier:
http://umfragen-service.de/avr/

Grüße und Danke

Michael
Autor: Michael H. (overthere)
Datum: 04.07.2009 11:11

Nachtrag: Irgendwie scheinen sich die Compare-Matches zu bekriegen: Das
Compare-Match, das größer ist, "gewinnt", bei dem anderen wird die Zeit
nicht eingehalten...
Hoffe, ihr könnt mir helfen...
Autor: Jörg G. (joergderxte)
Datum: 04.07.2009 12:21

Kannst du mal in Worten beschreiben, was die Timer-interrupts tun
(sollen)?
Autor: Michael H. (overthere)
Datum: 04.07.2009 12:54

Kurze Ablaufbeschreibung:
Nach der Inizialiserung (servo_init()), soll das erste Interrupt
(COMPARE MATCH A) denn PORTB auf high setzen und COMPARE MATCH B
inizialiseren.
COMPARE MATCH B soll genau nach 1ms aktiv sein. Die Interrupts werden
nun deaktiviert. Jetzt soll der Treiber immer warten, bis er an ein
gewisser Wert erreicht ist und dann die Servodaten ausgeben. Nun wird
der Timer0 wieder gesetzt, dass er in 20ms mit COMPARE MATCH A weiter
gemacht - so jedenfalls meine theoretischen Überlegungen.
Aber irgendwie wird der entweder COMPARE MATCH A oder COMPARE MATCH B
übersprungen. Wie kann ich das richten?
Autor: Peter Dannegger (peda)
Datum: 04.07.2009 13:26

ISR(TIMER0_COMPB_vect){
...
  do{
    // Warte ab, bis das es (das Flag) high ist
    loop_until_bit_is_set(TIFR,OCF0B);


Das ist Schwachfug. Du kannst nicht in einem Interrupt warten, bis er
wieder zuschlägt. Damit hast du genau 0 Zyklen für andere Interrupts und
das Main übrig.
Generell ist es dumm, in einem Interrupt überhaupt zu warten.


Schmeiß mal das ganze Gedöns mit der Timermanipulation aus den
Interrupts raus, da sieht doch keiner mehr durch und außerdem ist es
Unsinn.

Die Compareinterrupts sind doch genau dazu da, Dir den ganzen
Timingablauf abzunehmen.
Den T0 laß einfach durchlaufen und wenn etwas passieren soll, setzt Du
den OCR0A auf T0 + Startzeit, und OCR0B auf T0 + Endezeit. Dann beide
Pending flags löschen, beide Interrupts freigeben und fertsch.

Und die beiden Interrupts machen dann nur das zu den beiden Zeiten
gewünschte.
Wenn sie single-shot sein sollen, löschen sie noch ihre eigene
Interruptfreigabe. Aber mehr machen sie nicht mit den Timern rum.


Peter
Autor: Falk Brunner (falk)
Datum: 04.07.2009 13:43

Siehe Interrupt

Antwort schreiben

Die Angabe einer Email-Adresse ist freiwillig. Wenn Sie automatisch per Email ü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

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel




Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichungen und Screenshots im PNG- oder GIF-Format hochladen.
Siehe Bildformate

Hinweis: der Originalbeitrag ist mehr als 6 Monate alt.
Mit dem Abschicken erkennst du die Nutzungsbedingungen an.

webmaster@mikrocontroller.netImpressumNutzungsbedingungenWerbung auf Mikrocontroller.net