STM32 SPI wartet nicht bis CLK fertig ist

OP #4463947
Lesenswert?
• ▲
▼
Hallo zusammen

Ich benutze folgenden Code für meine SPI Routinen:
1
void write_spi (unsigned char data_out)
2
{       //msb first
3

4
  SPI_I2S_SendData(SPI2,data_out);
5
  while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);
6
  while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY) == SET);
7
  SPI_I2S_ReceiveData(SPI2);
8
}
9

10
unsigned char read_spi (void)
11
{
12

13
  SPI_I2S_SendData(SPI2,0x00);
14
  while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);
15
  while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY) == SET);
16
  return SPI_I2S_ReceiveData(SPI2);
17

18
}

NSS ist als Soft konfiguriert.

meine Zugriff sieht etwa wie folgt aus:
1
  cs_0;
2
  read_spi;
3
  cs_1;


Nun ist es leider so, dass CS bereits auf 1 geht, während dem am SPI 
noch die letzte CLK Flanke kommt.
Ja noch schlimmer, CS kann sogar wieder auf low gehen, während dem die 
letzte CLK Flanke der vorherigen Übertragung noch am Pin anliegt.

Siehe dazu die Bilder im Anhang.

Wenn ich vor das CS1 ein Delay einfüge, funktionierts.

Aber weshalb funktioniert der obige SPI code nicht?

Danke
Angehängte Dateien:
OP #4464151
Lesenswert?
• ▲
▼
Für alle die es interessiert.
1
void write_spi (unsigned char data_out)
2
{       //msb first
3

4
  while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY) == SET);
5
  while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);
6
  SPI_I2S_SendData(SPI2,data_out);
7

8
  while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET);
9
  SPI_I2S_ReceiveData(SPI2);
10

11
  while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY) == SET);
12
  while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);
13
}
14

15
unsigned char read_spi (void)
16
{
17

18
  while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY) == SET);
19
  while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);
20
  SPI_I2S_SendData(SPI2,0x00);
21

22
  while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET);
23
  while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY) == SET);
24
  while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);
25

26
  return SPI_I2S_ReceiveData(SPI2);
27
}
Gast #4464251
Lesenswert?
• ▲
▼
Und wie stellst du dir mit deinen beiden Funktionen eine funktionierende 
SPI-Kommunikation vor?
SPI braucht eigentlich nur eine einzige Funktion:
1
uint8_t SPI_transfer_byte(uint8_t tx_data);

Senden und Empfangen geht immer gleichzeitig. Wenn man nur Senden will, 
wertet man den Rückgabewert halt einfach nicht aus.

Deine receive-Funktion sendet ja auch wieder ein Dummy-Byte, so dass das 
vorher im RX-Register enthaltene Byte wieder rausfliegt.
Gast #4464386
Lesenswert?
• ▲
▼
Holger K. schrieb:

> SPI_I2S_ReceiveData(SPI2);
>   while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY) == SET);
>   while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);

Nonsense. Schau Dir mal intensiv die Diagramme an, wie die Events da so 
kommen. Das funktoniert mit jedem Dummy Befehl auch. BSY wird nur vor 
Abschalten der SPI angefragt. Delay(2us) reicht aus.

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.