Forum: Mikrocontroller und Digitale Elektronik STM32 SPI Master Overrun


von TSE (Gast)


Lesenswert?

Hallo,

ich habe einen komischen Effekt beim STM32 SPI.
Dieser zeigt mir im Master Mode ein Overrun Flag.

Ich spreche mit dem STM einen LTC1960 an.
Dieser verlangt zwischen den Bytes einen Impuls auf der SS Leitung.
Das Overrun Flag wird beim Senden des 2. Bytes gesetzt
1
     SPI_Cmd(SPI1,ENABLE);
2
3
    while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
4
    SPI_I2S_SendData(SPI1,0b00000100);
5
    while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) != RESET);
6
    temp1=SPI_I2S_ReceiveData(SPI1);
7
8
    while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
9
    while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) != RESET);
10
    SPI_Cmd(SPI1,DISABLE);
11
    for(temp3=10;temp3>0;temp3--)
12
    {
13
      asm("nop");
14
    }
15
16
    SPI_Cmd(SPI1,ENABLE);
17
    //temp2=SPI_I2S_ReceiveData(SPI1);
18
    while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
19
    SPI_I2S_SendData(SPI1,0b00000101);    //Senden 2. Byte
20
    while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) != RESET);
21
    temp2=SPI_I2S_ReceiveData(SPI1);    
22
    while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_OVR)==1)
23
    {
24
      temp3=SPI_I2S_ReceiveData(SPI1);
25
    }
26
    while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
27
    while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) != RESET);
28
29
30
    SPI_NSSInternalSoftwareConfig(SPI1,DISABLE);
31
    SPI_Cmd(SPI1,DISABLE);

erst wenn ich diese Zeile mit hinzu nehme läuft der code fehlerfrei 
durch
1
temp2=SPI_I2S_ReceiveData(SPI1);

Zu meiner Frage:
Warum wird das Overrun Flag gesetzt?

Grüße TSE

von (prx) A. K. (prx)


Lesenswert?

Wo findet denn dieser SS Puls statt? Im obigen Code jedenfalls nicht, 
denn eine automatische Abschaltung von SS gibt es beim STM32 nicht.

von (prx) A. K. (prx)


Lesenswert?

TSE schrieb:

> Warum wird das Overrun Flag gesetzt?

Wenn du die empfangenen Daten nicht abholst dann ist irgendwann der 
Empfangspuffer voll. Zu jedem gesendeten Byte/Wort wird auch immer eines 
empfangen, ob genutzt oder nicht.

von TSE (Gast)


Lesenswert?

hallo  A. K.

1.
 SPI_Cmd(SPI1,DISABLE);
    for(temp3=10;temp3>0;temp3--)
    {
      asm("nop");
    }

  SPI_Cmd(SPI1,ENABLE);

hier wird der Impuls generiert

2. mit
temp2=SPI_I2S_ReceiveData(SPI1);

werden die Daten aus dem RX Register gelesen (STD_Lib funktion)

von (prx) A. K. (prx)


Lesenswert?

TSE schrieb:

> hier wird der Impuls generiert

Weiss du das oder hoffst du das?

Der STM32 mag SS zwar bei entsprechender Konfiguration automatisch 
aktivieren, aber deaktivieren tut er es hardwareseitig nicht. Ob es die 
Lib tut weiss ich nicht.

> werden die Daten aus dem RX Register gelesen (STD_Lib funktion)

So wie ich dich verstanden habe, wunderst du dich, weshalb ohne diese 
Zeile ein Fehler kommt. Wenn ich das missverstanden habe, dann zeig den 
Code mal entsprechend kommentiert ohne dass man raten muss wo du die 
Zeile einfügst.

von TSE (Gast)


Lesenswert?

Das Oszi zeigt mir den Impuls.
der Impuls ist nicht das Problem der kommt ganz gut.

Die Zeile die ich mein ist in meinem 1. Post auskommentiert; kommt 
gleich nach dem 2. Enablen

ist die Zeile drausn dann gehts nicht
ist die Zeile drinnen dann gehts.

von Lasse S. (cowz) Benutzerseite


Lesenswert?

Die Ursache steht doch schon in

Beitrag "Re: STM32 SPI Master Overrun"

Oder nicht?

von ... (Gast)


Lesenswert?

Gibt es einen guten Grund das SPI Interface jedes Mal komplett 
abzuschalten? Mach es Dir doch leicht (wie in den Beispielen der FW 
Lib):
SPI_InitStructure.SPI_NSS = SPI_NSS_Hard;
...
SPI_SSOutputCmd(SPI_MASTER, ENABLE);
...
SPI_SSOutputCmd(SPI_MASTER, DISABLE);
...
SPI_SSOutputCmd(SPI_MASTER, ENABLE);
...
Dann würdest Du das Interface jedenfalls ein wenig im Sinne des 
Erfinders benutzen.

von Michael (Gast)


Lesenswert?

... schrieb:
> Gibt es einen guten Grund das SPI Interface jedes Mal komplett
> abzuschalten? Mach es Dir doch leicht (wie in den Beispielen der FW
> Lib):
> SPI_InitStructure.SPI_NSS = SPI_NSS_Hard;
> ...


so geht das nicht, wenn man den NSS Pin als Frame select nutzen möchte.
Der STM zieht den nämlich auch low und da bleibt der bis zum 
Weltuntergang... Oder eben Reset bzw. bei Abschaltung des SPI.
Ich setze den NSS bin daher selbst per Software.

Grüße,
Michael

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.