Forum: Mikrocontroller und Digitale Elektronik frage zum branching


von olli (Gast)


Lesenswert?

Mir ist leider kein besserer Betreff eingefallen:

Habe gerade starke Probleme beim debuggen eines Programms und vermute
nun den Fehler im folgenden Code

mov temp, signal
and temp, loopMic
cpi temp, 1
brsh sendTime

im Register signal steht sowas wie 00010010 (beispielsweise)
und loopMic shifte ich von rechts nach links durch also sagen wir mal
steht da zu Anfang 00000001 drin.

Die einzelnen Bits stellen die einelnen Kanäle dar. Ich will also durch
alle Kanäle durchshiften und falls ein Signal auf dem ausgewählten Kanal
vorliegt etwas ausgeben.

Es müsste doch also in Temp irgendetwas drin stehen was größer oder
gleich 1 ist wenn ich ein Signal auf betreffenden Kanal vorliegen habe
und gerade mit loopMic bei diesem Kanal bin.

Meine Frage also ist ob der Codeschnipsel soweit das tut was ich will.
Habe meine kleinen Probleme mit den Flags...

MfG.Olli

von Christof Krüger (Gast)


Lesenswert?

cpi temp, 1
brsh sendTime

kannst du ersetzen durch

brne sendTime

Wenn beim AND etwas ungleich 0 herauskommt, wird das Z-Flag gelöscht
und dementsprechend wird ge-branch-t, wenn am Kanal eine 1 anlag.

Funktioniert dein Schnippsel nicht? Oder möchtest du es erstmal nur
analysiert haben und hast es noch nicht ausprobiert?

von olli (Gast)


Lesenswert?

Danke für den Hinweis, ein bißchen Code gespart. Aber der Code war doch
richtig soweit, oder? Muss wohl woanders der Fehler liegen


> Funktioniert dein Schnippsel nicht? Oder möchtest du es erstmal nur
> analysiert haben und hast es noch nicht ausprobiert?

Ne der Code ist schon implementiert. Nur leider tut das Programm nicht
ganz was ich will. Um genauer zu sein der AVR resettet sich einfach mal
von Zeit zu Zeit und ich weiß nicht wieso. Da er sich aber resettet
vermute ich den Fehler irgendwo in der Sprunglogik.

von Christof Krüger (Gast)


Lesenswert?

Bist du sicher, dass deine Spannungsversorgung stimmt?
Hast du das Programm schon mal im AVRStudio simuliert? Da kannst du ja
Register zu jedem Zeitpunkt beliebig setzen und schauen, wie das
Programm reagiert.

Warum liest du nich mal die entsprechenden Register aus, um
herauszufinden, warum ein Reset stattgefunden hat?

von olli (Gast)


Lesenswert?

Arbeite mit Linux kann also daher leider nicht AVR Studio nutzen.

Wie kann ich das genau machen...?

Ich hab jetzt sowas hier stehen:

ldi temp, 48   ; Die Ziffer 0 in Ascii Code
in output, MCUSR
add output, temp
rcall send

die Unterroutine send schickt das ganze dann über den seriellen Port an
den Rechner.

Jetzt schmeisst der Mir die ganze Zeit ne 3 vor die Füsse.


Ich vermute ja das ich irgendwas mit dem Stack verkehrtmach, aber die 3
heisst doch dann Power-On Reset und Brown Out? 2 Resets auf einmal?

von Christof Krüger (Gast)


Lesenswert?

Du musst nach dem Abfragen des MCUCSR das Register löschen, das macht er
AFAIK nicht von alleine. Das sieht also danach aus, als würdest du einen
Brownout bekommen.

von olli (Gast)


Lesenswert?

Habe den Fehler jetzt gefunden (naja, fast wenigstens).

Und zwar habe ich wohl irgendwie (deswegen nur fast) mit Interrupts
einen Stack Overflow ausgelöst, der mir dann irgendwelche Variablen
überschrieben hat, so das ich in eine Routine gesprungen bin die mit
dem Stack arbeitet. Etwas komisch die ganze Sache...

Hab also in der kritischen Prozedur explizit Interrupts ausgemacht
(cli) und später wieder eingeschaltet (sei). Jetzt funktioniert die
ganze Sache.

Scheint mir eher ein Workarround zu sein aber besser als garnichts...

von thkais (Gast)


Lesenswert?

Öhm - Den Stack hast Du aber zu Programmbeginn definiert, oder?
Die Register SPL/SPH sind nämlich nach einem Reset nicht richtig
definiert, üblicherweise legt man den Stack an das Ende des RAM.
Das ist wichtig, wenn man RCALL und Interrupts verwenden will, denn die
Rücksprungadressen werden auf dem Stack gesichert.
Natürlich kann es dann noch sein, daß Du Register doppelt nutzt - d.h.
im Hauptprogramm und im Interrrupt. Da man nicht immer voraussehen
kann, wann ein Interrupt ausgelöst wird, werden dann u.U. Werte des
Hauptprogramms geändert. In diesem Fall werden die entsprechenden
Register in der Interruptroutine mit PUSH / POP gesichert und
wiederhergestellt.

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.