AVR Studio - Adressierung in 16Bit?

Gast #1798095
Lesenswert?

Hallo

Ich bin noch Anfänger in AVR Assembler und gerad verwirrt. Im Flash habe 
ich eine Sinustabelle abgelegt:
1
.ORG 0x100 ; Use 256Byte boundary. In this case high byte of Z-register can be used to detect end of table
2
sine:
3
    .db 0x52, 0x4F, 0x4E, 0x4C, 0x4A, 0x48, 0x46, 0x44, 0x42, 0x40, 0x3E, 0x3C, 0x3A, 0x38, 0x36, 0x34
4
[...]
Wenn ich den Debugger starte und den Inahlt des Flash anzeigen lasse, 
liegt die Adresse auch an 0x100. Was mich jetzt nur verwirrt: Zähle ich 
die Bytes in "Memory" Fenster fällt auf, dass die Adresse nach 16Bytes 
nur um 8 erhöht wird. Kann es sein, dass im AVR Assembler als Basis 
16Bit und nicht 8Bit verwendet werden?

An einer anderen Stelle will ich die Sinus-Werte über den Z-Pointer 
auslesen:
1
  LDI R30, LOW(sine+1)   ; Set PWM position to 1 because first value of table has just been loaded
2
  LDI R31, HIGH(sine+1)
3
[...] nun steht in R30=0x01 und R31=0x01
4
  LPM R16, Z+            ; Load new value for rising edge into timer and post increment it
5
  OUT OCR0B, R16
6
[...]

Meine Idee war, dass wenn ich "sine" verwende die korrekte Adresse 
verwendet wird. Hier wird sine allerdings als 8Bit Wert interpretiert. 
In R16 wird daher nicht 0x4F geladen sondern 0xD0, wobei 0xD0 in der 
Wort-Adresse 0x80 liegt.

Wie kommt es, dass anscheinend einmal als Basis 8Bit und einmal als 
Basis 16Bit verwendet wird?

Vielen Dank,
#1798107
Lesenswert?

Tilo Lutz schrieb:

> nur um 8 erhöht wird. Kann es sein, dass im AVR Assembler als Basis
> 16Bit und nicht 8Bit verwendet werden?

richtig

AVR sind wortweise orientiert.

> An einer anderen Stelle will ich die Sinus-Werte über den Z-Pointer
> auslesen:
>
1
>   LDI R30, LOW(sine+1)   ; Set PWM position to 1 because first value of
2
> table has just been loaded
3
>   LDI R31, HIGH(sine+1)
4
> [...] nun steht in R30=0x01 und R31=0x01
5
>   LPM R16, Z+            ; Load new value for rising edge into timer and
6
> post increment it
7
>   OUT OCR0B, R16
8
> [...]
9
>
>
> Meine Idee war, dass wenn ich "sine" verwende die korrekte Adresse

Das Problem an dieser Stelle ist nicht "sine" an sich, sondern der LPM 
Befehl. Der will, anderes als der Rest, Byteadressen sehen.

1
   LDI R30, LOW( 2*sine + 1)   ; Set PWM position to 1 because first value of table has just been loaded
2
   LDI R31, HIGH( 2*sine + 1)

Die Multiplkation mit 2 ist erforderlich, weil das Z-Register in 
späterer Folge mit einem LPM benutzt werden soll.
#1798121
Lesenswert?

This is not a bug, it is a feature. ;)

Die Befehle des AVR sind in 16-Bit-Worten organisiert. Daran orientieren 
sich alle Befehle, die damit zu tun haben (jmp etc.) Es wäre dort 
ziemlich unsinnig, ein LSB zu haben, dass zwangsläufig immer null ist. 
So kann man mit rjmp&Co zudem doppelt so weit springen und 128k Flash 
mit einem 16-Bit PC bedienen. Bei dem Zugriff auf Daten geht das aber 
nicht, da man sonst auf die "ungeraden" Adressen gar nicht zugreifen 
könnte.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren