Forum: Mikrocontroller und Digitale Elektronik SPI-Kommunikation mit STM32F2xx


von Entwickler (Gast)


Lesenswert?

Guten Abend,

ich seit einiger Zeit ein Problem mit der SPI-Kommunikation. Für die 
SPI-Kommunikation verwende ich dazu den DMA für das Senden und 
Empfangen. Ein SPI-Frame ist 16bit breit. Dieser Mikrocontroller ist der 
Master. Zuerst sende ich ein Kommando (2 16bit SPI-Frames) an den Slave. 
Der Slave empfangt das Kommando und löst auf dem Master einen Interrupt 
aus. Daraufhin sendet der Master so lange 2 16bit SPI-Frames mit 
Dateninhalt 0, bis der Slave keine Daten mehr sendet. Der DMA für das 
Senden und Empfangen benutzt jeweils ein 2 16bit Array. Wenn ich zuerst 
das Kommando sende, dann wird auch ein Interrupt (initiiert vom SLave) 
auf dem Master ausgelöst. Nun steht aber beim ersten empfangenen 16bit 
SPI-Frame nicht der gewünscht Inhalt drin. Ist auch verständlich, da die 
SPI seriell wie ein Schieberegister die Daten von A nach B durchreicht. 
Was kann ich da tun, damit im ersten empfangen Wert der korrekte Wert 
drinsteht ? Mit dieser Zeile "SPIx->DR;" funktioniert dies auch nicht.

von holger (Gast)


Lesenswert?

Bitte noch mal erklären mit Flussdiagramm. Dort einzeichnen
wann der Master was sendet und an welcher Stelle das Problem ist.

von Moritz M. (avrprogger)


Lesenswert?

Hallo,

guck mal hier vllt. : http://www.diller-technologies.de/stm32.html

Moritz

von Entwickler (Gast)


Lesenswert?

Hallo, vielen Dank für eure Rückmeldungen. Das eigentliche Problem tritt 
beim ersten empfangenen 16bit SPI-Frame auf. Danach wird vom Slave ein 
Interrupt auf dem STM32 (Master) ausgelöst. In diesem Interrupt werden 
dann 2 16bit SPI-Frames mit Dateninhalt 0 an den Slave gesendet. Der 
Slave antwortet indem dieser seriell die Daten rausschiebt. Im 
RxDMA-Interrupt-Handler werden die Daten empfangen und in einem Puffer 
abgelegt. Genau da ist auch das Problem, sobald zum erstenmal der 
Rx-Interrupt-Handler auf dem Master ausgeköst wird. Das erste SPI-Frame 
(16bit) ist nicht der zu erwartende Dateninhalt. Dies rührt noch vom 
zuvor gesendete Kommando (2 16bit SPI-Frames). Wie kann nun der RxBuffer 
vom SPI-Interface nachdem das Kommando gesendet wird komplett gelöscht 
werden ?

von Entwickler (Gast)


Angehängte Dateien:

Lesenswert?

Guten Morgen,

im Anhang ist der Inhalt vom ReceiveBuffer zu sehen.
Eigentlich sollten die Daten ab dem ersten Element gespeichert sein.

ReceiveBuffer[0] <-- 0x0000005E
ReceiveBuffer[1] <-- 0x00004000

Nachdem der RxDMA aktiviert wird, ist der erste empfangen 16bit Wert 
nicht 0x0000005E sondern 0x00000000.
1
SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Rx, ENABLE);
Wie kann ich dieses Problem lösen ?

von Entwickler (Gast)


Lesenswert?

Nachtrag:Dies passiert nachdem die 2 16bit Werte(Kommando) gesendet 
wurden.

von Entwickler (Gast)


Lesenswert?

Wie kann der erste 16bit Wert im RxBuffer, nach dem Senden eines 
Kommandos (2x16bit) ignoriert werden ? Das ist das einzige Problem.

von holger (Gast)


Lesenswert?

>Wie kann der erste 16bit Wert im RxBuffer, nach dem Senden eines
>Kommandos (2x16bit) ignoriert werden ?

Nimm den UART und schieb damit die ersten beiden Bytes aus dem Gehäuse.
Dann sind sie weg und stören nicht mehr;)

SCNR

von Entwickler (Gast)


Lesenswert?

Danke holger für deine Hilfestellung. Was meinst du genau ?

von Entwickler (Gast)


Lesenswert?

Folgender Ablauf findet auf dem Matser (STM32) statt. Zuerst sende ich 
eine Kommando, bestehend aus 2 16bit SPI-Frames. Danach wird durch den 
Slave ein Interrupt (External-Interrupt-Handler) ausgelöst. In diesem 
Interrupt sende ich dann ebenfalls 2 16bit SPI-Frames, allerdings mit 
Dateninhalt 0. Daraufhin sendet der Slave seine Daten und im 
RxDmaInterrupt (DMA1_Stream3_IRQHandler) kann ich 2 16SPI-Frames 
empfangen und in einen BPuffer speichern.

von Entwickler (Gast)


Lesenswert?

Ich habe auch folgendes schon ohne Erfolg getestet:
1
void EXTI15_10_IRQHandler(void) // External-Interrupt-Handler (Master){      
2
  if(EXTI_GetITStatus(EXTI_Line15) != RESET)
3
  {   
4
    /* Clear the EXTI line 15 pending bit */
5
    EXTI_ClearITPendingBit(EXTI_Line15);         
6
        
7
    if(Flag == 1)
8
    {
9
      Flag = 0;
10
      SPIx->DR;
11
    }
12
    
13
    SPI_MASTER_Buffer_Tx[0] = 0;
14
    SPI_MASTER_Buffer_Tx[1] = 0;
15
    
16
    SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, DISABLE);
17
    SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Rx, DISABLE);
18
    DMA_Config();
19
    SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, ENABLE);
20
    SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Rx, ENABLE); 
21
  }
22
}

Wenn ich diese Zeile am Anfang ausführe, werden zwar die Daten korrekt 
gesendet, allerdings funktioniert der Empfang nicht mehr. Es werden 
keine Daten vom Master empfangen.

von Entwickler (Gast)


Lesenswert?

Gibt es für mein Problem keine Lösung ?

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.