mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Mega8: Timer 2 Interrupt-Problem??


Autor: Christoph S. (mixer) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich möchte mit dem Timer 2 vom Mega8 2 Interrupts auslösen, einmal bei 
Compare und einmal bei Overflow.
Habe Takt eingestellt und beide Interrupts freigegeben, das 
Compareregister mit dem entsprechenden Wert geladen!
Wenn jetzt der Compare-Interrupt auftritt, dann springt der Simulator 
nach dem "reti" auf den Overflow-Interrupt!?!
Habe ich da im Datenblatt was übersehen wie ich den genau initialisieren 
muss oder funktioniert das gar nicht, dass ich mit einem Timer 2 
Interrupts auslösen kann??

MFG Mixer

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bedenke, dass der Timer weiterläuft, wenn der Compare-Interrupthandler 
(die ISR dafür) am schuften ist!

Wenn dabei ein Overflow auftritt, ist der Interrupt dafür in 
Lauerstellung bis der aktuelle Compare-Interrupthandler fertig ist. Nach 
dem RETI des Compare-ISR wird der Overflow-Interrupthandler 
angesprungen... genau das Bild, das du beschreibst.

Abhlfe?

Hmm, überlegen, ob du wirklich die beiden Interrupts auf dem gleichen 
Timer haben willst.

Und ob du überhaupt beide Interrupts brauchst oder ob es einer, ggf. 
geschickter gewählter, auch tun würde.

Was willst du eigentlich machen?

Autor: Christoph S. (mixer) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Compare-Interrupt sollte eigentlich 1 ms nach dem Overflow kommen, 
und der Abstand von Overflow zu Overflow sollte ca. 20ms betragen.

Ich möchte damit eine Servosteuerung machen, und da der Impuls ja immer 
min. 1ms lang ist, hab ich mir gedacht, kann der AVR ja die 1ms mit nem 
Interrupt überbrücken und da ggf. was anderes machen!

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also du willst, alle 20ms die Möglichkeit haben, einen Puls an den Servo 
zu schicken und der Puls ist 1 ms lang.

Und du dachtest, dass du den Overflow-Interrupt als Zeitscheibe 
verwendest aber das Ende des Pulses über den Compare-Interrupt abpasst.

Dann würde ich den Compare-Interrupt nicht ständig erlauben. Nur wenn 
der Overflow-Interrupt ausgelöst hat und ein Puls an den Servo unterwegs 
ist. Die Einstellung sollte so sein, dass 1ms später als "jetzt" (d.h. 
Zustand im Overflow-ISR) der Compare-Interrupt kommen soll, Danach nur 
den Compare-Interrupt wieder disablen.

Und genereller Tip: Beide ISRs knapp halten.

Autor: Christoph S. (mixer) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das ist ja schön und gut, aber wenn nach 1ms der Compare-Interrupt 
ausgelöst wird und dann mit "reti" wieder beendet wird, dann springt er 
sofort auf den Overflow-Interrupt, obwohl er ja da nichts zu suchen 
hat!!

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
In Echt oder nur im Simulator?

Wenn du es in Echt noch nicht testen kannst, bring  Beispielcode bei. 
Ich lasse das dann auf einem Atmega8 laufen (heute abend).

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mixer S. wrote:
> Das ist ja schön und gut, aber wenn nach 1ms der Compare-Interrupt
> ausgelöst wird und dann mit "reti" wieder beendet wird, dann springt er
> sofort auf den Overflow-Interrupt, obwohl er ja da nichts zu suchen
> hat!!

Solche Antworten "liebe" ich. Null neue Information und das Gesagte von 
einem Ohr rein und zum anderen raus.

Autor: Christoph S. (mixer) Benutzerseite
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Sorry, war grad falsch, hier kommt die richtige:

Ist sowohl auf m Simulator als auch auf m AVR so, hab s mit m Oszi
betrachtet.

Der Code soll zuerst den Timer initialisieren und PB1 auf "high" setzen,
dann soll nach 1ms der Compare-Interrupt einspringen und je nach Wert
für den Servo eine bestimmte Zeit warten bis der PB1 auf "low" gesetzt
wird. 20ms nach dem Start soll dann der Timer Overflow den PB1 wieder
auf "low" setzen und das spiel geht von vorne los

Hab die Schleifen, Prescaler usw. für Simulation optimiert, damit das
immer nicht so lange dauert ansonnsten Originalcode!

Autor: Christoph S. (mixer) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry, da ist mir ein Fehler unterlaufen, jetzt ist aber der richtige 
Code da!

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mixer S. wrote:
> Das ist ja schön und gut, aber wenn nach 1ms der Compare-Interrupt
> ausgelöst wird und dann mit "reti" wieder beendet wird, dann springt er
> sofort auf den Overflow-Interrupt

Das ist unmöglich!
Er muß nach dem RETI immer einen Befehl der Mainloop ausführen.

Wenn der Compare-Interrupt zu lange dauert, kann durchaus ein Overflow 
erreicht werden.
Delays in Interrupts sind immer gefährlich.
Schau dochmal in den Simulator, wie das Overflowbit vor dem RETI steht.


Peter

Autor: Christoph S. (mixer) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Das ist unmöglich!

Das hab ich mir auch gedacht, darum hab ich ja auch diesen Thread 
gestartet!

Bei der Simulation wird das Bit für nen Overflow Interrupt nicht 
gesetzt, und der Timer ist auch noch weit weg von nem Overflow!

Kann des sein, dass des an der Initialisierung des Timers liegt?? Evtl. 
muss man da noch n bit setzen oder so, hab das Datenblatt nicht ganz 
überblickt!

Autor: Michael U. (amiga)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

mit welchem Wert wird delay initialisiert?
Warum vergleichst Du mit brlo und machst nicht den Abbruch bei gleich 
mit breq? brlo kann nette Effekte erzeugen, wenn man einen möglichen 
Überlauf durch 0 übersieht.

Due rettest weder SREG noch die benutzten Register in den ISR, spielt 
hier zwar vermutlich keine Rolle, sollte man sich aber generell 
angewöhnen, spart später viel Zeit bei der Fehlersuche.

Warum diese seltsame Springerei? Macht es schwer lesbar...
Ein Programm sollte möglichste in der Folge des Ablaufs geschrieben 
sein.

Gruß aus Berlin
Michael

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du darfst oben in der Vektortabelle kein rcall benutzen! Dort gehört 
ein rjmp hin. Am Rest bin ich noch am schauen.

Autor: Stefan B. (stefan) Benutzerseite
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
So hier meine Kommentare und Änderungen. Der Code macht jetzt das, was 
ich mir vorstelle, was du haben willst ;-)

Nicht verstanden habe ich allerdings die Sache mit dem delay und servo. 
Das habe ich grosszügig auskommentiert bzw. der Code wird nicht 
angesprungen. Da müsstest du nacharbeiten.

Jetzt passiert folgendes:

Bei 8 MHz Takt alle (ca.) 20 ms PB1 HIGH über den Overflow Interrupt von 
Timer2 und 1 ms später PB1 LOW über den Compare Match Interrupt von 
Timer2.

Die Vorladewerte für TCNT2 habe ich von dir übernommen (TCNT2 100 bzw. 
CTC 8 Timertakte später = 108). Dein Prescaler 8 kommt mir spanisch vor, 
daher habe ich den auf 1024 hochgesetzt. Mit 1024 sieht es für mich 
sinnvoll aus:

Vorladewert 100 ergibt 256-100 = 156 Timertakte bis Overflow. * 
Prescaler 1024 sind das 159744 Maschinentakte und bei 8 MHz sind das 
1/50,08 s d.h. ca. 20 ms.

Vorladewert 108 für das Vergleichsregister bei einem Vorladewert von 100 
für das Timerregister ergibt 108-100 = 8 Timertakte * Prescaler 1024 
sind das 8192 Maschinentakte und bei 8 MHz sind das 1/976,5625 s, d.h. 
1,024 ms

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mixer S. wrote:

> Der Code soll zuerst den Timer initialisieren und PB1 auf "high" setzen,
> dann soll nach 1ms der Compare-Interrupt einspringen und je nach Wert
> für den Servo eine bestimmte Zeit warten bis der PB1 auf "low" gesetzt
> wird. 20ms nach dem Start soll dann der Timer Overflow den PB1 wieder
> auf "low" setzen und das spiel geht von vorne los

Ups. Das habe ich mir ganz oben anders zusammengereimt. Also Kommando 
zurück, meine Änderungen am Code machen das nicht. Ich schaue mir das 
noch mal an.

Autor: Stefan B. (stefan) Benutzerseite
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
So hier die Änderung.

Autor: Christoph S. (mixer) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Danke für deine Mühe!! Das rcall war der Auslöser, dass danach der 
Overflow Interrupt kommt!!
Den Rest muss ich mir noch genau anschauen, aber rein vom überfliegen 
siehts gar net so schlecht aus!
MFG Mixer

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail ü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
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.