Forum: Mikrocontroller und Digitale Elektronik Stringauslesen mit dem Atmega88 (adiw Problem)


von horst (Gast)


Lesenswert?

Ich bekomme folgende Fehlermeldung:  Error   : adiw can only use 
registers R24, R26, R28 or R30

Soweit ich das verstehe, wird in den Z Registern die Anfangs-Adresse der 
db gespeichert. Wie Funktioniert da genau die Zeigererhöhung? Wird dabei 
die Adresse des nächsten zeichens ins Z Register geladen?

Wie kann ich den Befehl adiw "umgehen". Eine erhöhung im zl wird wohl 
nicht reichen oder? Oder muss ich nur noch kontrollieren falls es im zl 
einen Überlauf gibt, und diesen dann im zh "übertragen".

USART_TX_STRING:
    lpm                             ; nächstes Byte aus dem Flash laden
    and     r0,r0                   ; = Null?
    breq    string_ende             ; wenn ja, -> Ende
warten:
    lds temp, UCSR0A
    sbrs temp, UDRE0                ; Warten bis Senden möglich
    rjmp    warten
    sts     UDR0, r0
    ldi temp, 0x01
    adiw    zl:zh,1                 ; Zeiger erhöhen
    rjmp    USART_TX_STRING         ; nächstes Zeichen bearbeiten
string_ende:
    ret                             ; zurück zum Hauptprogramm

von Lucky (Gast)


Lesenswert?

ADIW funktioniert schon, aber mit ZH:ZL nicht ZL:ZH

ADIW ZH:ZL, 1

> Wie kann ich den Befehl adiw "umgehen".

LPM R0, Z+

von Karl H. (kbuchegg)


Lesenswert?

> Eine erhöhung im zl wird wohl nicht reichen oder?

Das W ind ADIW steht für Word, also 2 Bytes. Machst du einen

  ADIW  ZL, 1

dann 'weiß' ADIW schon, dass es auch das ZH Register berücksichtigen 
muss. Sonst wäre der Befehl ja ein bischen sinnlos.

von spess53 (Gast)


Lesenswert?

Hi

>ADIW funktioniert schon, aber mit ZH:ZL nicht ZL:ZH
>ADIW ZH:ZL, 1

Oder auch adiw Z,1

>> Wie kann ich den Befehl adiw "umgehen".
>LPM R0, Z+

Funktioniert nicht nur mit r0


>    and     r0,r0                   ; = Null?

Dafür gibt es auch 'tst rxy'

MfG Spess

von Markus W. (Firma: guloshop.de) (m-w)


Lesenswert?

horst schrieb:
> Soweit ich das verstehe, wird in den Z Registern die Anfangs-Adresse der
> db gespeichert. Wie Funktioniert da genau die Zeigererhöhung? Wird dabei
> die Adresse des nächsten zeichens ins Z Register geladen?

Du musst ZH und ZL zuerst initialisieren, das heißt, die Startadresse 
selbst laden. Beispiel:

ldi ZH,high(daten<<1)
ldi ZL,low(daten<<1)

Das "<<1" (Wertverdopplung) ist notwendig, weil Adressen im PM (Flash) 
immer als Wort-Adressen gespeichert werden. String:Beispiel:

daten:
.db 0x41 0x42 0x43 0x00

> Wie kann ich den Befehl adiw "umgehen". Eine erhöhung im zl wird wohl
> nicht reichen oder? Oder muss ich nur noch kontrollieren falls es im zl
> einen Überlauf gibt, und diesen dann im zh "übertragen".

Warum willst du adiw umgehen? Verwende doch einfach eines der 
vorgesehenen Registerpaare (r25:r24, XH:XL, YH:YL oder ZH:ZL).

Falls du das wirklich nicht willst, brauchst du zwei Befehle 
hintereinander: add und adc. Zuerst wird das Low-Byte normal addiert, 
dann das High-Byte einschließlich Übertrag, der bei der Erhöhung des 
Low-Bytes entstanden ist.

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.