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
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!
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.
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
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.
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.
> 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
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.
@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
@ 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
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.)
@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
>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.
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?
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.
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?
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
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
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.