mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik AVR läuft instabil / Interrupts deaktivieren sich?


Autor: Matthias Larisch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi!
Ich programmiere gerade ein Spiel für den AT Mega 8(L). Dort habe ich
einmal nen unregelmäßigen Timer-Interrupt für die Hintergrundmusik
(Timer2, OCR wird immer auf den jeweiligen Wert für die Note gesetzt).
Ein weiterer, regelmäßiger Interrupt (Timer1, ca. 1-2 Sekunden) macht
etwas im Spielgeschehen. Als Eingabe benutze ich einen handelsüblichen
Joystick: Anschluss PortC 0 und 1 X und Y Achse mit jeweils 100k
Pulldown, Port C 2 und 3 die Buttons 1/2.
PortC 0 und 1 werte ich per ADC aus. Dazu gleich ne weitere Frage: Kann
ich trotz aktiviertem ADC ganz normal per in temp, PORTC den Port
einlesen (dann halt nicht die ADC Werte sondern in dem Fall für die
Buttons)? Damit hab ich auch noch Probleme, die sind allerdings erstmal
egal.
Zurück zum Hauptproblem: Das Programm läuft einige Zeit wunderbar.
Jedoch irgendwann gehts los: Es scheint sich der Vorteiler für den
Timer zu verstellen (Musik läuft langsamer). Dann plötzlich überspringt
er einfach mal einen Wert und macht nur noch scheisse (Ausgabe auf LED
Display spinnt total, Musik hat keine Ähnlichkeit mehr mit dem Soll),
ich speichere im EEPROM die Musik immer 1 byte note, nächstes Byte die
Notenlänge. Da wird er einfach mal exakt 1 oder 3 Bytes überspringen,
sodass er dann die Notenlänge als Notenwert hat und umgekehrt ;-). Und
ne kurze Zeit später, bzw. manchmal auch direkt, is dann ganz leise.
Beide Timerinterrupts scheinen deaktiviert oder die Timer gestoppt.
Jedoch kann ich die "Spielfigur" noch per Joystick links/rechts
bewegen, also ADC läuft noch, auch Ausgabe. Demnach hängt sich der AVR
also nicht richtig auf.
Hat jemand eine Ahnung, wieso das so ist? Sind allgemein Probleme mit
instabilitäten des AVRs bekannt? Das hier ist erst meine 2. Anwendung
(die erste war ne Lüftersteuerung per 4x Software PWM und serieller
Schnittstelle). Achso: programmieren tu ich in Assembler. Im Code ist
es UNMÖGLICH, dass irgendwie die interrupts deaktiviert werden und/oder
der Prescaler verstellt wird. das wird einmalig beim Reset getan und
diese Stelle wird nie wieder angesprungen.

Ich danke euch schonmal!

cu
Matze

Autor: Benedikt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hört sich nach einem Stack Overflow oder in den Interrupts
überschriebene Register, Bits usw. an.

Autor: Alex (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn zuviele Interrupts in zu kurzer Zeit kommen und dein ISR noch zu
langen Code beinhalten, kann das von dir beschriebene Verhalten
auftauchen. Kannst ja mal deinen Code für eine genauere Diagnose und
eventuell zum Tipps geben veröffentlichen, ansonsten bleibt es eh nur
beim Rumraten.

Gruß, Alex

Autor: Matthias Larisch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi!
Also das Problem lag tatsächlich am Code. Durch überlaufen bzw.
"unterlaufen" von Registern durch die Bewegung nach links (x < 0) und
rechts (x>255) aus der karte raus... ich kann mir zwar nicht erklären,
wieso das nicht funktioniert hat... werde mir das aber nochmal
anschaun. Dann hab ich auf die schnelle nen check eingebaut (spielfigur
nur in X Richtung verschiebbar, x=0 bis x=7 ist das spielfeld), der
einfach cpi stonex, 8 macht... dann letzte bewegung rückgängig. Das hat
nicht gereicht, trotzdem ging es meistens unter X=0 hinaus! Manchmal hat
man noch 1 Hälfte der Spielfigur gesehen (is 2 Pixel breit) manchmal
garnichts... bei nem zusatzcheck cpi stonex, 0 gabs ne pixelspalte frei
auf der linken Seite. Naja ich werd meinen Code mal ausführlich
durchschaun müssen. Macht auch so noch einige kuriositäten, die sich
aber sicher durch einfache Korrekturen ausbessern lassen. Im großen und
ganzen läuft er jetzt, ohne dass der reguläre Programmablauf gestört
wird ;-)

Alex: Die Timer Interupts können sich nicht direkt gegenseitig stören.
1 is zwar verdammt lang, aber die wird auch nur max. 2x pro Sekunde
aufgerufen. Die andere darf der auch ruhig zwischenfunken, denn die hat
komplett eigene Register. Und das SREG sichere ich gleich als erstes bei
beiden Interrupt Routinen ;-) (der Fehler hat mich auch schon 30 Minuten
gekostet vorn paar Tagen).

Was ich bisher so über den AVR sagen kann:
Trotz Assembler leicht zu programmieren,
trotz rel. komplexer Routinen (etliche Schleifen und alles zur
Spielregeleinhaltung) verdammt schnell (ich komme bisher auf ungefähr
500 gezeichnete Bilder pro Sekunde bei 4MHz, wobei er immer am Ende der
Mainloop zeichnet)
und es macht mir einfach Spaß ;-) Der AVR ist ein richtig toller µC.


Da fällt mir gleich noch was ein: Wie oft kann man die Fuses neu
beschreiben? Ich spiele ziemlich viel an den Clockfuses rum, nicht,
dass man das nur 100x kann und dann is aus...
Danke, dass ihr mir so superschnell geantwortet habt,
cu
Matze

Autor: Thomas Burkhardt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

wegen der Fuses...

Mmmh, AFAIK sind die Fuses in genau der selben Flash-Technologie
gespeichert, wie das Programm. Also würden die dort angegebenen Werte
gelten. Typisch zehntausend mal bei den neueren Modellen :)


Grüße

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.