www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik lcd in asm kriegs nicht gebacken....


Autor: raoul4 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo,
hab schon seit längerem nix mehr mir mcu's gemacht. wollte dann heute
mal in C (codevision) ein lcd ansteuern (hat KS0070B controller, is ja
kompatibel zum standart) das ganze mit nem avr mega32. habs auch
initialisieren können (schwarze balken sind verschwunden). konnte aber
mit der codevision lib und lcd_puts nix darstellen. dann hab ich es mal
wie in dem tut von dieser seite in asm probiert. folgender code:

--------------------

.include "m32def.inc"
.include "lcd-routines.inc"
.def temp1 = r16
.def temp2 = r17
.def temp3 = r18


           ldi temp1, LOW(RAMEND)      ; LOW-Byte der obersten
RAM-Adresse
           out SPL, temp1
           ldi temp1, HIGH(RAMEND)     ; HIGH-Byte der obersten
RAM-Adresse
           out SPH, temp1

           ldi temp1, 0xFF    ;Port D = Ausgang
           out DDRD, temp1

           rcall lcd_init     ;Display initialisieren
           rcall lcd_clear    ;Display löschen

           ldi temp1, 'T'     ;Zeichen anzeigen
           rcall lcd_data

           ldi temp1, 'e'     ;Zeichen anzeigen
           rcall lcd_data

           ldi temp1, 's'     ;Zeichen anzeigen
           rcall lcd_data

       ldi temp1, 't'     ;Zeichen anzeigen
           rcall lcd_data

loop:
           rjmp loop

-----------------

jedoch verschwinden bei diesem code nicht einmal die schwarzen balken,
was ja eigentlich bei der init. passieren sollte (?!)

hab ihr nen tipp für mich?

PS: das kable vom controller zum lcd ist ca. 30 cm lang (flachband).
ist das zu lang?

Autor: Steffen H. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also an der Länge kann es nicht liegen, meines ist locker mal 50cm lang.
Du müsstest vielleicht mal die lcd-routines.inc mit angeben.

Autor: raoul4 (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
hier die routine.
das ist die von der lcd tutorial seite hier. die steht da ganz unten
auf der seite:
http://www.mikrocontroller.net/tutorial/lcd.htm

danke für die schnelle antwort!

mfg raoul4

Autor: Steffen H. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also ich hab jetzt leider keine Zeit, aber hast du gemerkt das diese
Routine für 4MHz geschrieben ist. Wenn deine höcher ist kann es zu
Problemen kommen.

Autor: raoul4 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
schade, dass du keine zeit hast.
der mega läuft auch mit 4 mhz.

gibt es für den compiler einen unterschied zw.

.include "lcd-routines.inc"
und
.include "lcd-routines.asm"

natürlich wenn es diese files auch gibt!
mfg raoul4

Autor: Tobi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
du solltest die include anweisungen auch ans ende der datei schreiben.
das include bedeutet nur, dass der code an dieser stelle komplett wie
er ist eingefügt wird. in deinem fall kommt da nach dem reset was
gehörig durcheinander weil kein definierter startpunkt vorliegt
(spätestens beim ersten ret schmiert alles ab)

Autor: raoul4 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
cool danke! es geht.
aber kannst du mir das nochmal erklären? normalerweise includet man
doch am anfang alles, damit alle befehle und funktionen wissen was sie
tun sollen, oder etwa nicht?!

mfg raoul4

Autor: Christof Krüger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, vielleicht in C, wo es nur Funktionsprototypen o.ä. sind. Aber das
include in ASM kannst du mit einem Präprozessor-makro vergleichen, was
dir wirklich alles au der Datei an diese Stelle knallt. Nach einem
RESET wird bei der Anweisung an der Speicheradresse 0x00 gestartet, und
wenn du das Include am Anfang setzt, ist da auf einmal dein
Unterprogramm. Also entweder alles hinten includen, oder aber zuerst
den Interrupt-Vektor mit den richtigen Jumps, dann includen und dann
das Hauptprogramm... ist Geschmackssache.

Autor: raoul4 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
noch eine frage:
wie kann ich nun in die 2. zeile kommen?

mfg raoul4

Autor: raoul4 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ah nochwas ;)

wie kann ich ganze wörter auf einmal schreiben? also nicht immer jeden
buchstaben einzeln senden, das nervt ja....

mfg raoul4

Autor: Christof Krüger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was meinst du mit "in die 2. Zeile kommen"? Meinst du Sprünge zu
labels?

Wenn du ganze Wörter schreiben willst, dann lege diese als Konstante im
Flash ab und schreibe dir eine Routine, die z.B. im Z-Register die
Adresse des ersten Zeichens übergeben bekommt und sie nacheinander
ausgibt, bis das Null-Byte gelesen wird.

Autor: raoul4 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo,
mit in die 2. zwile kommen meine ich, wie ich etwas in die 2. zeile
meines displays reinschreiben kann.

Zitat:
"Wenn du ganze Wörter schreiben willst, dann lege diese als Konstante
im
Flash ab und schreibe dir eine Routine, die z.B. im Z-Register die
Adresse des ersten Zeichens übergeben bekommt und sie nacheinander
ausgibt, bis das Null-Byte gelesen wird."

bahnhof?!
verstehe nur das wort "wenn" ;)

mfg raoul4

Autor: condor (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo

zeile 2 im lch mußt du adressiern.

ganze texte lise doch mal hir

http://www.mikrocontroller.net/tutorial/memory.htm

Autor: Christof Krüger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"Wenn du ganze Wörter schreiben willst, dann lege diese als Konstante
im Flash ab und schreibe dir eine Routine, die z.B. im Z-Register die
Adresse des ersten Zeichens übergeben bekommt und sie nacheinander
ausgibt, bis das Null-Byte gelesen wird."

Aaaalso:
Du willst ja am liebsten nur einen kurzen Aufruf, um einen festen Text
auszugeben, ja? Da wir es hier nicht mehr mit C, sondern mit ASM zu tun
haben, wird es hier ein printf("blabla") nicht tun. Wir müssen die
Zeichen also Schritt für Schritt anzeigen. Damit wir das nicht bei
jedem Mal extra schreiben müssen, können wir uns eine Routine
überlegen, die wir dann nur noch mit CALL aufrufen müssen. Damit die
Routine weiss, welchen Text sie ausgeben soll, müssen wir ihr das
irgendwie mitteilen.
Die verschiedenen Texte an sich müssen ja auch irgendwo gespeichert
werden. Das passiert am besten im Programmspeicher (also im
"Flash"-Speicher). Damit unsere tolle Routine für Texte beliebiger
Länge funktioniert, muss sie wissen, wann das letzte Zeichen
geschrieben wurde. Das kann man (übrigens wie auch mit C) durch eine
Terminierung durch ein Null-Byte (ASCII-Wert: 0) machen. Also wenn
unsere Routine 0 liest, dann macht sie Feierabend.
Es ist also am besten, wenn wir der Routine die Anfangsadresse des
auszugebenden Textes übermitteln, das kann man ganz gut im Z-Register
machen (sind eigentlich zwei register: ZL = Z-low und ZH = Z-high).

Lies dir am Besten folgendes durch, evtl. auch die vorhergehenden
Kapitel:
http://www.mikrocontroller.net/tutorial/memory.htm

Autor: raoul4 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo christoph,
finde ich stark von dir, dass du dir so viel zeit nimmst!
nur weiter so! danke. werde mal alles durchlesen. wenn ich dann fragen
habe, werdet ihr sie hier nachlesen können ;)

mfg raoul4

Autor: raoul4 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
also:

1. muss man immer bevor man rjmp und call und ret und so benützen will
den stack initialisieren?

2. muss man verstehn wie man den stack initialisiert, oder reicht es
wenn man es einfach vom tutorial abschreibt? (ernstgemeinte frage,
würde es schon gerne verstehen)

3. heißt RAMEND -> Ram End -> Ende des Rams?

4. wie kann man sich diesen stack vorstellen? alles was ich darüber
weis ist, dass was als letztes draufgekommen ist auch wieder als erstes
weggenommen wird, und dass da in diesem stack steht, wo er wieder
"hin-returnen" soll (nach dem rcall befehl)

5. im tutorial steht:

-------
ldi temp, LOW(RAMEND)             ; LOW-Byte der obersten RAM-Adresse
out SPL, temp
ldi temp, HIGH(RAMEND)            ; HIGH-Byte der obersten RAM-Adresse
out SPH, temp
-------

was bedeutet das?
benötigt der stack den ganzen ramspeicher? also sagen diese zeilen dem
stack, von welcher bis welcher adresse der ram speicher geht?!



SCHONMAL DANKE IM VORAUS FÜR ANTWORTEN

mfg roul4

Autor: Christof Krüger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Beim Stack gibt es nicht viel zu verstehen. Das Grundprinzip kennst du
ja schon: Bei jedem Funktionsaufruf wird die Rücksprungadresse auf den
Stack gelegt und beim Return wieder gelesen, um an die richtige Stelle
zurückkommen zu können. Es sollte einleuchten, dass hier ein Stack sehr
praktisch ist, vor allem, wenn man z.B. im Unterprogramm noch weitere
Unterprogramme aufruft, die selbst evtl. wieder Unterprogramme
aufrufen.  Man kann auf dem Stack auch Register ablegen und vor dem ret
wieder auslesen, damit das aufrufende Programm nach dem Aufruf alles
unverändert wiederbekommt.
Der Stack-Pointer zeigt immer auf die nächste leere Stelle im Speicher.
Da Die Variablen generell "von unten" an allokiert werden, ist der
Stack im SRAM "von oben" angelegt und wächst nach unten. Das
Bedeutet, dass man den Stack Pointer ganz zu Anfang an die
höchstmögliche Speicheradresse setzt (RAMEND) und jedes call und jedes
push legt etwas auf den Stack und erniedrigt die Speicheradresse, so
dass der Stack Pointer wieder auf die nächste freie Speicherstelle
zeigt.
Ein Problem, das dann entstehen kann ist natürlich, wenn der Stack zu
voll wird und "unten" in den Datenbereich hereinwächst und Daten
überschreibt. Daher sollte man z.B. Rekursionen vermeiden.

Da viele AVRs mehr als 256 Byte Speicher haben, muss der Stack-Pointer
mit entsprechend großen Adressen umgehen können, er kann also nicht nur
8 Bit breit sein. Daher ist der SP ganze 16 Bit breit, besteht also aus
zwei 8-Bit register, nämlich SPH und SPL (SP-High und SP-Low).

Autor: raoul4 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
vielen dank nochmals
habs jetzt ein wenig verstanden.
aber noch was:

das problem wie ich in asm bei meinem 2 zeiligen display in die 2.
zweil etw. reinschreiben kann ist immer noch nicht gelöst. mit conors
satz: "zeile 2 im lch mußt du adressiern." kann ich leider nocht viel
anfangen. bei dieser lcd routine gibt es den befehl lcd_comman. kann ich
das mit dem vielleicht irgendwie anstellen?

noch was grundlegendes: ist in einer mcu alles adressiert? also kann
man sich das so vorstellen wie in einer großen stadt? (klingt ein
bisschen komisch ;-) )

mfg raoul4

Autor: raoul4 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
weis das wirklich keiner (kann ich mir nicht vorstellen)? möchte doch
nur in die 2. zeile kommen! :-) :-) :-)


mfg raoul4

Autor: Tobi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
steht im datenblatt zu jedem 08/15 lcd display. da solltest du einfach
mal reinschaun

Autor: raoul4 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo,
dem datenblatt (im anhang) nach zu folge müsste ich dann um in die
zweite zeile zu kommen folgendes machen:

ldi temp1, 0b00001010    ;temp1 ist r16
rcall lcd_data           ;unterprogramm (ist in lcd-routines.inc)

ist das richtig?

Autor: Tobi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
sag uns doch lieber was du laut datenblatt machst und nicht nur so eine
zeile. ich glaub aber das wars nicht aber keine garantie, bin zu faul
nachzuschaun...

Autor: Andi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ist FAST richtig.
Allerdings mußt Du nicht Daten zum LCD senden, sondern einen Befehl um
direkt zum Anfang der zweiten Zeile zu kommen.

Probier mal dieses:

;Setzen des LCD-Cursors an eine Adresse
;Befehl  = 1xxxxxxx
;Adresse = xnnnnnnn
;Bei 64  = 11000000
 ldi temp1, 0b11000000
 rcall lcd_command           ;unterprogramm (ist in lcd-routines.inc)
;Zeichen senden
 ldi temp1,"M"
 rcall lcd_data

Im 2-Line-Mode beginnt die erste Zeile bei 0 und die zweite bei 64.
Du kannst Dir natürlich eine Routine machen mit der Du eine ganze Zeile
zum LCD sendest.
Als Paramter in Z die Adresse des Textes (ACHTUNG: Adr*2, da Byte) und
mit r16 oder r17 die Zeilennummer.
Mit nen ATMega8 und größer einfach Zeilennummer * 64 mit "mul Rd,Rr"
und aus R0 die Adresse holen mit nen kleinerer 6 mal nach links
schieben.
Studier Dir auch das "Busy-Verfahren".
Man muß dann halt die R/W-Leitung doch an den Port D.6 z. B.
anschließen.
Man spart sich dann allerdings ne Menge Wartezeit des AVR´s der ja
besseres zu tun haben könnte.

Hier noch ein sehr gutes Datenblatt eines LCD-Controllers (KS0066):
http://www.adamswann.com/projects/avr-lcd/KS0066U.pdf
Bitte 10 mal durchlesen (Befehlsliste und Init-Verfahren).

Gruß
Andi

Autor: raoul4 (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
hallo andi,
danke für deine ausführliche hilfe. dein bsp. funktioniert. aber mal ne
frage dazu. du schreibst:

;Bei 64  = 11000000

was meinst du damit?
in dem datenblatt was du angähngt hast ist auch so eine komsiche
tabelle. genau wie in "meinem". die verstehe ich irgendwie nicht. ich
meine die bei "deinem" auf seite 18 und bei "meinem" auf seite 4.

mfg raoul4

P.S.:habe mir das datenblatt noch nicht 10 mal durchgelesen ;)

Autor: raoul4 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ach hab das mit den 64 doch gecheckt! du meinst die adresse, bei der die
2. zeile anfängt!

mfg raoul4

Autor: Andi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, genau!
Der Befehlscode 1aaaaaaa bedeutet die Übergabe einer Cursor-Adresse
wobei die 1 an Bit-Nr. 7 sein muß und in Bit 6 - 0 die Adress-Bit
(0-127 möglich).

Gruß
Andi

PS: Das mit den 10 mal lesen war nur ein Wink sich das ganze genau
durchzulesen da man es bei 3 mal meist so wie so noch nicht kapiert
hat.

Autor: Andi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ach ja!
Vor dieser "komischen" Tabelle ab Seite 13 sind die ganzen Befehle
genauer beschrieben.

Gruß
Andi

Autor: raoul4 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
das ist ja alles schön und gut ;) (2 von 3 problemen gelöst).
jetzt bleicht halt nur noch das mit den wörtern/sätzen unkompliziert
übertragen zu können.

-----------
Als Paramter in Z die Adresse des Textes (ACHTUNG: Adr*2, da Byte) und
mit r16 oder r17 die Zeilennummer.
Mit nen ATMega8 und größer einfach Zeilennummer * 64 mit "mul Rd,Rr"
und aus R0 die Adresse holen mit nen kleinerer 6 mal nach links
schieben.
-----------

bin ja noch sehr sehr neu in asm.
also fragen zu deinem text:
1. wie kann ein text eine adresse haben?

2. (ACHTUNG: Adr*2, da Byte) was heißt das? zwei adressen? aber wenn
die adresse des textes in das Z register soll, warum brauche ich dann 2
register?! passt in eins nicht ein byte rein?!

3. warum zeilennummer mal 64?

4. was "mul Rd,Rr"

5. jetzt kommt er mit R0 :-)

mfg raoul4

Autor: Andi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dachte eigentlich, Du bist in ASM schon recht firm!
Sorry, aber an Deiner Stelle würde ich erst mal mit dem Grundsätzlichen
anfangen (ASM-Befehle, Zugriffstechniken auf ROM und RAM mittels 2
8Bit-Register etc.).
Lies Dir das AVR-Tut noch mal ordentlich von vorne bis hinten durch.
Auch die Hilfe von AVR-Studio über die AVR-Befehle und zu guter letzt
das PDF für Deinen µC können nicht schaden.
Das alles hier jetzt zu erklären würde den Rahmen hier sprengen.

Gruß
Andi

Autor: raoul4 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ja das prob ist halt nur das ich in dem tut viele sachen nicht verstehe,
und dann gleich wieder aufhöre, weil es mich so ankotzt.

am rande noch eine frage: ist das z-register also 2 byte groß und
besteht deswegen aus 2 reigstern (jeweils 1 byte groß)? also r25 low
byte und r26 ist das high byte von z? kann man z überhaupt ein register
nennen?

mfg raoul4

PS: bei mir besteht ein byte aus 8 bit und ein bit kann entweder 0 oder
1 sein. wenn jetzt jmd sagt, dass das nicht stimmt, kann ich ja gleich
aufhören mit mcu's zu experimentieren. :-(

Autor: Andi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die AVR´s haben 32 8Bit-Register R0 bis R31, OK?
Mit denen kann man alle Dinge mit 8Bit Datenbreite (Add, Sub, OR etc.)
erledigen, also rechnen.
Jetzt haben die letzten 6 Register, R26 - R31 eine Zusatzfunktion als
"Adresspointer" im RAM um auf externen "Arbeitsspeicher" zugreifen
zu können.
Diese Register nennt man dann in Verbindung mit den Befehlen LD
"Load" und ST "Store" dann X, Y und Z.
X besteht dann aus den Registern R26 und R27 oder auch XL und XH.
Y besteht aus den Registern R28 und R29 oder auch YL und YH.
Z besteht aus den Registern R30 und R31 oder auch ZL und ZH.
Um aus dem SRAM ein Byte zu lesen muß man z. B. folgendes machen:

 LDI ZL,low(Adresse)    ;ZL = R30
 LDI ZH,high(Adresse)   ;ZH = R31
 LD R16,Z               ;Inhalt von Adresse "Adresse" nach R16 laden

So weit zum Zugrif auf das SRAM was für alle 3 16Bit-Adresspointer, X,
Y und Z, gleich ist.

Jetzt gibt es aber nur einen Adresspointer mit dem man mit dem
Spezialbefehl "LPM" ein Byte aus dem Flash-RAM lesen kann: Register
Z.
Hier ein Beispiel:

 LDI ZL,low(Adresse*2)    ;ZL = R30; low-Byte der Adresse nach ZL
 LDI ZH,high(Adresse*2)   ;ZH = R31; high-Byte der Adresse nach ZH
 LPM R16,Z                ;Inhalt von Adresse "Adresse" nach R16
laden

Jetzt ist das Problem, dass das Flash-RAM Word-Orientiert ist.
Also Byte Nr. 0 und 1 ist Word-Adresse 0, Byte Nr. 1 und 2 ist
Word-Adresse 1 etc.
Deswegen muß man bei der Zuweisung einer Adresse in Z bzw. ZL und ZH
die Adresse verdoppeln da die Word-Adresse 100 die Adresse in Byte
(8Bit breit) 200 ist.
Auch das AVR-Studio orientiert sich bei Adressierungen im Code-Segment
(cseg) in Word-Adressen.
Deswegen die Verdoppelung.

So, jetzt wird schon fast ein neues TUT draus.
Ich hoffe, Du verstehst das da oben.

Gruß
Andi

Autor: Andi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Shi..! Ein FEHLER!
Hier richtig:
Also Byte Nr. 0 und 1 ist Word-Adresse 0, Byte Nr. 2 und 3 ist
Word-Adresse 1 etc.

Gruß
Andi

Autor: raoul4 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
schönes tut! danke!

frage dazu: (was sonst :))

LDI ZL,low(Adresse)    ;ZL = R30
LDI ZH,high(Adresse)   ;ZH = R31
LD R16,Z               ;Inhalt von Adresse "Adresse" nach R16 laden

ist das so:
z = zl + zh ?
dann ist das ja so:
z = r30 + r31
also praktisch so (in der dritten zeile):
r16 = r30 + r31

aber das geht doch nicht? in ein byte passen doch nicht 2 bytes rein?
oder wie groß ist so eine adresse?
und z zeigt auf diese adresse?
oder ist das so:
es gibt immer zwei adressen in dem speicher, bei der aber dann nur ein
byte gespeichert ist

hast du den msn messenger? dann könnten wir mal chatten, und ich könnte
dich alles schneller fragen ;)
falls du ihn hast: meine e-mail adresse oben ist auch zum adden.
falls nicht: msn messenger ist sowas wie icq
(messenger.msn.de)

mfg raoul4 (noch verwirrter ;) )

Autor: Andi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Chatten ist ja gut und schön aber hier haben evtl. auch andere was
davon.
Die Register X, Y und Z bezeichne ich jetzt mal als "virtuelle
Register" in Verbindung mit den Befehlen LD, ST und LPM.
Bei Ausführung des Befehls "LPM R16,Z" werden die Register ZL und ZH
vom µC zu einem 16Bit-Register zusammengefasst und als Zeiger
(Adresspointer) auf das Flash-RAM benutzt.
Deswegen muß man vor Ausführung des Befehls "LPM R16,Z" die Register
ZL und ZH mit dem low- und high-Byte der Adresse, woraus ein Byte
gelesen werden soll, laden.
Die Register ZL und ZH sind auch nur umschreibungen für die Register
R30 und R31 also in Wirklichkeit besteht das Virtuelle Register Z aus
R30 und R31.
Genauso mit XL, XH, YL und YH (R26, r27, R28 und R29).

Gruß
Andi

Autor: Andi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ach ja!
Man nennte das auch "indirekten Speicherzugriff".
Die Adresse im Flash-RAM wird durch ZL und ZH (Z) gebildet.
Nicht, das Du jetzt meinst, das "LPM R16,Z" heißt lade ZL und ZH nach
R16 sondern lade das Byte, was an der Adresse die in ZL und ZH (Z) steht
nach R16.

Gruß
Andi

Autor: raoul4 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ja aber warum lädt man in zl und zh adressen rein? wenn man jetzt in zl
20 und zh 10 lädt, welchen wert hat denn z? auf was zeigt der dann?
auch 10 oder 20 oder dan ganzen zwischenraum? ich verstehe das alles
nicht. bin ich zu dumm dafür? (16 jahre)

mfg raoul4

Autor: Andi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Na ja, nicht zu dumm, zu unerfahren würd ich mal sagen.
Mit den beiden Registern ZL und ZH wird dann aus 2 8Bit-Zahlen eine
16Bit-Zahl gebildet (low- und high-Byte).
Und eine 16Bit-Zahl braucht man dann nun mal bei Zugiffen auf den
Speicher (Flash-ROM und SRAM) da diese aus mehr als 256 Zellen
bestehen.
In Deinem Beispiel mit 20 und 10 in ZL und ZH hast Du dann eine
16Bit-Zahl von 2580 (high-byte*256 (10*256) + low-byte(20)).

Wie gesagt, fang jetzt erst mal die Grundsätze an zu lernen
(ASM-Befehle, Speicherzugriff etc.).

Gruß
Andi

Autor: Andi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hier noch ein kleines Beispiel:

 ldi r16,1              ;LCD löschen
 rcall lcd_command

 ldi ZL,low(Text*2)     ;lade das low-Byte der Adresse Text in ZL
 ldi ZH,high(Text*2)    ;lade das high-Byte der Adresse Text in ZH
 rcall Print

Halt:
 rjmp Halt

Text: .db "Erster Versuch!",0

Print:
 lpm r16,Z            ;Lade den Inhalt von Adresse bei Text in R16
 tst r16              ;Ist das Zeichen ne 0?
 breq PrintEnd        ;Dann Textende und raus
 rcall lcd_data       ;Zeichen ausgeben
 adiw zh:zl,1         ;Verschiebe Z (ZH:ZL) auf das nächste Zeichen
 rjmp Print           ;Nächstes Zeichen laden
PrintEnd:
 ret                  ;Return

So ne Art Algorhytmus sollte Dir selber einfallen aber vielleicht hilft
es Dir beim verstehen.

Viel Spaß!

Gruß
Andi

Autor: Christof Krüger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Eine extrem wichtige sache beim Herumbasteln ist: Geduld!

Wenn du dir also ein Tutorial durchliest und du verstehst etwas nicht,
dann darfst du nicht sofort aufgeben, sondern solltest es evtl. nochmal
lesen und überlegen, was in deiner Vorstellung denn Sinn macht. Wenn du
es dann immer noch nicht verstehst, dann kannst du immer noch hier
konkret nach einer Formulierung fragen. Vielleicht ist im Tut ja auch
etwas für den Anfänger missverständlich formuliert, so dass ein Hinweis
darauf evtl. sogar anderen hilft, da man das Tut an der Stelle klarer
formulieren kann.
Für schnelle Fragen zwischendurch kannst du auch im IRC auf den server
irc.euirc.net in den Raum #mikrocontroller.net kommen. Wenn du nicht
allzu ungeduldig bist, dann wird da sicherlich immer jemand drin sein,
der dir helfen kann. Allerdings ist es wichtig, dass du dann auch
Eigeninitiative zeigst, und dazu gehört: Datenblatt, div. Tutorials zum
Thema, google.
Also nicht wundern, wenn du nicht direkt die Lösung für dein Problem
bekommst, sondern einen Verweis darauf, wo du dir diese Lösung selbst
erarbeiten kannst. Ich denke, du wirst mir zustimmen, dass du selbst
mehr davon hast, wenn du dir etwas selbst erarbeitest, statt dass dir
jemand etwas vorprogrammiert.

Die zwei 8-Bit register von Z werden nicht, wie du vermutet hast,
addiert o.ä., sondern nebeneinander gesetzt und als ein 16-Bit-Register
gesehen.

Also wenn ZH = 0b11100111 (dezimal 231) und ZL = 0b00011000 (dezimal
24) ist, dann besteht Z ja aus ZH und ZL aneinandergeknüpft, also
Z = 1110011100011000 (binär), was dezimal 59160 entspricht.
Rein mathematisch gilt:
Z = ZH * 256 + ZL
oder
Z = ZH << 8 + ZL, wobei "<<" der Links-Shift-Operator ist (ein
Linksshift entspricht der Multiplikation mit 2, und das 8 Mal
durchgeführt ergibt eine Multiplikation mit 256.)

Autor: Christof Krüger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe zum Thema Adressierung beim AVR mal einen Artikel im Wiki
geschrieben:

http://www.mikrocontroller.net/wiki/Adressierung

Autor: Dirk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

hier war jemand so nett und hat ein schoenes AVR ASM Tutorial
zusammengestellt.


http://www.avr-asm-tutorial.net/avr_de/beginner/index.html

Mfg

Dirk

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.