Irgendwo scheint ja etwas nicht klar zu sein!
Wenn ihr möchtet zeige ich euch mal einen fertigen Code und erkläre euch das, ok?
Oder wollt ihr es jetzt selber herausfuseln!? *lol*
Hallo ihr Beiden!
Ich bin mir bewusst, dass es ziemlich verwirrend ist!
Das glaube ich weniger! ;o)Sorry, aber wahrscheinlich bin ich echt zu doof dafür *g*
Ihr braucht euch erstmal nur mit dem Zählerregister Z, also ZL und ZH beschäftigen, die anderen Anwendungen werdet ihr später kennenlernen!
Empfehlungen zur Registerwahl
1. Register immer mit der .DEF-Anweisung festlegen, nie direkt verwenden.
2. Werden Pointer-Register für RAM u.a. benötigt, R26 bis R31 dafür reservieren.
3. 16-Bit-Zähler oder ähnliches realisiert man am besten in R24/R25.
4. Soll aus dem Programmspeicher gelesen werden, Z (R30/31) und R0 dafür reservieren. (WICHTIG!)
5. Werden oft konstante Werte oder Zugriffe auf einzelne Bits in einem Register verwendet, dann die Register R16 bis R23 dafür vorzugsweise reservieren.
6. Für alle anderen Anwendungsfälle vorzugsweise R1 bis R15 verwenden.Richtig!So wie ich das verstanden habe, ist der Programmspeicher WORD-weise organisiert. Also unter einer Addresse im Programmspeicher findet man 2 Byte.
Ich braucht euch da jetzt nicht große Angst machen, nehmt einfach mal zwei und fertig! ;o)
Also ladet ihr die Adresse der Daten so in das Z-Register:
Jetzt sollt ihr mit lpm die Daten dazu in r0 laden und das dann in r16 rüberschieben.Code:ldi ZL , LOW (datenlabel * 2) ; das kennt ihr ja schon mit Ramend! ldi ZH , HIGH (datenlabel * 2) ; wie oben
Danach sollt ihr das Z-Register um 1 erhöhen, um das nächste Byte zu bekommen, somit hätte sich die Frage mit den Word's und Byte's erledigt! ;o)
Das ist alles, was ich von euch sehen will! *lol*
Ich hoffe, ich war jetzt verständlicher! *g*
Irgendwo scheint ja etwas nicht klar zu sein!
Wenn ihr möchtet zeige ich euch mal einen fertigen Code und erkläre euch das, ok?
Oder wollt ihr es jetzt selber herausfuseln!? *lol*
Wir lesen noch ein klein bißchen!
Gibt uns eine Chance!
http://www.mikrocontroller.net/tutorial/memory
Selber herrausfinden bringt wohl mehr, aber ich komm da ja nun gar nicht klar. Hier mal mein Code:
Wie man sieht, sieht man nichts *g*Code:;Programm ;CDurTonleiter rauf und runter spielen .include "m8def.inc" .def tmp = r16 ;Mein Universallregister .org 0x000 rjmp reset ;Interruptvektor "reset:" reset: ;Stack einrichten ldi tmp, HIGH(RAMEND) ;HIGH-Byte der obersten RAM-Adresse out SPH, tmp ldi tmp, LOW(RAMEND) ;Low-Byte der obersten RAM-Adresse out SPL, tmp ldi ZH, HIGH(daten2 * 2) ldi ZL, LOW(daten2 * 2) lpm sei ;Interrupts zulassen loop: adiw ZL,1 lpm ST Z,tmp rjmp loop ;immer wieder zu "loop:" springen daten1: .dw 65535 , 0 ;zwei Words daten2: .db "Hallo!" ;immer eine gerade Anzahl an Bytes
Ich versteh das nicht mit dem Programmspeicher und dem Z-Register und dann muss ich das Z-Register um 1 erhöhen und wieder auslesen und und und...
Vor allem, wozu brauch ich unten zwei Labels mit daten?
Schummler! *lol*
Da steht mein beispiel ja fast Wort für Wort! *rofl* *@ Thomas -> schau da mal*
@ Thomas:
Stell Dir ein Buchregal vor!
Mit dem Z-Register gibst Du nun die Position des Buches an.
Danach ziehst Du das passende Buch mit dem Befehl lpm aus dem Regal und packst es in den Einkaufswagen r0.Code:ldi ZL , LOW (datenlabel * 2) ldi ZH , HIGH (datenlabel *2)
Da Du es aber nach dem bezahlen mit nach Hause nehmen möchtest musst Du es in einen Beutel packen, r16, da Du den Einkaufswagen nicht mitnehmen darfst/kannst bzw. willst -> für dieses beispiel!
Jetzt verstanden?
Wenn Du dann aber mehrere Bücher haben möchtest, musst Du mehrere Male einkaufen gehen.
Wenn Du vor dem regal stehst musst Du den Pointer für das Regal um eine Position (Byte) erhöhen, um das nächste Buch einzupacken!
Also mal in Stichworten:
- Datenpointer
- Schleife öffnen
- lpm
- r0 (lpm_reg) in r16 (temp) übertragen
- Datenzähler um 1 erhöhen
- Schleife wiederhohlen
Das wars!
Das ist eigentlich, wenn man es einmal verstanden hat, garnicht schwer!?
Ps:
Habs glatt überlesen! ;o)
Die beiden labels sind die Positionen für die daten, die Du auslesen willst, Dein Bücherregal!
Florian, kannst Du uns bitte das mit dieser 2 mal erklären.
Im Tutorial steht, dass.das unterste Bit gibt jeweils an, ob das untere oder obere Byte des Wortes im Programmspeicher geladen werden soll
Sagen wir mal unser speicher beginnt bei b0000 0000 0000 0000 an.
Also
b0000 0000 0000 0000: 0011 1100 0101 0011
Wenn wir die Adresse mal 2 nehmen, bleibt diese ja gleich: 2x0 = 0
Also das unterste Bit der Adresse ist gleich 0. Dann landet 0011 1100 in das r0. Ist das richtig so?
Jetzt erhöhen wir die Adresse um eins:
b0000 0000 0000 0001: 0000 1111 1111 0000
Adresse mal 2 = b0000 0000 0000 0010 -> das unterste Bit ist wieder 0!
hmm, irgendwie versteh ich das nicht
Soweit hab ich das erstmal verstanden mit dem Bücherregal, danke.
Hier mal mein Code:
Bloß wie überprüfe ich, ob er auch wirklich den String "Hallo!" in tmp kopiert? Im Debug-Modus seh ich in r16 auch keine Strings..hmm..Code:;Programm ;CDurTonleiter rauf und runter spielen .include "m8def.inc" .def tmp = r16 ;Mein Universallregister .org 0x000 rjmp reset ;Interruptvektor "reset:" reset: ;Stack einrichten ldi tmp, HIGH(RAMEND) ;HIGH-Byte der obersten RAM-Adresse out SPH, tmp ldi tmp, LOW(RAMEND) ;Low-Byte der obersten RAM-Adresse out SPL, tmp ldi ZH, HIGH(daten1 * 2) ldi ZL, LOW(daten1 * 2) sei ;Interrupts zulassen loop: lpm ;nächstes Byte des String nach r0 einlesen mov tmp, r0 ;Inhalt von R0 nach "tmp" kopieren adiw ZL,1 ;Adresse des Z-Pointers um 1 erhöhen rjmp loop ;immer wieder zu "loop:" springen daten1: .db "Hallo!" ;immer eine gerade Anzahl an Bytes
@Tekeli: Danke für den Link, bin grad nicht drauf gekommen, da nachzuschauen *g* Habs dadurch auch erstmal besser verstanden, aber das mit der 2x hab ich immer noch nicht verstanden, also keine Sorge. Im Tut steht ja auch "Über die Multiplikation der Adresse mit 2 sollte man sich erst mal keine Gedanken machen: "das ist einfach so"™" Da hat der Florian wohl den Satz geklaut oder er weiß es selber nicht *duck* *gg*
@Tekeli: Hast du dir den Wert "0011 1100 0101 0011" jetzt nur ausgedacht, oder muss ich verstehen, was dahinter steckt?
Hallo Tekeli!!
Das Zitat ist etwas kompliziert, das habe ich auch zuerst nicht verstanden!
Der Speicher ist so aufgebaut:
00 00 00 00 00 00
das sind jeweils zwei Bytes zusammengefasst in ein Word!
Das erste Word hat die Adresse 0x0000.
Wenn ich jetzt das Z lade, dann steht darin 2*0 = 0, das ist richtig!
Jetzt erhöhe ich das ganze um eins, ohne es mal 2 zu nehmen, das ist wichtig, das muss man nur bei der initalisierung des Z machen!
2*0 = 0 + 0 = 0 -> erste Adresse
2*0 = 0 + 1 = 1 -> nächste Adresse
2*1 = 2 + 0 = 2 -> nächste adresse
2*1 = 2 + 1 = 3 -> nächste Adresse
Hmm..Achtung, doofe Frage, aber wieso addierst du einmal mit 0 und einmal mit 1? Also mit 1 addieren versteh ich ja, weil wir das nächste Byte haben wollen, aber mit 0?
Ok, alles klar!
Danke sehr!
Lesezeichen