-
-
Erfahrener Benutzer
Roboter Experte
Mega16 stürzt manchmal ab
Wie es der Titel schon sagt, wenn ich zu viele Sachen gleichzeit ausführe stürt der µC einfach ab.
Über die RS232 kommt dann in etwa sowas (im Terminal sind es kleine Herze):
Code:
ìüÿÿÿ
ÿ2ÿÿÿ
8ÿ
ÿ=ÿÿ
Mein Programm ist mitlerweile schon etwas komplexer, ca. 10 Goto's, 2 Timer und ein Interrupt.
Wüsstet ihr wie ich solche Probleme beheben könnte?
Oder liegt es nur an der Software?
Der Mega16 ist über einen 16Mhz Quarz getaktet.
Sorry ist ne etwas dumme Frage, ich könnte den Code auch jetzt postet, aber der ist etwas unübersichtlich.
-
Erfahrener Benutzer
Roboter Genie
springst du evtl mit einem goto aus der ISR oder aus einer subroutine? dann läuft dein stack über, das würde abstürze erklären.
-
Erfahrener Benutzer
Roboter Experte
Ja das mache ich. Mist.
Wie könnte ich das umgehen?
kann man den Stack einfach erhöhen?
$swstack = 32
$hwstack = 40
-
Erfahrener Benutzer
Roboter Experte
Ich denke nicht, dass das was bringt. Denn dann tritt das Problem einfach ein klein wenig später auf, eine richtige Lösung ist es nicht.
-
Erfahrener Benutzer
Roboter Experte
Hm wiso später?
Ist der Stack irgentwann voll oder?
Ich werd mich gleich mal genauer über die Stacks informieren.
Schade das es nicht so geht.
-
Erfahrener Benutzer
Roboter Experte
Naja, der Stack ist eine komplexe Sache. Erstens kann es passieren, dass der Pointer überläuft, also nicht mehr auf die letzte RAM-Adresse sondern zeigt, sondern plötzlich auf 0x00. Danach läuft dein AVR Amok.
Ausserdem kann es bei unachtsamer Benutzung von Routienen und ungünstigen Variablenadressen passieren, dass der Stack eine Variable überschreibt, oder umgekehrt.
Wenn bu bei Interupts komplexere Sachen machen musst, ist es vielleicht ratsam, wenn du die Variable, die du aus der ISR benutzen willst, in ein FIFO ablegst, und eine Control-Varibale einführst, woraus dein Program später weiss, dass da noch eine Variable ist, die noch nicht verarbeitet worden ist. Hoffentlich ist das verständlich, damit kannst du es vermeiden, das unkontrolliert Routienen aufgerufen werden, die normalerweise hintereinander laufen sollten.
Ablauf einmal kurz erklärt:
1. AVR ist in Routine #1, und arbeitet
2. ISR tritt auf, speichert neue Variable, und setzt eine Control-Variable
3. Routine #1 endet
4. Zurück in die Hauptrutine, die anhand der Control Varibale (oder noch besser Control-FIFO) entscheidet, welche Routine jetzt aufgerufen werden soll, und übergibt die Varibale, die von der ISR gespeichert worden ist, an diese weiter
5. AVR arbeitet in Rutine #2
Damit hast du ein kleines OS, was die Aufgaben verteilt. Das kann man dann noch vertiefen, indem man Prioritäten usw einstellt.
MfG
pongi
-
Erfahrener Benutzer
Roboter Genie
in asm springt man einfach mit RETI (interrupt) oder RET (subroutine) zurück. dann läuft auch der stack nicht über. wie das in Bascom ist, weiß ich nicht.
-
Erfahrener Benutzer
Roboter Experte
Danke euch beiden.
Ich denke mal das es in Bascom auch ein Befehl gibt um den Stackpointer zurückzusetzen.
Bei mir ist es in etwas so:
1. Hauptprogramm Endlosschleife ruft Wait_and_get Fkt auf
2. Wait_and_get Fkt emfängt IR und geht in Sub Programm (GoTo).
3. Das Sub Programm wird Endlos ausgeführt uns ruft jedesmal die Wait_and_get auf, um zu prüfen ob ein neues Signal (IR) anliegt
Zusätzlicht läuft noch ein PWM Timer0 der per Interrupt RGB hochzählt
Und halt noch der RC5 Emfang mit Timer2
-
Erfahrener Benutzer
Roboter Experte
Verstehe ich das richtig? Du rufst immer wieder ein Subprogramm auf, das aber nie endet, weil Endlosschleife? Ist nicht besonders gut... Vielleicht liegst ja daran. Sowas kann den Stack ziemlich verwirren...
-
Erfahrener Benutzer
Roboter Genie
bei jedem sprung in eine ISR oder SUB wird die rücksprungadresse (also da, wo das proggi grade war, als gesprungen wurde) auf den stack gepushed. mit RET(I) wird dieser wert wieder vom stack geholt und zurückgesprungen. wird immer weiter gesprungen ohne rücksprung, werden immer neue werte auf den stack geschoben, aber nicht mehr abgeholt. das ergebnis ist, dass auf dem stack früher oder später kein platz mehr ist, und dadurch schlussendlich dein programm abkackt.
deshalb hinter jeden ISR-einsprung ein reti und hinter jedes rcall ein ret (so heissen die befehle in asm, aber das prinzip ist in basic sicher dasselbe).
denke das stimmt so, wenn ich mich irre, tut mich bitte korrigieren.
Berechtigungen
- Neue Themen erstellen: Nein
- Themen beantworten: Nein
- Anhänge hochladen: Nein
- Beiträge bearbeiten: Nein
-
Foren-Regeln
Lesezeichen