Forum: Compiler & IDEs Problem mit SPI


von Fritz (Gast)


Lesenswert?

Hallo,

ich habe folgendes Problem.

Ich schicke Daten über SPI mit Atmega644.

So sieht der Code aus:

SPDR = 1;                        //eine 1 über SPI versenden
while(!(SPSR&(1<<SPIF)));        //Auf Interrupt warten
bData1 = SPDR;                   //Interrupt Flag zurückgesetzt

SPDR = 2;
while(!(SPSR&(1<<SPIF)));        //Auf Interrupt warten
bData2 = SPDR;


Leider die zweite while-Schleife hängt. Also es kommt kein Interrupt, 
wenn ich SPDR = 2 versende. Woran kann das liegen??

von Fritz (Gast)


Lesenswert?

Ich habe gerade festgestellt, dass WCOL Bit nach der ersten Übertragung 
gesetzt wird!! Das ist ein Kollisionsflag.

The WCOL bit is set if the SPI Data Register (SPDR) is written during a 
data transfer. The WCOL bit (and the SPIF bit) are cleared by first 
reading the SPI Status Register with WCOL set, and then accessing the 
SPI Data Register.

Warum wird dieser Flag gesetzt? Hat jemand eine Idee, warum die SPI 
Übertragung nicht geht, bzw. warum eine Kollision entsteht?

Danke!

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Fritz wrote:

> Hat jemand eine Idee...
> ...warum eine Kollision entsteht?

Das Datenblatt deines geringsten Misstrauens.  Es schreibt:
The WCOL bit is set if the SPI Data Register (SPDR) is written during
a data transfer.

Ich vermute mal, dein SPIF ist noch von einer früheren Operation
möglicherweise gesetzt.  Damit wartet die erste Schleife nicht, weil
es zum Beginn des Transfers nicht gelöscht worden ist.

Es müsste eigentlich helfen, ein
1
(void)SPSR;
obendrüber zu schreiben (über den ersten Transfer).

von Uqzze (Gast)


Lesenswert?

Nachdem ich das gemacht habe, hängt die erste Schleife auch!! Also es 
wird nicht mal ein Byte gesendet!

von Fritz (Gast)


Lesenswert?

WCOL ist gesetzt!! Der Register SPSR hat den Wert 01000000, und das ist 
WCOL Bit -> Kollisionflag.

Woran kann es liegen?!

Im Programm habe ich keinen weiteren Code, nur diese Zeilen mit SPI 
Übertragung.

von holger (Gast)


Lesenswert?

Hast du den SS Pin auf Ausgang programmiert ?
Oder wenigstens als Eingang mit Pullup ?

von Fritz (Gast)


Lesenswert?

Ich habe den als Ausgang programmiert.

von Fritz (Gast)


Lesenswert?

Mein Code sieht so aus:

SPCR0 = (1<<SPE0)|(1<<MSTR0)|(1<<SPR00); // SPI Enable; as Master; 
fck/64
printf ("1");  //Ausgabe über COM

(void)SPSR0;  //SPSRO wird zurückgesetzt
(void)SPDR0;  //SPDR0 wird zurückgesetzt
SPDR0 = 0b00000001;   //SPI Data zum Verschicken
while(!(SPSR0 & (1<<SPIF0)));    // wird auf Interruptanforderung 
gewartet
printf ("2"); ->>> Diese Zeile wird nie ausgeführt, es läuft die 
while-Schleife!! Wenn ich SPSR0 anzeigen lasse, dann ist WCOL 
(Kollisionsflag) gesetzt.

:-( Ich bin verzweifelt... was kann das Problem sein?

von Fritz (Gast)


Lesenswert?

Ich glaube das Problem liegt an der Hardware. Weil der Code geht an der 
STK500! Welche Ursache kann dieses Problem haben? Kann sein, dass ich 
etwas falsch verbunden habe?

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.