Estoy tratando de entender cómo funciona esta función a pesar de que hay tanta gente quejándose de ello. Mis preguntas son estas:
1) ¿Cuál es la diferencia entre usar esto en mi código:
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)
y esto:
HAL_SPI_TransmitReceive (SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size, uint32_t Timeout)
Quiero decir, si uso la función Transmitir primero y luego inmediatamente después, uso la función Recibir , ¿cuál es la diferencia con usar solo TransmitReceive ?
El único problema que se me ocurre es el de recibir mientras se envía. Por ejemplo, digamos que quiero enviar 4 bytes al Esclavo y recibir de él 7 bytes. Entonces hay 2 escenarios:
1er escenario: Si mi dispositivo Esclavo envía datos solo después de que el Maestro haya enviado todos sus datos, lo que significa que el Esclavo esperará que el Maestro envíe 4 bytes y luego ( Esclavo ) comenzará a enviar sus datos y luego el código que debería funcionar es el
HAL_SPI_Transmit(&hspi1,txData,4,TIMEOUTVALUE);
HAL_SPI_Receive(&hspi1,rxData,7,TIMEOUTVALUE);
porque, por lo que puedo pensar, TransmitReceive comenzará a recibir desde el principio, por lo que los primeros 4 bytes recibidos serán basura y los últimos 3 recibidos serán los primeros 3 transmitidos desde el Esclavo .
2do escenario: si mi dispositivo esclavo envía datos después de que el maestro haya enviado solo el primer byte de sus datos, lo que significa que el esclavo va a esperar que el maestro envíe 1 byte y luego ( esclavo ) comenzará a enviar sus datos entonces el código que debería funcionar es el
HAL_SPI_TransmitReceive(&hspi1,txData,rxData,12,TIMEOUTVALUE);
(12 = 4 + 7 + un byte que es el primer byte recibido, que es ficticio porque el esclavo comienza a transmitir después de que el maestro envía el primer byte ).
2) ¿Cómo se usa la variable de tamaño uint16_t en la función TransmitReceive ? Si quiero enviar 4 bytes y simultáneamente recibir 7, ¿voy a usar 11 en la variable de función?
SPI es una interfaz muy específica y el esclavo solo puede transmitir si el maestro transmite. Tienes que transmitir datos ficticios para recibir algo.
Por lo tanto, no puede enviar 4 bytes y recibir 7. Necesitará enviar tantos datos como sea necesario.
En cada byte enviado por el maestro, el esclavo también envía un byte. Si el esclavo comienza a enviar datos valiosos después de recibir 4 bytes y espera recibir 7 del esclavo, debe enviar 11 bytes.
Una observación interesante de STM32Cube creó archivos HAL para stm32f103: si SPI está configurado como maestro, HAL_SPI_Receive
usa HAL_SPI_TransmitReceive
. Envía bytes basura en pData (búfer para recibir bytes del otro extremo) como bytes ficticios.
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