Hallo
ich möchte einen String z.B. hallo welt ins sramm legen und ihn dann
per lds wieder in ein Register laden um ihn auf dem LCD auszugeben.
Der String soll später Variabel über z.b. Tastatur kommen.
Bei meinem Programm kann ich aber nur ein Buchstaben laden und
ausgeben??
.include"m8def.inc"
.def temp = r16
.def temp1 = r17
.def temp2 = r18
.def temp3 = r19
.equ adresse = 0x60
ldi temp, low(RAMEND)
out SPL, temp
ldi temp, high(RAMEND)
out SPH, temp
ldi temp, 0xFF
out DDRD, temp
rcall lcd_init
rcall lcd_clear
ldi temp, 'hallo Welt'
sts adresse, temp
rcall pause
rcall pause
rcall pause
lds temp1, adresse
rcall lcd_data
rcall pause
jump:
rcall jump
Das problem ist, ein Register hat 8Bit. Ein Zeichen brauch 8 Bit.
"Hallo Welt" sind 10 Zeichen, du bräuchtest ergo 10 Register für
diesen String.
mach doch einfach:
1. ldi temp, 'h'
2. ins ram schreiben an adresse
3. ldi temp, 'a'
4. ins ram schreiben an adresse+1 (oder +8? egal ihr wisst schon was
ich mein ;))
5. ldi temp, 'l'
.
.
.
Register sind keine Variablen :-) kommst du zufällig von Basic oder so
rüber? Passiert schonmal, isses mir auch.
Indirekte Adressierung sollte auch möglich sein. Dabei wird in ein
Register eine Adresse geschrieben, welche zur auswahl der Register
dient , in denen dein String geschrieben ist:
z.B.
Adresse|Inhalt
100 |H
101 |a
102 |l
103 |l
104 |o
Adressregister: 100 -> File-Select-Register: H
Adressregister: 101 -> File-Select-Register: a
...
Adressregister: 104 -> File-Select-Register: o
Du musst nur nachsehen wie (mit welchen Mnemonics) man Indirekte
Adressierung macht. (Asembler-Hilfe?!)
Grundsätzliches Problem auf Harvard-Rechnern wie AVR. Es lassen sich nur
entweder Daten auf dem RAM (z.B. LD R0,Z+) oder Daten aus dem ROM lesen
(LPM). Mit dem gleichen Code beides tun geht nur, wenn man neben dem
Zeiger auch noch die Information mitschleppt, ob der nach RAM oder ROM
zeigt, und im Code dementsprechend darauf zugreift.
Um den String variabel zu machen, musst du ne speicher-Schleife und ne
lade-Schleife bauen.
Speichern musst dann byte für byte. Also im Flash als .db ablegen und
zur Laufzeit reinkopieren. Steht im Tutorial hier auf der Seite (wie
man den Flash ausliest).
Indirekte Adressierung geht nur mit Konstanten.
dave
Danke für die Antworten!
Mit welchem Befehl kann ich denn während er Laufzeit ins Sram
ein .db anlegen und wieder auslesen. Im Tuto ist .db fest vorgegeben.
Ich möchte ja einen veränderlichen String speichern und ausgeben?
Stehe irgendwie aufm Schlauch.
Frank
Hallo,
ldi ZH,0
ldi ZL,0x60 ;Z-Pointer auf RAM-Anfang stellen(Adresse abhängig
vom verwendeten Prozessor und Deinen Vorstellungen)
ldi temp1, 0xF1 ; beispielsweise eine Konstante laden
st Z+, temp1 ; ins RAM speichern
; st kopiert dorthin ins RAM, wo der Z-Ponter hin zeigt, siehe
Befehlsreferenz
GRuß
Z+ heißt, das der Z-Pointer, bestehend aus ZL und ZH, also 16 Bit, nach
der Aktion um 1 erhöht wird, also danach auf das nächste Byte im SRAM
zeigt.
Was Du brauchst sind "Print-Routinen" für feste Texte aus dem Flash
und veränderliche Texte aus dem SRAM-Buffer.
Hier mal Beispiele:
.equ PrtEnd=0 ;Markiert das Textende.
;Ausgabe von Zeichenketten aus dem Flash.
Print:
lpm r16,z+
cpi r16,PrtEnd
breq Print_End
rcall lcd_data
rjmp Print
Print_End:
ret
;Ausgabe von Zeichenketten aus dem SRAM.
Print_SRAM:
ld r16,z+
cpi r16,PrtEnd
breq Print_End
rcall lcd_data
rjmp Print_SRAM
Man muß bei beiden darauf achten, dass das Textende mit PrtEnd
abgeschlossen wird, z. B. im Flash .db 'Hallo Welt',PrtEnd
Beiden Routinen wird in Z die Adresse des Textes übergeben.
Für Texte aus dem Flasch:
ldi zl,low(Text1*2)
ldi zh,high(Text1*2)
rcall Print
Text1: 'Test1',PrtEnd
Für Texte aus dem SRAM:
ldi zl,low(Text2)
ldi zh,high(Text2)
rcall Print
.dseg
Text2: .byte 50
Texte im SRAM können natürlich nicht vorab per AVR-Studio gesetzt
werden sondern müssen per Programm gefällt werden wie es bei Dir ja
eine Übertragungsroutine vom Keyboard ins SRAM machen muß.
Das ist eine andere Sache.
MfG
Andi