Forum: Mikrocontroller und Digitale Elektronik Assemblerbefehl LPM + Tabelle


von Norbert (Gast)


Lesenswert?

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

von mmerten (Gast)


Lesenswert?

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)

von Norbert (Gast)


Lesenswert?

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

von daniel (Gast)


Lesenswert?

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

von A.K. (Gast)


Lesenswert?

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.

von Michael U. (Gast)


Lesenswert?

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

von daniel (Gast)


Lesenswert?

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

von daniel (Gast)


Lesenswert?

Hi@Michael

vielen Dank, ich werde den nochmal mit deinen Hinweisen un bespielen
nochmal überarbeiten.

daniel

von Michael U. (Gast)


Lesenswert?

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.

von daniel (Gast)


Lesenswert?

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

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.