Forum: Mikrocontroller und Digitale Elektronik WinAVR Fehlermeldung: Error: number must be positive and less than 32


von BastiH (Gast)


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

von Stefan E. (sternst)


Lesenswert?

Weder SPCR noch SPSR liegen in dem Adressbereich, der für sbi oder sbis 
erreichbar ist.

von Bastian H. (bastianh)


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!

von Stefan E. (sternst)


Lesenswert?

sbi kannst du ersetzen durch eine in/ori/out-Sequenz und sbis durch 
in/sbrs.

von holger (Gast)


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

von Stefan E. (sternst)


Lesenswert?

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.

von Simon K. (simon) Benutzerseite


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

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Simon K. schrieb:
> Ich tippe mal auf:
>
> in r0, SPCR
> ori r0, (1<<SPE)
> out SPCR, r0
Falsch getippt, ORI geht nur mit den Registern R16-R32 ...
Ansonsten okay.

von Simon K. (simon) Benutzerseite


Lesenswert?

Läubi .. schrieb:
> Simon K. schrieb:
>> Ich tippe mal auf:
>>
>> in r0, SPCR
>> ori r0, (1<<SPE)
>> out SPCR, r0
> Falsch getippt, ORI geht nur mit den Registern R16-R32 ...
> Ansonsten okay.

Stimmt! Schon etwas länger her mit dem Assembler.

von holger (Gast)


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

von Simon K. (simon) Benutzerseite


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.

von Bastian H. (bastianh)


Lesenswert?

Hehe seh ich genauso...

Danke euch allen für die Antworten!

von remmy (Gast)


Lesenswert?

@Bastian

Kannst du noch mitteilen was die Lösung war ? Leider sind meine ASM 
Kentnisse so minim, dass ich das nicht hinbringe.

Ich verwende einen AT90CAN128.

Danke

von Falk B. (falk)


Lesenswert?

@  Simon K. (simon) Benutzerseite

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

Na dann schau dir mal PIC-Assembler an . . . 8-0

MfG
Falk

von Hc Z. (mizch)


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

von remmy (Gast)


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

von holger (Gast)


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.

von Timo B. (Firma: MicroForge) (timob)


Lesenswert?

Stefan Ernst schrieb:
> sbi kannst du ersetzen durch eine in/ori/out-Sequenz und sbis durch
> in/sbrs.

Hi Stefan,

muss hier nicht sbis durch in/sbrs/out ersetzt werden und wenn nein, 
warum?

von Flo (Gast)


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.

von Timo B. (Firma: MicroForge) (timob)


Lesenswert?

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?

von Michael U. (amiga)


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

von spess53 (Gast)


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

von Flo (Gast)


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.

von Timo B. (Firma: MicroForge) (timob)


Lesenswert?

Ah, jetzt ist mir alles klar. Danke sehr :)

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.