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


von Matthias Larisch (Gast)


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

von Benedikt (Gast)


Lesenswert?

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

von Alex (Gast)


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

von Matthias Larisch (Gast)


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

von Thomas Burkhardt (Gast)


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

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
Noch kein Account? Hier anmelden.