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 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.
Eine interessante Beobachtung von STM32Cube erstellte HAL-Dateien für stm32f103: Wenn SPI als Master konfiguriert ist, HAL_SPI_Receive
verwendet 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);
}
// ....
}
Chris Stratton