STM32G0 SPI RXNE hängt sporadisch

OP #7420894
Lesenswert?
• ▲
▼

Hallo,

ich habe ein sporadisches Problem mit der SPI-Schnittstelle vom STM32 G0. Die Schnittstelle wird manuell betrieben und dient der Kommunikation mit einem MCP3561. Im Betrieb und auf der normalen Platine funktioniert alles einwandfrei. Für Hardware-in-the-Loop Tests ersetzen wir den MCP3561 mit einem SPI-Slave. Bevor wir diesen aber durchtesten können, haben wir das Problem, dass unsere Sende/Empfangsroutine hängen bleibt. Da wir den SPI im Master betreiben, sollte eigentlich im schlimmsten Falle irgendein Müll eingelesen werden, aber hauptsache irgendwas wird eingelesen? Hier der Code:

1
uint8_t mySPITransmitReceiveBlocking(uint8_t *tx_data, uint8_t *rx_data, uint16_t size){
2
  uint8_t crcerror = 0;
3
  //  if CRC is enabled, reset CRC registers
4
  if(SPI2->CR1 & SPI_CR1_CRCEN){
5
    SPI2->CR1 &= ~SPI_CR1_CRCEN;
6
    SPI2->CR1 |= SPI_CR1_CRCEN;
7
  }
8
  __disable_irq();
9
  SPI2->CR1 |= SPI_CR1_SPE;  //  enable SPI
10
  for(int i = 1; i <= size; i++){
11
    while(!(SPI2->SR & SPI_SR_TXE));
12
    *((__IO uint8_t *)&SPI2->DR) = (uint8_t) *tx_data;
13
    tx_data++;
14
    if(i == size){  //  if CRC is enabled, send CRC next if transmission is finished
15
      if(SPI2->CR1 & SPI_CR1_CRCEN){
16
        SPI2->CR1 |= SPI_CR1_CRCNEXT;
17
      }
18
    }
19
    while(!(SPI2->SR & SPI_SR_RXNE));
20
    *rx_data = (*((__IO uint8_t *)&SPI2->DR));
21
    rx_data++;
22
  }
23
  //  CRC CHECK
24
  if(SPI2->CR1 & SPI_CR1_CRCEN){
25
    //  16 bit CRC is sent automatic, but must be read!
26
    while(!(SPI2->SR & SPI_SR_RXNE));
27
    uint8_t dummy = (*((__IO uint8_t *)&SPI2->DR));
28
    while(!(SPI2->SR & SPI_SR_RXNE));
29
    dummy = (*((__IO uint8_t *)&SPI2->DR));
30
    (void)dummy;  //  remove warning of ununsed variable
31

32
    //  check crc flag
33
    if(SPI2->SR & SPI_SR_CRCERR){
34
      //  wrong crc value
35
      SPI2->SR &= ~SPI_SR_CRCERR;
36
      crcerror = 1;
37
    }
38
  }
39
  __enable_irq();
40
  while(SPI2->SR & SPI_SR_BSY);
41
  SPI2->CR1 &= ~SPI_CR1_SPE;  //  disable SPI
42
  return crcerror;
43
}

Hier bleibt er ab und zu bei "while(!(SPI2->SR & SPI_SR_RXNE));" hängen. Auf der bestückten Platine tut er das Ganze nicht. Kann das Ganze am Slave liegen? Oder übersehe ich irgendetwas, als Master sollte ja nach jedem Rausschicken auch irgendetwas im Empfangsregister sein.

Viele Grüße

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.