Ich arbeite z.Zt. mit einem ATMega128 (128K Flash). Das bedeutet, daß
HIGH und LOW nicht ausreichen um die oberen Bereiche des Speichers
anzusprechen. Wie kann ich diesen Bereich trotzdem erreichen?
spess53 schrieb:> Hi>>>Der 128 ist organisiert zu 64K x 16Bit, also alles über HIGH und LOW>>erreichbar.>> Nein. Z.B. für LPM ist er 128x8 organisiert.>> MfG Spess
Stimmt. Ich hatte es nur aus Instruction-Pointer-Sicht betrachtet; bei
Tabellen hast Du recht.
Route 66 schrieb:> Stimmt. Ich hatte es nur aus Instruction-Pointer-Sicht betrachtet; bei> Tabellen hast Du recht.
Dann würde ich erst mal die Tabellen im unteren Bereich unterbringen -
falls das reicht, natürlich.
Gruss Reinhard
Hallo Spess,
zum besseren Verständnis mein Problem:
Ich habe den Speicher mit Bilddaten gefüllt, die ich jetzt von oben
(d.h. höchste Adresse) nach unten auslesen und zu einem Controller
übertragen will.
Wenn ich es richtig verstehe, dann kann ich durch setzen des RAMPZ Bits
den Zeiger auf die oberste Adresse setzen und dann mit lpm (oder elpm?)
und sbiw nach unten gehen. Muß ich dann bei Erreichen der 64K Grenze das
RAMPZ Bit wieder löschen?
Gruß Bruno
Hi
>Wenn ich es richtig verstehe, dann kann ich durch setzen des RAMPZ Bits>den Zeiger auf die oberste Adresse setzen und dann mit lpm (oder elpm?)>und sbiw nach unten gehen.
Ja.
Muß ich dann bei Erreichen der 64K Grenze das RAMPZ Bit wieder löschen?
Ja. Allerdings würde ich das 'automatisieren':
1
clr r2 ; Null
2
3
.....
4
5
ldi ZL,1
6
mov r3,ZL ;
7
out RAMPZ,r3 ; RAMPZ laden
8
ldi ZL,Low(xy*2)
9
ldi ZH,High(xy*2) ; Z laden
10
11
....
12
13
lpm r16,Z ; Byte holen
14
sbiw Z,1
15
sbc r3,r2
16
out RAMPZ,r3 ; (RAMPZ:Z) - 1
also keine Vergleiche und bedingte Sprünge.
>Ich habe den Speicher mit Bilddaten gefüllt, die ich jetzt von oben>(d.h. höchste Adresse) nach unten auslesen und zu einem Controller>übertragen will.
Die ungedrehte Reihenfolge wäre besser. Dann könntest du
1
elpm r16,Z+
benutzen. Bei elpm wird Z und PAMPZ als 24 Bit Register benutzt und du
brauchst dich nicht um die 64K-Grenzen zu kümmern. Allerdings kennt elpm
nur das postincrement.
MfG Spess
Hi
>Woher kommt der Wert in r2 wenn die Adresse von Z nach - geht??
Von hier:
Beitrag "Re: ASM-Problem bei Speicher >16 Bit"
clr r2 ; Null
Wenn Z = $0000 ist und das sbiw ausgeführt wird enthält Z den Wert $FFFF
und das Carry-Flag wird gesetzt. sbc subtrahiert dadurch 1 (0 + C-Flag)
von r3. Mit dem 'out RAMPZ, r3' wird dann das RAMPZ0-Bit gelöscht. Damit
zeigt dann Z auf die oberste Adresse der unteren 64k.
MfG Spess
Hi
>Was ich aber nach wie vor nicht verstehe ist,>warum das Carry Flag von Z in r2 gesetzt wird.
Nicht in r2. Das ist immer Null.
Dir ist anscheinend sbc (Subtract with Carry) nicht so richtig geläufig.
Mal mit Zahlen:
C-Flag = 0 sbc 5,2 Ergebnis: 3
C-Flag = 1 sbc 5,2 Ergebnis: 2
Solange Z>=1 ist wird bei sbiw Z,1 das Carry-Flag nicht gesetzt. r3
bleibt damit unverändert (1-0/0-0). Bei einem negativen Überlauf (Z=0 -
1) setzt sbiw das Carry-Flag. Und in dem Fall wird von r3 (0+1)
abgezogen. Bei out wird dann RAMPZ0 gelöscht.
MfG Spess
Ich würde Dir dringend empfehlen, so Du weiterhin in Assembler
programmieren willst, Dir die Beschreibung der Befehle anzuschauen.
Der Prozessor schleppt einen ganzen Sack voll Flags mit sich herum, die,
in der Hauptsache, von arithmetischen Operationen gesetzt bzw. gelöscht
werden.
Ich meine ich habe es verstanden.
Das Carry Flag oder auch andere Flags sind unabhängig von den Registern
und werden beim nächsten Carry-Befehl wirksam. In unserem Beispiel
könnte somit statt r2 auch jedes andere Register stehen, soferne es 0
ist.
Danke für die Geduld!
Hi
Bis auf 'beim nächsten Carry-Befehl wirksam'. Die Flags sind bis zum
nächsten Befehl, der diese beeinflußt gültig. Die Auswertung sollte
daher möglichst unmittelbar erfolgen.
Für die Befehle lege ich dir nahe das
http://www.atmel.com/images/doc0856.pdf
gründlich zu studieren.
MfG Spess
@Bruno
>Ich meine ich habe es verstanden.
Etwas vereinfacht ausgedrückt kann man sagen:
a) Es gibt Befehle, die die Flags beeinflussen und
b) Befehle, die diese unverändert lassen.
Man muss dabei aber höllisch aufpassen. Z.B.
LDI R16,20 ; Lade 20 nach R16, keine Flagänderung
SUBI R16,20 ; Subtrahiere 20 von R16, Flags verändert (Z)
; Ein BREQ XXX an dieser Stelle würde zu einer Verzweigung führen
; da Z=1 (stimmt ja auch)
LDI R16,10 ; Lade 10 nach R16, keine Flagänderung
; Ein BREQ XXX an dieser Stelle würde zu einer Verzweigung führen
; da immer noch Z=1 - Obwohl R16 mittlerweile 10 ist.
>; Ein BREQ XXX an dieser Stelle würde zu einer Verzweigung führen>; da Z=1 (stimmt ja auch)>LDI R16,10 ; Lade 10 nach R16, keine Flagänderung>; Ein BREQ XXX an dieser Stelle würde zu einer Verzweigung führen>; da immer noch Z=1 - Obwohl R16 mittlerweile 10 ist.
Das kann ich mir nicht vorstellen. Hast du das mal ausprobiert?
Gruß Jonas
Hi
>Das kann ich mir nicht vorstellen. Hast du das mal ausprobiert?
Ist schon richtig so. Ein ldi-Befehl beeinflusst keine Flags. Um auf das
veränderte Register r16 zu reagieren müsste ein 'tst r16' gemacht
werden.
MfG Spess
http://www.atmel.com/images/doc0856.pdf
Runterladen. Lesen. Verstehen. Nochmal lesen. Und beim programieren
solange immer wider konsultieren, bis man es auswendig kann.
Oliver
Hi,
ich muß mich noch einmal melden!
In der Zwischenzeit habe ich versucht meinen Code arbeitsfähig zu
machen, was mir letztendlich auch gelungen ist.
Ich bin dabei allerdings auf ein Problem gestoßen, das ich mir wieder
einmal nicht erklären kann.
Ich habe zuerst versucht die Version von Spess zu realisieren u.z.wie
folgt:
1
Bild_loop:
2
elpm temp, Z
3
st X+, temp
4
sbiw Z, 1
5
sbc r3, r2
6
out RAMPZ, r3
7
cp XH, temp1
8
brne Bild_loop
9
ret
mit X und temp1 wird die Speicheradresse neu eingestellt und hat hiermit
eigentlich nichts zu tun.
Das Ergebnis ist in Bild1 zu sehen, wobei jetzt aber auch noch
Spiegelungen von der Kamera enthalten sind. Bei Vergrößerung sind die
Fehler im Mittelteil aber deutlich zu sehen. Dazu kommen noch die
Doppelungen oben und unten, die auf einen Speicherfehler hindeuten.
Erklären kann ich mir das nicht, da ich mit dem Debugger eigentlich
keinen Fehler finden konnte.
Funktioniert hat es letztendlich damit:
1
Bild_loop:
2
elpm temp, Z
3
st X+, temp
4
sbiw Z, 1
5
cpi ZH, 0
6
breq RAMP
7
_Bild_loop:
8
cp XH, temp1
9
brne Bild_loop
10
ret
11
RAMP:
12
cpi ZL, 0
13
brne _Bild_loop
14
clr r3
15
out RAMPZ, r3
16
rjmp _Bild_loop
Das Ergebnis sieht man in Bild2
Hat jemand eine Erklärung?
Mfg Bruno
Hallo Spess,
> Bist du sicher, das du r2 auf Null gesetzt hast?
Ich muß gestehen, daß ich es nicht ausdrücklich auf Null gesetzt habe,
da ich es im restlichen Programm nicht benutzt habe. Das ist natürlich
Lotterie, ich weiß. Ich melde Dir das Ergebnis nach Korrektur.
Gruß Bruno