WinAVR Fehlermeldung: Error: number must be positive and less than 32

Gast #1358357
Lesenswert?

Hallo,

ich versuche einen Quellcode der ursprünglich für einen Atmega128 
geschrieben wurde für einen Atmage168 zu kompilieren. Leider spuckt der 
Compiler eine Fehlermeldung aus mit der ich wenig anfangen kann und zu 
der ich auch nur wenig gefunden habe:

Code:
1
SPI_SEND:   
2
    sbi SPCR,SPE        ;enable SPI
3
    out SPDR,r24        ;load byte in SPI data register
4
SPI_SEND_0: 
5
    sbis    SPSR,SPIF
6
    rjmp    SPI_SEND_0      ;transmitt byte to LCD
7
    in  r0,SPDR
8
    sbi PORTB,LCD_CS        ;deselect Display
9
    ret

Die Zeile "sbi SPCR,SPE" erzeugt den folgenden Fehler:

../lcd.S:219: Error: number must be positive and less than 32

Die Zeile "sbis    SPSR,SPIF" erzeugt ebenfalls diese Fehlermeldung:

../lcd.S:222: Error: number must be positive and less than 32


Ich habe hier schon gelesen das in/out Teilweise durch lds/sts ersetzt 
werden müssen aber das hilft hier nicht und betrifft ja auch nicht 
wirklich die Zeile(n) um die es geht.

Hat jemand eine Idee? Übersehe ich eventuell einen ganz offensichtlichen 
Fehler?

Freundliche Grüße
Bastian Hundt
#1358370
Lesenswert?

Danke für die schnelle Antwort!

Da hätte ich wohl auch alleine drauf kommen können. Hast du jetzt auch 
noch ne Tip wie ich das ganze umschreiben muss? (jetzt rächt sich meine 
ASM Abneigung).

Vielen dank und freundliche Grüße
Bastian

PS es ist unglaublich wie schnell man hier konstruktive Antworten 
kriegt!
Gast #1358378
Lesenswert?

>    sbi SPCR,SPE        ;enable SPI

    ldi SPCR,(1<<SPE)        ;enable SPI

Ich hoffe das stimmt so.

>    sbis    SPSR,SPIF
>    rjmp    SPI_SEND_0      ;transmitt byte to LCD


    in r0,SPSR
    sbrs r0,SPIF
    rjmp    SPI_SEND_0      ;transmitt byte to LCD
Persönliche Seite #1358410
Lesenswert?

Stefan Ernst schrieb:
> holger schrieb:
>>>    sbi SPCR,SPE        ;enable SPI
>>
>>     ldi SPCR,(1<<SPE)        ;enable SPI
>>
>> Ich hoffe das stimmt so.
>
> Nein, das geht nicht. Und selbst wenn es prinzipiell gehen würde, wäre
> es nicht das Gleiche, wie das Setzen eines Bits.

Ja, gleich zwei Fehler ;)

Ich tippe mal auf:

in r0, SPCR
ori r0, (1<<SPE)
out SPCR, r0
Gast #1358438
Lesenswert?

> Nein, das geht nicht. Und selbst wenn es prinzipiell gehen würde, wäre
> es nicht das Gleiche, wie das Setzen eines Bits.

>Ja, gleich zwei Fehler ;)

Hatte gleich so ein schlechtes Gefühl dabei.

>Falsch getippt, ORI geht nur mit den Registern R16-R32 ...

AVR Assembler ist doof ;)
Duck und wech
Persönliche Seite #1358441
Lesenswert?

holger schrieb:
>> Nein, das geht nicht. Und selbst wenn es prinzipiell gehen würde, wäre
>> es nicht das Gleiche, wie das Setzen eines Bits.
>
>>Ja, gleich zwei Fehler ;)
>
> Hatte gleich so ein schlechtes Gefühl dabei.
>
>>Falsch getippt, ORI geht nur mit den Registern R16-R32 ...
>
> AVR Assembler ist doof ;)
> Duck und wech

Genau, wofür gibts C! ;) ;) AVR Assembler ist doch ein einziger 
Würg-Around.
#1457897
Lesenswert?

Das reicht nicht. Ein wichtiger Punkt wurde vergessen: es muss heißen
1
 sbi _SFR_IO_ADDR(SPCR),SPE        ;enable SPI
statt
1
 sbi SPCR,SPE        ;enable SPI

und das überall, wo der I/O-Bereich angesprochen wird, sonst wird das 
alles nichts.

Siehe Manual zur AVR-Libc.  (Man kann auch '#define __SFR_OFFSET 0' an 
den Programmbeginn setzen, aber ich würde mir gleich die 'richtige' 
Syntax angewöhnen, wie sie die gcc-Toolchain vorsieht.)
Gast #1459173
Lesenswert?

@Hazeh

>Das reicht nicht. Ein wichtiger Punkt wurde vergessen: es muss heißen
> sbi _SFR_IO_ADDR(SPCR),SPE        ;enable SPI

>statt
> sbi SPCR,SPE        ;enable SPI

Wenn ich das bestehnde mit deinem Vorschlag ersetzte tut das immer noch 
nicht. Der Fehler ist noch der selbe:

Error: number must be positive and less than 32


Danke
Gast #1459197
Lesenswert?

>Ich verwende einen AT90CAN128.

> sbi SPCR,SPE        ;enable SPI

>Wenn ich das bestehnde mit deinem Vorschlag ersetzte tut das immer noch
>nicht. Der Fehler ist noch der selbe:

>Error: number must be positive and less than 32

SPCR kann beim AT90CAN128 nicht per sbi benutzt werden.
Das Register sitzt zu weit oben. 0x2C (0x4C).

Du musst einen Umweg über ein Register nehmen.
Gast #1539429
Lesenswert?

Code:

SPI_SEND:
    sbi SPCR,SPE        ;enable SPI
    out SPDR,r24        ;load byte in SPI data register
SPI_SEND_0:
    sbis    SPSR,SPIF
    rjmp    SPI_SEND_0      ;transmitt byte to LCD
    in  r0,SPDR
    sbi PORTB,LCD_CS        ;deselect Display
    ret

wird zu

Code:

SPI_SEND:
    in  r16, SPCR       ;freies register benutzen
    ori r16, (1<<SPE)   ;rein ins register, verändern und raus
    out SPCR, r16

    out SPDR,r24        ;load byte in SPI data register
SPI_SEND_0:
    in      r24, SPSR
    sbrs    r24, SPIF
    rjmp    SPI_SEND_0      ;transmitt byte to LCD
    in  r0,  SPDR
    sbi PORTB,LCD_CS        ;deselect Display
    ret

Kannst das mal austesten, r16 (oder ein anderes) muss halt frei sein, 
damit du es bequem überschreiben kannst. Ansosnten mit push / pop 
arbeiten.
#1539442
Lesenswert?

Hallo,

Timo Birnschein schrieb:
> Das würde bedeuten, dass sbrs auch wieder zurück speichert.... O_o
Wozu?

Skip if Bit in Register is Set überspringt den nächsten Befehl, wenn das 
gewünschte Bit im Register gesetzt ist.

> Oder wird mittels
>
> in r24, SPSR
>
> ne Art pointer geladen mit dem durch sbrs das Bit SPIF im Register
> gezeigt aus r24 gesetzt wird?

Nein, in lädt den Inhalt vom I/O in das gewählte Register.
Am I/O wird ja damit nichts geändert.

Gruß aus Berlin
Michael
Gast #1539444
Lesenswert?

Hi



>Das würde bedeuten, dass sbrs auch wieder zurück speichert.... O_o
>Oder wird mittels

>in r24, SPSR

>ne Art pointer geladen mit dem durch sbrs das Bit SPIF im Register
>gezeigt aus r24 gesetzt wird?

Weder ein Zeiger, noch braucht etwas zurückgespeichert werden.

sbrs: Skip if Bit in Register is Set überspringt den nächsten Befehl 
wenn das entsprechende Bit gesetzt ist.

MfG Spess
Gast #1539445
Lesenswert?

Inhalt der Speicheradresse SPSR wird damit "in" das Register r24 
geladen,
über sbrs (Skip if Bit in Register Set) wird gesprungen, sobald das Bit 
SPIF im r24 gesetzt ist.
Damit überspringt man beim Ende der Übertragung den Jump zurück.

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