Forum: Mikrocontroller und Digitale Elektronik AVR Studio - Adressierung in 16Bit?


von Tilo (Gast)


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,

von Karl H. (kbuchegg)


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.

von Detlev T. (detlevt)


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.

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.