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,
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.
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.