Forum: Mikrocontroller und Digitale Elektronik SPI Xmega Statusregister nie !=0?


von Michael D. (sirs)


Lesenswert?

HI
1
uint8_t  SpiTransmit (uint8_t  date){ 
2
  SPIF.DATA = date; // Send data 
3
  while (SPIF.STATUS    ==    0); // Wait for the end of transmission
4
 return    SPIF.DATA;// Read the data  
5
  }


Mit diesem kleinen Codestückchen habe ich ein Problem auf meinem 
atxmega. Laut Manual sollte das Statusregister !=0 werden können, wenn 
die Daten ganz rausgeschoben wurden (Interrupt-Flag wird gesetzt). Er 
hängt sich aber in dieser While-Schleife fest.

Fürs Minimalbeispiel noch die init:
1
PORTF_DIRSET  = (1 << SPIF_MOSI) | (1 << SPIF_SCK)  | (1 << SPIF_CS);
2
PORTF_DIRCLR  = (1 << SPIF_MISO);
3
PORTF.OUTCLR = (1 << SPIF_MOSI) | (1 << SPIF_SCK)  | (1 << SPIF_CS)
4
//über defines werden die Pins festgelegt, zB: #define SPIF_SCK  7
5
6
SPIF.CTRL =  SPI_MODE_0_gc | SPI_PRESCALER_DIV4_gc | (1<< SPI_ENABLE_bp) | (1<< SPI_MASTER_bp)| (1<< SPI_CLK2X_bp);
7
SPIF.INTCTRL = SPI_INTLVL_MED_gc;

Was ich mir nicht erklären kann:
Wenn ich den Interrupt ausschalte wird das Statusregister 128 
(Interrupt-Flag als höchstes Bit gesetzt), aber die Schleife hängt 
trotzdem fest?? Habe mir das Register immer ausgeben lassen.

Kann mir das jemand erklären, warum das passiert? Weil der Slave nix 
antwortet? Weil ich einen Fehler reingebaut hab?

PS: Verweist mich ja nicht auf dieses hässlcihe Atmel-Beispielgedönz. 
Ich will das Hardware-SPI-Zeug schließlich lernen.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Michael D. schrieb:
> Mit diesem kleinen Codestückchen habe ich ein Problem auf meinem
> atxmega. Laut Manual sollte das Statusregister !=0 werden können, wenn
> die Daten ganz rausgeschoben wurden (Interrupt-Flag wird gesetzt). Er
> hängt sich aber in dieser While-Schleife fest.

 Probiere es mal mit einer Hilfsvariable in die zuerst Statusregister
 eingelesen wird.
 Oder mit bit prüfen anstatt vorauszusetzen, dass der Register einen
 bestimmten Wert hat.

 If (SPIF.STATUS & 0x80) - oder so.

von Falk B. (falk)


Lesenswert?

@ Michael D. (sirs)

>  while (SPIF.STATUS    ==    0); // Wait for the end of transmission

Das ist schon mal GANZ falsch! Du musst das Bit IF prüfen und den Rest 
ausblenden, denn der ist undefiniert! Siehe Bitmanipulation.

  while (SPIF.STATUS & SPI_IF_bm); // Wait for the end of transmission

>Fürs Minimalbeispiel noch die init:

Die ist unvollständig. Denk dran, du musst das ECHTE SS Signal dieses 
SPI-Moduls als Ausgang definieren, nicht ein belibiges IO-Pin, sonst 
erlebst du dein blaues Wunder. Siehe Doku, "Master mode".

"If the SS pin is not used and is configured as input, it must be held 
high to ensure master operation. If the SS pin is set as
input and is being driven low, the SPI module will interpret this as 
another master trying to take control of the bus. To
avoid bus contention, the master will take the following action:
1. The master enters slave mode.
2. The SPI interrupt flag is set."

von Michael D. (sirs)


Lesenswert?

Nur das IF-Bit zu prüfen macht natürlich Sinn. Danke! Manchmal sieht man 
diese Sachen einfach nicht. Undefiniert kann ja alles sein...

Danke auch für die Info mit dem SS-Pin. War sowieso angedacht dieses SS 
nicht zu verwenden (sondern einen anderen Port) und hier nur per define 
SPIF_CS = 4 zu setzen und gut.

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.