Forum: Mikrocontroller und Digitale Elektronik STM32G0 SPI RXNE hängt sporadisch


von Christoph S. (mr9000)


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

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.