PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Programmspeicher auslesen ?



Gucky
06.11.2007, 09:56
Hallo,
ich habe meine ersten AVR Programme in Assembler geschrieben und habe im Moment ein Problem beim Auslesen einer Textliste aus dem Programmspeicher.
Hierzu habe ich die Anfangsadresse der auszulesende Liste in das Register Z geladen (high und low) und versuche nun den ersten Wert aus der Liste mit dem Befehl LPM (load program memory) auszulesen. Der ausgelesenen Wert sollte dann in R0 stehen. Tut er aber nicht. :-s
Im Simulator des AVR-Studios wird die richtige Programmadresse am Z-Pointer (z.B. 0x00F1) angezeigt. Ich habe anstelle von R0 auch andere Register probiert.

Andere Programmteile wie die Ein- und Ausgabe an den Ports zur LED- und Relaissteuerung sowie auch eine einfache RS232-Übertragung zum PC funktionieren.
Ich nehme an, dass ich entweder noch irgendwo das Auslesen aus dem Programmspeicher freigeben muß oder ich grundsätzlich irgend etwas falsch mache. 8-[

Kann mir jemand einen Tip geben ?

Gruß Gucky. O:)

gummi_ente
06.11.2007, 10:13
Hallo Gucky,

ich meine die AVR's haben den Speicher Wordweise organisiert, daher muß Du die Adresse eins hoch schieben:


ldi ZH,high(Startadr<<1) ; Pointer of Table
ldi ZL,low(Startadr<<1) ; Pointer of Table

Grüße

Gucky
06.11.2007, 11:05
Hallo gummi_ente,
werde ich heute abend mal probieren.

Danke. Gruß Gucky.

Rofo88
06.11.2007, 11:13
gummi_ente hat recht, hier noch mal ein Link zur Erklärung der Sache:

http://www.avr-asm-tutorial.net/avr_de/beginner/register.html#LPM

Gucky
08.11.2007, 12:49
Hallo gummi_ente, hallo Rofo88,
hab's ausprobiert und es läuft.
Was ich jedoch nicht verstehe, ist die Erhöhung der Adresse (mal 2??? warum ???).
Ich habe hier mal ein Listing abgebildet. Vieleicht kann mir jemand genaueres dazu sagen.

;Z-Definition nach Angabe gummi_ente
000036 e0f0 ldi ZH,high(text1<<1) ; Pointer of Table
000037 e8e6 ldi ZL,low(text1<<1) ; Pointer of Table
000038 9005 lpm r0, z+
000039 9005 lpm r0, z+
00003a 9005 lpm r0, z+
00003b 9005 lpm r0, z+

;Z-Definition nach Assembler für Anfänger.
00003c e0f0 ldi ZH,HIGH(2*text1)
00003d e8e6 ldi ZL,LOW(2*text1)
00003e 9005 lpm r0, z+
00003f 9005 lpm r0, z+
000040 9005 lpm r0, z+
000041 9005 lpm r0, z+

;....
;....

;------------------------------------------------------
; HAUPTSCHLEIFE
;------------------------------------------------------
Hauptschleife:
;.... eigene befehle
;.... eigene befehle
;.... eigene befehle
000042 cfff rjmp Hauptschleife ; immer wiederholen

;------------------------------------------------------
; Listen
;------------------------------------------------------
000043 4241
000044 4443 text1: .db 0x41, 0x42, 0x43, 0x44

Beide Z-Definitionen führen zum gleichen Ergebnis.
Im Debugger wird die Z-Anfangsadresse mit 0x0086 angegeben, obwohl die Liste bei Adresse 0x0043 anfängt. Das krieg ich nicht auf die Reihe.

Gruß Gucky. #-o

gummi_ente
08.11.2007, 15:07
Hallo Gucky,

wie es im Tutorial steht:



Für das Lesen aus dem Programmspeicher gibt es nur den Zeiger Z und den Befehl LPM. Er lädt das Byte an der Adresse Z in das Register R0. Da im Programmspeicher jeweils Worte, also zwei Bytes stehen, wird die Adresse mit zwei multipliziert und das unterste Bit gibt jeweils an, ob das untere oder obere Byte des Wortes im Programmspeicher geladen werden soll. Also etwa so:

LDI ZH,HIGH(2*Adresse)
LDI ZL,LOW(2*Adresse)
LPM

Nach Erhöhen des Zeigers um Eins wird das zweite Byte des Wortes im Programmspeicher gelesen. Da die Erhöhung des 16-Bit-Speichers um Eins auch oft vorkommt, gibt es auch hierfür einen Spezialbefehl für Zeiger:

ADIW ZL,1
LPM



Ob man nun die Adresse eins links schiebt oder mit 2 multipliziert ist gleich (bei Binärrechnung).

Grüße

Besserwessi
08.11.2007, 20:02
Der Befehl LPM in der Form LPM r0,z+ ist nicht bei allen (besonder ältere) Chips integriert. Neben dem Lesen des Probrammspeichers wird auch noch nebenbei der Zeiger Z erhöht, also das ADIW ZL,1 gleich mit integriert.

p.s. Bei einer älteren Version von AVRStudio hat der Assembler noch nicht getestet ob der Befehl auch wirklich unterstützt wird und keine Fehlermeldung ausgegeben. Bei mir hat damit ein Programm mit LPM r0,Z+ auf einem Tiny26 funktioniert, obwohl der Befehl nach Datenblatt gar nicht unterstützt wird. Nur als Warnung: Es kann gut sein das der Befehl Probleme macht, z.B. bei höhererem Takt oder wenn sich ZH ändern soll.

Gucky
12.11.2007, 14:15
@gummi_ente, @Rofo88
Danke noch mal für eure Tipps. Langsam begreife ich's, auch wenn ich mir das Tutorial hierzu noch mehrfach durchlesen musste.

@Besserwessi
Probleme bzw. Warnungen habe ich bisher noch nicht mit dem Befehl LPM R0,Z+ gehabt. Ich benutze z.Zt eine ATMEGA8 mit 8MHz intern getaktet und das AVR-Studio 4 V4.13 Build 528.

Gruß Gucky. :)