Was ist der Zweck von HAL_SPI_TransmitReceive und wie funktioniert es?

Ich versuche zu verstehen, wie diese Funktion funktioniert, obwohl sich so viele Leute darüber beschweren. Meine Fragen sind diese:

1) Was ist der Unterschied zwischen der Verwendung in meinem Code:

HAL_SPI_Transmit (SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout)
HAL_SPI_Receive (SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout)

und das:

HAL_SPI_TransmitReceive (SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size, uint32_t Timeout)

Ich meine, wenn ich zuerst die Transmit- Funktion und dann unmittelbar danach die Receive- Funktion verwende, was ist der Unterschied, wenn ich nur TransmitReceive verwende ?

Das einzige Problem, das ich mir vorstellen kann, ist das Empfangen während des Sendens. Nehmen wir zum Beispiel an, ich möchte 4 Bytes an den Slave senden und von ihm 7 Bytes empfangen. Dann gibt es 2 Szenarien:

1. Szenario: Wenn mein Slave- Gerät Daten erst sendet , nachdem der Master alle seine Daten gesendet hat, was bedeutet, dass der Slave darauf wartet, dass der Master 4 Bytes sendet, und dann ( Slave ) beginnt, seine Daten zu senden, dann den Code that sollte funktionieren ist das

HAL_SPI_Transmit(&hspi1,txData,4,TIMEOUTVALUE);
HAL_SPI_Receive(&hspi1,rxData,7,TIMEOUTVALUE);

denn soweit ich mir vorstellen kann, beginnt TransmitReceive von Anfang an zu empfangen, also werden die ersten 4 Empfangsbytes Müll sein und die letzten 3 empfangenen werden die ersten 3 sein, die vom Slave gesendet werden ?

2. Szenario: Wenn mein Slave- Gerät Daten sendet, nachdem der Master nur das erste Byte seiner Daten gesendet hat , bedeutet dies, dass der Slave darauf wartet, dass der Master 1 Byte sendet, und dann beginnt er ( Slave ) mit dem Senden seiner Daten dann Der Code, der funktionieren sollte, ist der

HAL_SPI_TransmitReceive(&hspi1,txData,rxData,12,TIMEOUTVALUE);

(12 = 4 + 7 + ein Byte, das das erste empfangene Byte ist, das ein Dummy-Byte ist, weil der Slave zu senden beginnt, nachdem das 1. Byte vom Master gesendet wurde ).

2) Wie wird die Variable uint16_t Size in der TransmitReceive -Funktion verwendet? Wenn ich 4 Bytes senden und gleichzeitig 7 empfangen möchte, werde ich 11 in der Funktionsvariablen verwenden?

SPI ist bidirektional, die unidirektionalen Funktionen verschenken die Hälfte der Möglichkeiten. Sie sollten in der Lage sein, daraus zu entscheiden, welche Sie verwenden möchten. Natürlich können Sie immer die bidirektionale verwenden und Ihre eigenen Empfangsdaten verwerfen oder Dummy-Sendedaten bereitstellen.

Antworten (2)

SPI ist eine sehr spezifische Schnittstelle und der Slave kann nur senden, wenn der Master sendet. Sie müssen Dummy-Daten übertragen, um etwas zu empfangen.

Sie können also nicht 4 Bytes senden und 7 empfangen. Sie müssen so viele Daten senden, wie benötigt werden.

Auf jedes vom Master gesendete Byte sendet auch der Slave ein Byte. Wenn der Slave nach 4 empfangenen Bytes beginnt, wertvolle Daten zu senden, und Sie erwarten, 7 vom Slave zu erhalten, müssen Sie 11 Bytes senden.

Also in Szenario 2, wie viele Daten soll ich senden-empfangen

Eine interessante Beobachtung von STM32Cube erstellte HAL-Dateien für stm32f103: Wenn SPI als Master konfiguriert ist, HAL_SPI_Receiveverwendet es selbst HAL_SPI_TransmitReceive. Es sendet Müllbytes in pData (Puffer zum Empfangen von Bytes vom anderen Ende) als Dummy-Bytes.

HAL_StatusTypeDef HAL_SPI_Receive(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout)
{
  uint32_t tickstart;
  HAL_StatusTypeDef errorcode = HAL_OK;

  if ((hspi->Init.Mode == SPI_MODE_MASTER) && (hspi->Init.Direction == SPI_DIRECTION_2LINES))
  {
    hspi->State = HAL_SPI_STATE_BUSY_RX;
    /* Call transmit-receive function to send Dummy data on Tx line and generate clock on CLK line */
    return HAL_SPI_TransmitReceive(hspi, pData, pData, Size, Timeout);
  }

 // ....
}