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!
>was Mnemonic ist, versteh ich jeden befehl außer BRNE branch if not equal Mnemonics sind die schnuckeligen Abkürzungen für die Befehle. >glaub ich nicht, dass die kleine lib sowas hat. Schau hier mal nach, das hast du offenbar geflissentlich übersehen: Literatur in http://www.mikrocontroller.net/articles/AVR-Tutorial:_Equipment Zahlensysteme in http://www.mikrocontroller.net/articles/AVR-Tutorial:_IO-Grundlagen Und fang vorne an, nicht beim LC-Display: Ausgabe in http://www.mikrocontroller.net/articles/AVR-Tutorial:_IO-Grundlagen
>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....
Schau mal hier: http://www.atmel.com/dyn/resources/prod_documents/doc0856.pdf --> AVR Instruction Set: beschreibt alle Befehle und dort: http://www.home.unix-ag.org/tjabo/avr/AVRdelayloop.html -->Warteschleifengenerator, nutzbar unter Windows
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. :-)
Abdou Zahim schrieb: > ; ============================= > ; Warteschleifen-Generator > ; 20000 Zyklen: > ; ----------------------------- > ; warte 19998 Zyklen: > ldi , $21 > WGLOOP0: ldi , $C9 > WGLOOP1: dec > brne WGLOOP1 > dec > brne WGLOOP0 ich meinte, wir kommt man an die 2 Zahlen $21 und $C9
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.