mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik frage zum branching


Autor: olli (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Christof Krüger (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: olli (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Christof Krüger (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: olli (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Christof Krüger (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: olli (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: thkais (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

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.