STM32 SPI wartet nicht bis CLK fertig ist

OP #4463947
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
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
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
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

Eine eigene Frage? Dieser Thread ist über 10 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

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.