Forum: Mikrocontroller und Digitale Elektronik STM32 HAL_SPI_TransmitReceive: Warum wird transmitData geändert?


von Holger T. (holger1979)


Lesenswert?

Hallo,

wenn ich beim STM32F2 mit der Funktion HAL_SPI_TransmitReceive() Daten 
versende, dann ist transmitData anschließend nicht mehr mit den Daten 
versehen, die vorher drin standen, sondern die sind leer oder aber 
vereinzelt sind andere Werte vorhanden.

Was hat es damit auf sich? Warum wird hier überhaupt der Puffer geleert 
und warum steht manchmal ein Wert drin?

Vielen Dank und viele Grüße!

von Jojo S. (Gast)


Lesenswert?

Die Antwort steht doch schon im Funktionsnamen...

von Arsch N. (arschnelson)


Lesenswert?

Wieso benutzt du HAL_SPI_TransmitReceive()? Willst du senden oder 
empfangen?

von Dr. Pinguin (Gast)


Lesenswert?

Arsch N. schrieb:
> Wieso benutzt du HAL_SPI_TransmitReceive()? Willst du senden oder
> empfangen?

Was könnte er mit "wenn ich beim STM32F2 mit der Funktion 
HAL_SPI_TransmitReceive() Daten versende" wohl gemeint haben?


Aber Hauptsache, mal irgendwelchen Blödsinn posten....

von Ingo L. (corrtexx)


Lesenswert?

Holger T. schrieb:
> wenn ich beim STM32F2 mit der Funktion HAL_SPI_TransmitReceive() Daten
> versende, dann ist transmitData anschließend nicht mehr mit den Daten
> versehen, die vorher drin standen, sondern die sind leer oder aber
> vereinzelt sind andere Werte vorhanden.
Wie funktioniert SPI? Da stelle ma uns ma ganz blöde:
Du packst etwas in das "SPI-Register". Dann drückst du auf "Senden". In 
dem Moment sendest du deine Daten und empfängst gleichzeitig die Daten 
vom Slave.

Guckst du:
https://www.mikrocontroller.net/articles/Serial_Peripheral_Interface

@Arsch Nelson
Du solltest auch gleich mal lesen ;)

von Stefan K. (stefan64)


Lesenswert?

Für alle, die hier posten, ohne die HAL_SPI_TransmitReceive auch nur 
einmal gesehen zu haben:
1
/**
2
  * @brief  Transmit and Receive an amount of data in blocking mode 
3
  * @param  hspi: pointer to a SPI_HandleTypeDef structure that contains
4
  *                the configuration information for SPI module.
5
  * @param  pTxData: pointer to transmission data buffer
6
  * @param  pRxData: pointer to reception data buffer to be
7
  * @param  Size: amount of data to be sent
8
  * @param  Timeout: Timeout duration
9
  * @retval HAL status
10
  */
11
HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size, uint32_t Timeout)
Für Transmit und Receive sind 2 GETRENNTE Buffer vorhanden.

@TS:
Mit welchen Parametern rufst Du HAL_SPI_TransmitReceive() auf? Ist 
dichergestellt, dass beide Buffer groß genug sind? Wie wurde hspi 
initialisiert? 8 oder 16 Bit Zugriff?

Gruß, Stefan

von Holger T. (holger1979)


Lesenswert?

Hallo Stefan K,

als Parameter verwende ich zwei Strukts, welche jeweils ein Bytefeld 
enthalten.

Als ersten Parameter: &hspi3
Als zweiten Parameter: transmit.data
Als dritten Parameter: receive.data
Als vierten Parameter: size

Demnach sollte es stimmen.

Masterseite verwendet HAL_SPI_TransmitReceive()
und Slave verwendet HAL_SPI_TransmitReceive_IT()

Nach der Übertragung steht in beiden Receivepuffern die erwartete 
Nachricht.
Lediglich der Transmitpuffer des Masters ist dann entweder leer oder 
aber enthält einzelne Werte, die auch mal von 0 abweichen.

Die Datenbreite habe ich als 8 Bit gewählt.
Die Felder sind jeweils 16 Byte groß. Sowohl Senden als auch Empfangen.

Als Bestätigung sende ich ein einzelnes Byte zurück per
HAL_SPI_Transmit und HAL_SPI_Receive. So wie es aussieht, kommt dann der 
HAL_Treiber damit nicht zurecht und ändert dann die Transmitadresse, die 
ich beim HAL_SPI_TransmitReceive zuvor verwendet habe.

Ein Ersetzen aller Transmit und Receive durch TransmitReceive beseitigt 
den Fehler.

Ist anscheinend ein Bug in den HAL-Treibern

von W.S. (Gast)


Lesenswert?

Holger T. schrieb:
> als Parameter verwende ich zwei Strukts, welche jeweils ein Bytefeld
> enthalten.

Ich geb dir einen guten Rat: Schmeiß die gesamte ST-Lib von deinem 
Rechner, lies das refMan damit du die HW verstehen lernst und mache dir 
deine eigenen Treiber für die Peripherie, die du gebrauchen willst.

W.S.

von Jojo S. (Gast)


Lesenswert?

Holger T. schrieb:
> Ist anscheinend ein Bug in den HAL-Treibern

da wäre ich skeptisch.

> HAL_SPI_Transmit und HAL_SPI_Receive. So wie es aussieht, kommt dann der
> HAL_Treiber damit nicht zurecht und ändert dann die Transmitadresse, die
> ich beim HAL_SPI_TransmitReceive zuvor verwendet habe.

Die Quellen von HAL_SPI_Transmit() kann man ja ansehen (oder sogar 
debuggen). Darin sehe ich zumindest keine Schreibzugriffe auf den 
TxBuffer. Der übergebene Pointer für den TxBuffer wird in 
hspi->pTxBuffPtr zwischengespeichert und der steht dann (dereferenziert) 
immer rechts vom Gleichheitszeichen, es wird also nur lesend auf den 
Buffer zugegriffen.
Da bleibt der Verdacht das der TxBuffer durch eine andere Funktion 
(Receive mit zu kleiner buffsize?) kaputtgeschrieben wird.

von Holger T. (holger1979)


Lesenswert?

Hallo,

bei der Verwendung von HAL_SPI_Receive_IT wird auch automatisch 
HAL_SPI_TransmitReceive_IT aufgerufen.

Hier wird zumindest beim Empfangen genau das als Dummy gesendet, was im 
Empfangspuffer vor dem aufrufen der Funktion drin stand.

Ich habe auf jeden Fall jetzt alle Transmit und Receive durch 
TransmitReceive ersetzt (Auf Master und Slave Seite). Da kann ich 
zumindest noch die Dummybytes setzen und schauen, ob die auf der anderen 
Seite richtig ankommen. Die Pakete sind dann auch in Ordnung.

Und einen Mehraufwand auf den Leitungen gibt es dadurch ja auch nicht, 
weil die Daten ja sowieso in beide Richtungen gehen.

von Holger T. (holger1979)


Lesenswert?

Lösung gefunden!

Während ich empfange kann gesendet werden.
Während ich sende kann empfangen werden.

Habe mich an ein Beispiel aus einer Vorlesung erinnert mit zwei 
Eisenbahnen die über eine Kreuzung fahren mussten. Die gute, alte 
Semaphore.

Wenn ich das Eine blockiere, wenn das jeweils Andere aktiv ist, dann 
läuft es plötzlich.   ;)

Da kommt man aber auch nicht drauf...

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.