www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Atmega8 ASM-Unterprogramm funktioniert nur bei Simulation


Autor: Paul H. (plan)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Guten Tag

Dieses kleine Programm sollte eigentlich die LEDs an PortD 0 und 1 
jeweils beim Betätigen eines Tasters 0 oder 1 an PortB an- und 
umschalten und beim Betätigen eines dritten Tasters an PortB 2 
ausschalten.

Die Simulation im AVR-Studio funktioniert wie ich es mir vorstelle, der 
µC reagiert aber anders.
Beim Anschalten sind beide LEDs schwach an und beim Drücken eines 
Tasters leuchtet die jeweilige LED heller und beim Drücken des Tasters 2 
passiert nichts.

Ich wäre dankbar, wenn mir jemand die Fehler in meinem Programm erklären 
könnte und einen passenden Code schreiben könnte.

Lg Paul

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Ich wäre dankbar, wenn mir jemand die Fehler in meinem Programm erklären
>könnte und einen passenden Code schreiben könnte.

Da fehlt die Stackinitialisierung.

MfG Spess

Autor: Vivil (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was sollte man nach einem rcall machen?

Dieses wäre deine richtige Frage gewesen.

Ist Dir die Antwort bekannt?

Autor: Vivil (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und was soll das?
led1:
  sbi portd, 0
  cbi portd, 1
  rcall taster1

  taster1: 
      sbic pinb, 1

Mein Tipp Kommentiere jeden Befehl mit deinem Gedankengang und Du wirst 
merken das du das zusammengestückelt hast. So wird das nix.

Autor: Toni (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bin ich leseschwach oder suche ich vergebens nach "RET"?

Am Ende eines Unterprogramms nötiger Befehl.

Autor: Paul H. (plan)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Danke für die Antworten und Fragen.

Ich habe mein Programm kommentiert und hoffe, dass Ihr es nachvollziehen 
könnt.
Mir ist jetzt auch das Problem mit dem Stack aufgefallen, nur weiß ich 
nicht wie ich den sichern soll, ohne das er abläuft.

LG Paul

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Mir ist jetzt auch das Problem mit dem Stack aufgefallen, nur weiß ich
>nicht wie ich den sichern soll, ohne das er abläuft.

Nicht Sichern, sondern Initialisieren .

MfG Spess

Autor: Toni (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schau dir mal die Reihenfolge beim Push und POP an!

Richtig wäre z.B.

push zl
push zh; Speichere auf Stack

pop zh
pop zl; Vom Stack zurückholen.

Stelle Dir den Stack vor als einen Stapel auf dem
Du ein Blatt Papier nach dem anderen ablegst.
Welches liegt dann immer oben?
Richtig das zuletzt hingelegte!

Autor: Vivil (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du hast nicht jede zeile Kommentiert sonst würde dir mehr auffallen.

Mensch Maier wir sollen Dir helfen. So mach auch das was Dir gesagt 
wird.

Hättest Du jeden Befehl kommentiert würdest du ein der schwachsinnigen 
aktionen wie

led1:
  sbi portd, 0
  cbi portd, 1
  rcall taster1

  taster1:
      sbic pinb, 1




sehen

Autor: Vivil (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Toni schrieb:
> Bin ich leseschwach oder suche ich vergebens nach "RET"?
>
> Am Ende eines Unterprogramms nötiger Befehl.

Net nachbabeln. Auch das Push würde Ihn nicht helfen. Genau so wenig 
eine Stackinitialisierung die aber sein muss.

Er hat nicht verstanden was er hier macht. Und das verständniss sollte 
erst mal da sein. Auch wenn er die Stackinitialisierung macht haut es 
ihm sein PROGRAMM auseinander. wegen einem StackOverFlow

Autor: oldmax (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi
Also, dein Stack ist ja initialisiert. Nun wird bei jedem RCAll die 
Rücksprungadresse dort eingetragen und bei einem Ret wieder weggenommen.
Was dein Assemblerprogramm betrifft...... tja, da ist noch ein weiter 
Weg.
Zuerst, ja, die Initialisierung gehört vor die Programmschleife. Aber 
was um himmelswillen haben Push und POP in der Schleife zu suchen ? Wer 
hat dir denn sowas gezeigt ?
Zum anderen , es ist nicht grad geschickt, die Abfage der Taster in 
Unterprogramme zu packen, die du aufgrund der Tasterbetätigung aufrufst. 
Und wenn du die Taster nach GND schaltest, ist die Bedingung für den 
Aufruf immer da, solange du die Taster nicht drückst, weil die 
zugeschalteten Pull-Ups natürlich "1"-Signal auflegen.
Mein Vorschlag:
Lies zuerst die Eingänge in einer kleinen Sub-Routine in eine Variable.
Read_IO:
    In    Reg_A, PIn(x)      ; Irgendeinen Port lesen 
    LDI   Reg_B, 0b11111111  ; Bits invertieren, da Abfrage nach GND
    EOR   Reg_A, Reg_B       ; damit ist ein gedrückter Schalter auch "1"
    ANDI  Reg_A, 0b00001111  ; ungültige Bits ausmaskieren
    STS   New_In, Reg_A      ; Bspw. die Portbits 0-3 sind Eingänge
RET
Nun hast du einen ganzen Zyklus Zeit, mit diesen Informationen zu 
arbeiten. Es können ja nur die Bits 0-3 gesetzt sein, ja nachdem, welche 
Schalter dedrückt sind. Entsprechend bearbeitest du eine Variable auf, 
die für die Ausgabebits steht.
Loop:
   RCALL Read_IO             ; Einlesen der Eingänge
   LDS   Reg_A, New_I
   ANDI  Reg_A, 0b00000001   ; ist Portbit 0 beschaltet ?
   BREQ  Next_Bit1           ; Wenn nicht nächsten Eingang prüfen
   RCall Action_eins         ; Reaktion auf Eingang 0
                             ; Ausgang schreib in Variable z.B. Out_Port
Next_Bit1:
   ....                      ; weitere Bearbeitung
   RCALL Write_IO            ; hier schreibst du die Bits aus Port_Out in
                             ; den Ausgabeport
   RJMP Loop
 Das ist die klassische "EVA" Methode: Einlesen, Verarbeiten, Ausgeben
Für die einzelnen Bearbeitungen rufst du Subroutinen auf.
Action_eins:
  ....
RET

Action_zwei:
  .....
RET
 usw.
Niemals das RET vergessen und, bevor ich es vergesse: du brauchst kein 
Push und POP. Erst, wenn du dich an Interrupt-Programme heranwagst, mußt 
du Registerwerte sichern. Es gibt zwar auch noch andere Verwendung 
dieser Befehle, aber da bist du noch weit von weg.
Gruß oldmax

Autor: Vivil (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@oldmax

Meinst du so lernt er was?
Selber hinter die Fehler kommen bringt was.

Und wenn er es nicht schafft seine Gedankengänge aufzuzeigen will er 
wohl auch nix lernen sondern sucht nur eine fertige lösung.

Autor: oldmax (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi
@Vivil
Nun, so ein wenig Anleitung zur Vorgehensweise schadet nicht. So krass 
wie du seine Fähigkeiten beurteilst, würd ich nicht vorgehen. Jeder hat 
seine ersten Schritte mal getan und bis zum perfekten Samba sind dann 
doch ein paar Jährchen vergangen... auch mit viel (liebevoller) 
Anleitung.
Also, gebt ihm eine Chance. Bisher hat er ja nicht gesagt: "Macht mir 
mal ein Programm....."
Gruß oldmax

Autor: Paul H. (plan)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank oldmax, das weiß ich zu schätzen.

Autor: Walter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Paul H. schrieb:
> Ich wäre dankbar, wenn mir jemand die Fehler in meinem Programm erklären
> könnte und einen passenden Code schreiben könnte.

oldmax schrieb:
> Bisher hat er ja nicht gesagt: "Macht mir
> mal ein Programm....."
> Gruß oldmax

Autor: *kopfkratz* (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Walter schrieb:
> Paul H. schrieb:
>
>> Ich wäre dankbar, wenn mir jemand die Fehler in meinem Programm erklären
>
>> könnte und einen passenden Code schreiben könnte.
>
>
>
> oldmax schrieb:
>
>> Bisher hat er ja nicht gesagt: "Macht mir
>
>> mal ein Programm....."
>
>> Gruß oldmax

Das alles erbsenzählerei...

Wenn man genau so viel Energie reinstecken würde, wie die negativen 
Bemerkungen, dann würden einige schneller und besser lernen.

Respekt @oldmax, weiter machen...

BR

Autor: Vivil (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hätte der TE mal seine Gedankengänge aufgezeigt und sich die ARBEIT 
gemacht diese zu Kommentieren so wäre ihm schon mehr geholfen als er es 
bräuchte.

Nur wer selbst nix machen möchte der sollte auch nix vor die Füsse 
geschmissen bekommen.Wie war das mit den Perlen?????

Sein Code zeigt klar auf das er nicht die Bohne wusste was er da tat. 
Dieses sollte sich ändern aber nicht damit das man es Ihm schreibt. 
Selbsterkentniss ist der einzige weg wie man lernen kann.

Nun eventuell bekommt er es hin seine Taster ab zu fragen aber gekonnt 
hat er nix da er vieles noch nicht verstanden hat. Und genau darum geht 
es das Verständniss schaffen.

Aber Ihr macht das schon grins

Autor: Paul H. (plan)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vivil ich verstehe ja, dass wenn man seine Fehler selbst korregiert mehr 
und besser lernt.
Das Problem ist aber, dass ich sie nicht sehe, da ich wenig Erfahrung 
hab.
So nun meine Fragen:
Wie kann ich den Stack-Over-Flow beheben ?
Mit einer Stack initialisierung ist es doch nicht getan oder ?
Und die Sequenz von oldmax
Read_IO:
    In    Reg_A, PIn(x)      ; Irgendeinen Port lesen 
    LDI   Reg_B, 0b11111111  ; Bits invertieren, da Abfrage nach GND
    EOR   Reg_A, Reg_B       ; damit ist ein gedrückter Schalter auch "1"
    ANDI  Reg_A, 0b00001111  ; ungültige Bits ausmaskieren
    STS   New_In, Reg_A      ; Bspw. die Portbits 0-3 sind Eingänge
RET

wenn ich das richtig verstanden hab, muss man den Wert am Pinx einlesen
mit einem EOR und 0xFF Filtern und den Rest der Bits löschen.

Da mein Programm so wunderbar ist.. **hust** könnt ihr mir sagen, wo ich 
die Grundlagen erlernen kann? links oder Buchvorschläge wären sehr gut.
Mit dem Tutorial auf dieser Seite komme ich nicht ganz zurecht.

LG Paul

Autor: Vivil (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich kann wieder nur schreiben. Kommentiere jeden deiner Befehle in 
deinem Code und schon wirst du es bemerken und etwas lernen.

Beitrag #2117988 wurde vom Autor gelöscht.
Autor: Steffen H. (avrsteffen)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Paul

Ich finde das Tutorial echt super hier. Angefangen zu programmieren hab
ich ebenfalls in Assembler. Das ist für eine Simulation viel besser als
"C". (Meine Meinung)

Ich hatte damals das Buch "AVR-RISK Mikrocontroller" vom Franzis Verlag.
Die darin verwendeten Controller sind zwar veraltet, aber dafür ist die
Hardware super beschrieben und auch viele Programm Beispiele mit
Erklärung dabei.

Grüße Steffen

Autor: Steffen H. (avrsteffen)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hab dir mal eine Seite wo der Stack erklärt ist rausgesucht. Ich hoffe 
man kann es lesen..

Autor: Paul H. (plan)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank Steffen ;)

Autor: Lordi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Moin hast du dir das schon durchgelesen ?

http://www.mikrocontroller.net/articles/AVR-Tutorial:_Stack

Gruß

Lordi

Autor: oldmax (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi
Nun, die Tutorials hier sind auch für mich sehr hilfreich gewesen und 
haben mir den Einstieg in die µC Welt erleichtert. Allerdings muß ich 
gestehen, das ich bereits in den 80ern mit Assembler und Z80 erste 
Begegnungen hatte. Ok, genug Geschichte. Schau mal bei den Kollegen von 
AVR-Praxis rein. Die haben einen Artikel zu "Keine Angst vor Assembler" 
unter FAQ's. Vielleicht hilft er dir etwas weiter. Wie andere und auch 
ich bereits erwähnten, ist die Kommentierung von Programmen hilfreich. 
Wenn du deine Gedanken, wie der Schritt arbeiten soll, aufschreibst, 
wird dir manchmal schon bei der Programmierung klar, das es so nicht 
funktionieren kann.
Zu meinen Erklärungen, Portbits einzulesen.
Du musst wissen, wir alle sitzen zig Kilometer von dir und deinen 
Gedanken weit weg. Immer mitzuschreiben, welche Portbits du einliest ist 
müßig, daher schreib ich einfach PortX. Welcher Port das sein soll, 
keine Ahnung, aber du weißt es und brauchst also nur den Buchstaben 
dafür einzusetzen. Nun zu den Bits.
Wenn du über In einen Port einliest, hast du immer die 8 Byte, also auch 
bits, die dich nicht interessieren. Wenn du aber deine Eingänge nach 
"0", also GND beschaltest, ist der Eingang immer wenn er nicht gedrückt 
ist "1" durch den internen Pull-Up Widerstand. Wenn du also ein 
Bitmuster 01011000 liest, ist der Schalter Bit 5 und Bit 7 
möglicherweise betätigt. Die Bits 0-2 sind keine Eingänge, erscheinen 
aber wie gedrückte Schalter. Also mußt du alles, was nicht von Interese 
ist ert einmal ausblenden. Da aber "0"en zu Denkfehlern führen, drehe 
ich erst mal die Bits mit einer EOR Anweisung. Danach sind die Bits mit 
den betätigten Eingängen "1". Nun wird über eine Und-Anweisung noch 
ausgeblendet, was nicht zu den Eingängen gehört. Geht sicherlich auch 
anders, aber an dieser Stelle habe ich nun die Möglichkeit, eine Flanke 
von einem Signal zu erfassen. Wie auch immer, jeder hat so seine 
Vorlieben, was den Programmierstil betrifft. Die Autoren von Büchern 
schreiben so oft Liebesromane, aber alle unterschiedlich, obwohl am Ende 
Adam seine Eva kriegt....
Gruß oldmax

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.