Hallo,
für den mega8 schreibe ich im Studio4.8 ein kleines Ass-Programm.
In einer Sequenz soll auf eine Tabelle im Flash-ROM zugegriffen werden.
So sieht's aus:
.
.
.
clr r31
ldi r30,tast0 ;z-pointer initialisieren
lpm ;wert in der tabelle unter tast0 in r0 laden
.
.
.
.org 0xa0
tast0: .db 0x0e, 0x1e
tast1: .db 0x0d, 0x1e
.
.
.
In r0 wird aber entweder nicht, etwas falsches oder 0xff geladen.
Ich habe das mit zwei Simulatoren getesten. Mit Studio4.08 und VMLAB.
VMLAB gibt eine zusätzliche Warnmeldung: z index points to a
unprogrammed ROM position: $00a0, Read $FF
Was mache ich hier falsch?
Norbert
Der Programmspeicher beim AVR ist 16 Bit breit. Daher ist folgende
Schreibweise für Byte-Adressierung erforderlich:
ldi r30,low(tast0 * 2) ;z-pointer initialisieren
ldi r31,high(tast0 * 2)
ahh, danke mmerten,
werd's heute abend ausprobieren. Meine z-pointer initialisierung habe
ich aus einem AVR-Lehrbuch(Franzis). Muss mal schauen, was da anders
ist.
Norbert
Hi, ich habe auch das selbe problem
hab schon einige Threads gelesen. Das Programm mehrmals umgeschrieben
und es geht immer noch nicht.
Ich möchte Konstanten in zwei tabellen schreiben.diese will ich dann in
ein Register laden und an OCR1AH und OCR1AL ausgeben.
Ich habe zwei Tabellen eine für OCR1AH und eine für OCR1AL. nun soll
ein Pointer auf den ersten wert der Tabelle zeigen und den wert in das
entsprechende register ausgeben (sozusagen der HIGHteil einer
Konstante). Nachdem der Wert des Zeigers gesichert wurde soll er dann
auf den ersten Wert der Tabelle zwei zeigen(sozusagen der LOW-Teil
einer Konstante).
so sieht das Programm aus(Programmausschnitte):
.def drehzl = r19
.def drehzh = r20
.def ptabl = r21
.def ptabh = r22
...
ldi ZL, low(tabhigh)
lpm drehzh, Z ; zuweisen der Maximalfrequenz
90Hz/0x2b5
mov ptabh, ZL
ldi ZL, low(tablow)
lpm drehzl, Z
mov ptabl, ZL
out OCR1AH, drehzh
out OCR1AL, drehzl
...
drehz_hoch:
in save_sreg, SREG
mov ZL, ptabh
lpm drehzh, Z+
mov ptabh, ZL
out OCR1AH, drehzh ; zuweisen von OCR1A
mov ZL, ptabl
lpm drehzl, Z+
mov ptabl, ZL
out OCR1AL, drehzl
out SREG, save_sreg
ret
drehz_runter:
in save_sreg, SREG
inc ptabh
mov ZL, ptabh
lpm drehzh, Z
out OCR1AH, drehzh ; zuweisen von OCR1A
inc ptabl
mov ZL, ptabl
lpm drehzl, Z
out OCR1AL, drehzl
out SREG, save_sreg
ret
.cseg
tablow:
.db 2,2,2,2,3,3,3,3,4,4,4,5,6,6,8,9,12,16,24,0
tabhigh:
.db
112,144,181,222,12,64,123,192,16,111,225,107,25,248,34,195,52,69,105,0
Habe das Programm im Simulator simuliert. Der Z Pointer besitzt die
richtige Adresse aber er liefert nicht den Wert von dieser Adresse. Er
liefert irgendeinen Hex.-wert.
Ich hoffe jemand hat eine Idee woran es liegen kann
daniel
Der Programmspeicher adressiert:
- 16bit Worte wenn Code,
- 8bit Bytes wenn Daten.
Die in den Studio-Tools angezeigte Adresse ist die Wortadresse. Beim
Mega8 also 4K Worte, Bereich 0x0000..0x0FFF. Die im LPM-Befehl nötige
Byte-Adresse ist das Doppelte davon, Bereich 0x0000..0x1FFF.
Daher => mmerten.
Hallo,
gleiches Thema...
außerdem ist die in Z genutzte Adresse 16Bit, ZH sollte also auch mit
ldi ZH,high(2*tabhigh)
ldi ZH,high(2*tablow)
geladen werden.
Oder Du machst es woanders und bist ganz sicher, daß es nie verändert
wird UND das die Tabellen IMMER im gleichen Seitenbereich zu liegen
kommen...
Ich verlasse mich auf sowas nie, wenn irgendwas im Code verändert wird,
verschieben sich ja auch die Tabellen beim assemblieren.
ldi ZL, low(2*tabhigh)
lpm drehzh, Z ; zuweisen der Maximalfrequenz
90Hz/0x2b5
mov ptabh, ZL ; willst Du hier nicht ZH nach ptabh
haben???
ldi ZL, low(2*tablow)
lpm drehzl, Z
mov ptabl, ZL
Außerdem: warum legst Du die Tabellen nicht als Word-Folge an, wenn Du
16Bit-Werte brauchst?
.tab .dw 0815, 4711, ...
Liest sich sicher besser und spart beim Zugriff:
ldi ZH, low(2*tab)
ldi ZL, low(2*tab)
lpm drehzh, Z+
lpm drehzl, Z ; zuweisen der Maximalfrequenz
90Hz/0x2b5
wenn es ein Mega ist, hier dann
movw ptabh,ZL
sonst Deine Version
mov ptabh, ZH
mov ptabl, ZL
Gruß aus Berlin
Michael
ich versteh nicht ganz :(
ich habe eine Tabelle mit 8 Bit werten, hintereinander.
sie steht im Speicherbereich über 0x60 und hat auch nur eine 8 Bit
speicheradresse (noch, wenn ich beide funktionierende Programmteile
zusammenführe wird sich das bestimmt ändern und die Tabelle steht
weiter hinten im Flash).
Ist der programmierte Code funktionsfähig und der Assambler macht etwas
falsch oder ist es ein programmierfehler?
daniel
Hallo,
nein, der Flash hat immer eine 16Bit-Adresse, nur weil (bis jetzt) die
obereb 8Bit auf 0 sind, ist es keine 8Bit-Adresse.
Deine Adresse ist also nicht 0x60 sondern 0x0060.
Geht auch nicht anders, wie sollten sonst Flash-Adressen über 256
angesprochen werden?
Der Zugriff auf den Flash ist Word- (16Bit) organisiert. Die Adresse
0x0001 zeigt also auf das 2. Word (oder eben das 3. und 4. Byte).
LPM liest aber Byte-weise, Bit 0 im Zeiger entscheidet, ob das Low-Byte
oder das High-Byte des 16Bit-Wertes in das 8Bit-Register gelesen werden
soll.
Die Adresse muß also *2 genommen werden, damit sie auf die richtige
Word-Adresse zeigt.
Näheres findet man im Datenblatt des AVR unter Memory und im
AVR-Instruktion-Manual unter LPM.
Dein Programm kann also so nicht funktionieren.
Hi
@Michael
Vielen Dank es funktioniert nur die Zahlen waren vertauscht
hab nun alle Konstanten wieder im Wordformat
ldi ZH, high(2 * tab)
ldi ZL, low(2 * tab) ; Z- Pointer initialisieren
lpm drehzl, Z+ ; zuweisen der Maximalfrequenz 90Hz/0x2b5
lpm drehzh, Z
out OCR1AH, drehzh
out OCR1AL, drehzl
tab:
.dw
0x0270,0x0290,0x02b5,0x02de,0x030c,0x0340,0x037b,0x03c0,0x0410,0x046f,0x
04e1,0x056b,0x0619,0x06f8,0x0822,0x09c3,0x1045,0x1869,0x0000
das funktioniert nun