Hallo,
ich stecke gerade im AVR Assembler Tutorial fest.
ich werde mit folgendem Unterprogramm konfrontiert:
delay5ms:
ldi temp1, $21
WGLOOP0: ldi temp2 $C9
WGLOOP1: dec temp2
brne WGLOOP1
dec temp1
brne WGLOOP0
ret
Da versteh ich leider nur Bahnhof. Zunächst mal: Dieses: $21 und $C9:
Ich nehm mal an, dass das der ASCII Code ist und für eine Zahl steht.
Wo kann ich nachschauen, für welche Zahl das im Binärsystem steht?
dann kenn ich nur loop. was ist der unterschied zw. loop und wgloop?
Wo schau ich allgemein am besten nach, für was der Befehl steht, wenn
ich ihn nun vergessen hab oder er mir noch nicht untergekommen ist?
Haribo wrote:
> Hallo,>> ich stecke gerade im AVR Assembler Tutorial fest.> ich werde mit folgendem Unterprogramm konfrontiert:>> delay5ms:> ldi temp1, $21> WGLOOP0: ldi temp2 $C9> WGLOOP1: dec temp2> brne WGLOOP1> dec temp1> brne WGLOOP0> ret>>> Da versteh ich leider nur Bahnhof. Zunächst mal: Dieses: $21 und $C9:> Ich nehm mal an, dass das der ASCII Code ist und für eine Zahl steht.
Nein, das "$"-Zeichen ist eine Einleitung für ein konstanten
Hexadezimalwert. $21 ist dez. 33. Es wird also der Wert 33 in die
Speicherzelle geschrieben, die durch temp1 adressiert wird.
> Wo kann ich nachschauen, für welche Zahl das im Binärsystem steht?
MSWindows hat einen schönes Tool namens "Rechner" dabei. Einmal in den
wissenschaftlichen Modus geschaltet, kann es auch zwischen verschiedenen
Zahlensystemen umrechnen.
> dann kenn ich nur loop. was ist der unterschied zw. loop und wgloop?
Das sind Namen für Sprungziel. "WGLOOP0:" definiert ein Sprungziel mit
"brne WGLOOP0" springt man es konditionell an.
>$21 und $C9
sind Hexadezimal-Zahlen (in C wäre das so geschrieben 0x21 und 0xc9)
21 hex = 33 dez
C9 hex = 201 dez
>für welche Zahl das im Binärsystem steht...
es gibt ein Windows-Programm, das heißt calc.
Umschalten auf wissenschaftliche Ansicht,
Hex auswählen, C 9 eingeben, Dez auswählen, fertig
>wgloop
könnte genauso z.B. wenndudasgetanhastdannspringdorthin oder x heissen.
Das ist nur ein Name für eine Sprungmarke. Wie z.B. auch delay5ms.
Ein Tip:
nimm dir ein Buch über AVR-Assembler und Zahlensysteme und blätter das
mal durch. Also, bis Freitag dann... ;-)
EDIT: Scheibe, Zweiter...
Okay, danke soweit!
ich hätte dann:
delay5ms:
ldi temp1, 0b00100001
WGLOOP0: ldi temp2, 0b11001001
WGLOOP1: dec temp2; temp2 ist nun 0b11001000
brne WGLOOP1
dec temp1
brne WGLOOP0
ret
ich versteh leider echt nicht, wieso das Display nun 5ms stillgelegt
sein soll :-(
Ich verstehe allerdings nicht, warum man gerade bei Zählschleifen
Hexadezimalwerte benutzen muss. Der Assembler versteht auch Dezimal...
Gerade bei Zählschleifen ist es doch sinnvoll, wenn man auf einen Blick
erkennen kann, wie viele Durchläufe gemacht werden sollen.
Die unterschiedlichen XXloops kommen daher, dass das mehrere ineinander
verschachtelte Zählschleifen sind.
Haribo wrote:
> ldi temp1, 0b00100001> WGLOOP0: ldi temp2, 0b11001001> WGLOOP1: dec temp2; temp2 ist nun 0b11001000
Uiuiui, die Binärschreibweise ist an der Stelle noch unbrauchbarer als
die hexadezimale. Nochmal: Es handelt sich um ineinander verschachtelte
Schleifen, die jeweils so und so oft durchlaufen werden. Da ist es
sinnvoller, direkt die Anzahl der Schleifendurchläufe hinzuschreiben,
und zwar in dem Zahlensystem, in dem Du auch im Kopf ohne Probleme
rechnen kannst. Die Binärschreibweise ist eigentlich nur dann sinnvoll,
wenn irgendwelche Bitmuster in Register geschrieben werden sollen.
> ich versteh leider echt nicht, wieso das Display nun 5ms stillgelegt> sein soll :-(
Was meinst Du mit "wieso"? Die Zählschleife beschäftigt den µC für eine
Weile, so dass er nichts anderes machen kann. Erst wenn die Zählschleife
abgearbeitet ist, kann der µC sich wieder mit dem Display beschäftigen.
Und derjenige, der den Code geschrieben hat, hat ausgerechnet, dass
diese Schleife bei einer bestimmten Taktfrequenz ungefähr 5 ms dauert.
Haribo wrote:
> delay5ms:> ldi temp1, 0b00100001> WGLOOP0: ldi temp2, 0b11001001> WGLOOP1: dec temp2; temp2 ist nun 0b11001000> brne WGLOOP1> dec temp1> brne WGLOOP0> ret> ich versteh leider echt nicht, wieso das Display nun 5ms stillgelegt> sein soll :-(
Du versteht offensichtlich die Bedeutungen der Mnemonic nicht. Nun, m.
E. würde es recht wenig Sinn machen, dir hier jede Einzelne zu erklären.
Am besten, du lädst dir eine AVR-Assembler Referenz runter und schaust
erstmal nach, was diese Befehle bedeuten. Das halte ich für deutlich
sinnvoller.
>wieso das Display nun 5ms stillgelegt sein soll...
Das kannst nur du wissen, ich kenne den Rest deines Codes nicht.
Hier wird nicht ein Display 5ms stillgelegt, sondern der Controller tut
für 5ms lang nichts als Schleifen abzählen. Von aussen sieht es aus, als
ob er wartet...
BTW: hast du das Buch schon?
>Du versteht offensichtlich die Bedeutungen der Mnemonic nicht. Nun, m.>E. würde es recht wenig Sinn machen, dir hier jede Einzelne zu erklären.>Am besten, du lädst dir eine AVR-Assembler Referenz runter und schaust>erstmal nach, was diese Befehle bedeuten. Das halte ich für deutlich>sinnvoller.
naja. davon abgesehen, dass ich nicht weiß, was Mnemonic ist, versteh
ich jeden befehl außer BRNE
>Hier wird nicht ein Display 5ms stillgelegt, sondern der Controller tut>für 5ms lang nichts als Schleifen abzählen. Von aussen sieht es aus, als>ob er wartet...
nun ist es trotzdem schon etwas klarer!
>BTW: hast du das Buch schon?
Hab leider kein Buch über Mikrocontroller/Assembler. Vielleicht sollt
ich mal in der Bibliothek schauen, aber irgendwie glaub ich nicht, dass
die kleine lib sowas hat.
Werd mirs nun nochmal anschauen
Haribo wrote:
> naja. davon abgesehen, dass ich nicht weiß, was Mnemonic ist, versteh> ich jeden befehl außer BRNE
Die Befehle heissen im Fachchinesisch "Mnemonic".
BRNE steht für "BRanch on Not Equal" also "Verzweige wenn nicht gleich".
Dieser Befehl wird eigentlich in Verbindung mit dem Vergleichsbefehl
"cmp" verwendet. Da dieser Befehl eigentlich nur das Zeroflag testet,
wird dieser Befehl das genannte sprungziel anspringen, solange das
Ergebnis der vorhergehende Opration (in diesem Fall dec) "nicht null"
war.
Hier nochmal der Hinweis auf die Referenz. Du wirst ohne nicht
weiterkommen!
>wird dieser Befehl das genannte sprungziel anspringen, solange das>Ergebnis der vorhergehende Opration (in diesem Fall dec) "nicht null">war.
achso. nun hats Klick gemacht. Ich dachte, dass der Befehl die zahl mit
irgendeiner vorausgegangenen zahl vergleichen muss, bis sie gleich sind.
Hab aber keine andre zahl gesehen^^, aber anscheinend muss er ja nur mit
0 vergleichen.
also macht der Code quasi 33 mal 200 Schleifen, die dann 5ms dauern?
Haribo wrote:
> also macht der Code quasi 33 mal 200 Schleifen, die dann 5ms dauern?
Ob das tatsächlich 5ms ergibt, hängt von den angelegten Taktung der MCU
ab, aber im Prinzip stimmts so....
hallo,
; =============================
; Warteschleifen-Generator
; 20000 Zyklen:
; -----------------------------
; warte 19998 Zyklen:
ldi , $21
WGLOOP0: ldi , $C9
WGLOOP1: dec
brne WGLOOP1
dec
brne WGLOOP0
ich versuche auch das Programm von Delay5ms zu verstehen:
ich habe alles möglich probiert und ich komme gar nicht an den zahl
20000.
zum Beispiel:$21*$C9= $19E9-------->6663dez
oder $21C9------>8649dez
wie krigt man 20000 zyklen
Abdou Zahim schrieb:> wie krigt man 20000 zyklen
Nicht nur das Runterzählen braucht Zeit, sondern auch die Prüfung des
Werts, der bedingte Sprung zurück, das Wertneuladen am Anfang der
inneren Schleife...
Das besste wärs, du programmierst das mal im AVR-Studio und schmeißt den
Simulator an, mit dem du die Zeit genau simulieren kannst. :-)