Forum: Mikrocontroller und Digitale Elektronik STM32 Probleme mit SPI Kommunikation zwischen Master und Slave


von Holger T. (holger1979)


Lesenswert?

Hallo,

ich habe ein Problem mit der Kommunikation zweier STM32F2 mit SPI.
Ich habe einen Master und einen Slave. NSS habe ich in CubeMX auf 
Hardware eingestellt.

Hier die Konfiguration:

Master:
1
  hspi3.Instance = SPI3;
2
  hspi3.Init.Mode = SPI_MODE_MASTER;
3
  hspi3.Init.Direction = SPI_DIRECTION_2LINES;
4
  hspi3.Init.DataSize = SPI_DATASIZE_8BIT;
5
  hspi3.Init.CLKPolarity = SPI_POLARITY_HIGH;
6
  hspi3.Init.CLKPhase = SPI_PHASE_1EDGE;
7
  hspi3.Init.NSS = SPI_NSS_HARD_OUTPUT;
8
  hspi3.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64;
9
  hspi3.Init.FirstBit = SPI_FIRSTBIT_MSB;
10
  hspi3.Init.TIMode = SPI_TIMODE_DISABLED;
11
  hspi3.Init.CRCCalculation = SPI_CRCCALCULATION_ENABLED;
12
  hspi3.Init.CRCPolynomial = 10;
13
  HAL_SPI_Init(&hspi3);

Slave:
1
  hspi3.Instance = SPI3;
2
  hspi3.Init.Mode = SPI_MODE_SLAVE;
3
  hspi3.Init.Direction = SPI_DIRECTION_2LINES;
4
  hspi3.Init.DataSize = SPI_DATASIZE_8BIT;
5
  hspi3.Init.CLKPolarity = SPI_POLARITY_HIGH;
6
  hspi3.Init.CLKPhase = SPI_PHASE_1EDGE;
7
  hspi3.Init.NSS = SPI_NSS_HARD_OUTPUT;
8
  hspi3.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32;
9
  hspi3.Init.FirstBit = SPI_FIRSTBIT_MSB;
10
  hspi3.Init.TIMode = SPI_TIMODE_DISABLED;
11
  hspi3.Init.CRCCalculation = SPI_CRCCALCULATION_ENABLED;
12
  hspi3.Init.CRCPolynomial = 10;
13
  HAL_SPI_Init(&hspi3);

Der Slave macht direkt zum Start ein TransmitReceive_IT
Der Master sendet irgendwann per TransmitReceive 16 byte zum Slave.
Die Daten kommen auf der Slave-Seite gut an und auch der Master empfängt 
die am Anfang
fest abgelegte Information.

PROBLEM 1:
Der Slave geht in den HAL_SPITxRxCpltCallback. Dort ist 
HAL_SPI_GetError() HAL_SPI_ERROR_NONE was ja auch gut ist. Jedoch 
liefert der Aufruf HAL_SPI_GetState() entweder 0x20 oder 0xe0. Beide 
Werte sind nicht im entsprechenden enum HAL_SPI_StateTypeDef zu finden.

Jetzt geht es weiter. Der Slave ist zufrieden und schickt ein einzelnes 
Byte als Empfangsbestätigung an den Master zurück. Dafür macht der Slave 
ein Transmit_IT und zieht einen Pin runter.

Problem 2:
Transmit_IT blockiert, was es nicht tun sollte. Daher habe ich zuerst 
den Pin runtergezogen, dann Transmit_IT aufgerufen und der Master wartet 
nach dem Pinwechsel jetzt 10us.

Und weiter gehts. Der Master merkt, dass der Pin runtergezogen wird und 
macht ein Receive (Nach den erwähnten 10us). Das Byte kommt richtig an. 
Der Slave startet ein neues TransmitReceive_IT und setzt den Pin wieder 
zurück. Der Master erkennt das Pin Rücksetzen und fährt daraufhin fort, 
die nächsten Daten zu senden.

Datensatz 2 wird gesendet. Es sind keine Errors mehr da und der State 
ist beim Master aud Ready und beim Slave auf BusyTxRx, weil er ja auf 
neue Daten wartet.

Problem 3:
Wieder ist wie nach dem Senden der SPI_State auf 0x20 oder 0xe0 auf 
Slave Seite???

Problem 4:
Die im Master gesendeten Daten a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p
kommen so beim Slave an:       0,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o

Meine erste Überlegung: Der Slave war noch nicht bereit. Aber dann hätte 
der Empfang bei b angefangen oder alle bits wären verschoben und der 
HAL_SPI_TxRxCpltCallback wäre nicht aufgerufen worden, weil die 16 byte 
nicht erreicht worden wären.

Weiter liefert HAL_SPI_GetError() ein HAL_SPI_ERROR_NONE.
Warum ist hier nicht zumindest ein CRC Fehler?
Demnach müssen die Daten ja richtig angekommen sein.
Aber warum stehen sie dann nicht im Empfangspuffer?

Hier der Aufruf beim Master:
1
HAL_SPI_TransmitReceive(&hspi3, transmitData.data, receiveData.data, MessageSize, 1000);

Hier der am Anfang stehende Aufruf beim Slave:
1
HAL_SPI_TransmitReceive_IT(&hspi3, transmitData.data, receiveData.data, MessageSize);

Wer kann mir zu den Problemen 1-4 weiterhelfen?

Vielen Dank!

von Marc (Gast)


Lesenswert?

Hallo,
ein bisschen "Off Topic"
Das Problem ist im Zweifel, das du "nicht siehst" was auf dem Bus 
passiert.
Ich empfehle einen Bus Analyser.

Beispiel so 
etwas:http://www.nkcelectronics.com/zeroplus-lap16032u-logic-ana16032.html

Gruß

von Holger T. (holger1979)


Lesenswert?

Hallo Marc,

das wäre natürlich die optimale Fehlersuche.
Leider sind beide Prozessoren auf der Rückseite einer Platine,
die feste in einem Gehäuse sitzt.

Es ist tatsächlich ein Problem, wenn man die Kommunikation nicht 
nachvollziehen kann. Leider komme ich mit dem Logic Analyzer nicht dran.
:-(

von Marc (Gast)


Lesenswert?

Hallo,
"NSS habe ich in CubeMX auf
Hardware eingestellt."

Einfach mal die Software Variante versuchen ;-) ??
Oder:

Den Bustakt vermindern und prüfen das die Clock Einstellungen auf beiden 
Controllern (zumondest für den Bus" gleich sind.

Gruß.

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.