- /**
- * [url=home.php?mod=space&uid=247401]@brief[/url] Transmit and Receive an amount of data in blocking mode.
- * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
- * the configuration information for SPI module.
- * @param pTxData: pointer to transmission data buffer
- * @param pRxData: pointer to reception data buffer
- * @param Size: amount of data to be sent and received
- * @param Timeout: Timeout duration
- * @retval HAL status
- */
- HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size,
- uint32_t Timeout)
- {
- uint32_t tickstart = 0U;
- HAL_StatusTypeDef errorcode = HAL_OK;
- /* Check Direction parameter */
- assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction));
- /* Process Locked */
- __HAL_LOCK(hspi);
- /* Init tickstart for timeout management*/
- tickstart = HAL_GetTick();
- if (!((hspi->State == HAL_SPI_STATE_READY) || \
- ((hspi->Init.Mode == SPI_MODE_MASTER) && (hspi->Init.Direction == SPI_DIRECTION_2LINES) && (hspi->State == HAL_SPI_STATE_BUSY_RX))))
- {
- errorcode = HAL_BUSY;
- __HAL_UNLOCK(hspi);
- return errorcode;
- }
- if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
- {
- errorcode = HAL_ERROR;
- __HAL_UNLOCK(hspi);
- return errorcode;
- }
- /* Don't overwrite in case of HAL_SPI_STATE_BUSY_RX */
- if (hspi->State != HAL_SPI_STATE_BUSY_RX)
- {
- hspi->State = HAL_SPI_STATE_BUSY_TX_RX;
- }
- /* Set the transaction information */
- hspi->ErrorCode = HAL_SPI_ERROR_NONE;
- hspi->pRxBuffPtr = (uint8_t *)pRxData;
- hspi->RxXferCount = Size;
- hspi->RxXferSize = Size;
- hspi->pTxBuffPtr = (uint8_t *)pTxData;
- hspi->TxXferCount = Size;
- hspi->TxXferSize = Size;
- /*Init field not used in handle to zero */
- hspi->RxISR = NULL;
- hspi->TxISR = NULL;
- /* Set the number if data at current transfer */
- MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSIZE, Size);
- __HAL_SPI_ENABLE(hspi);
- if (hspi->Init.Mode == SPI_MODE_MASTER)
- {
- /* Master transfer start */
- SET_BIT(hspi->Instance->CR1, SPI_CR1_CSTART);
- }
- /* Transmit and Receive data in 32 Bit mode */
- if (hspi->Init.DataSize > SPI_DATASIZE_16BIT)
- {
- while ((hspi->TxXferCount > 0U) || (hspi->RxXferCount > 0U))
- {
- /* Check TXE flag */
- if ((hspi->TxXferCount > 0U) && (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE)))
- {
- *((__IO uint32_t *)&hspi->Instance->TXDR) = *((uint32_t *)hspi->pTxBuffPtr);
- hspi->pTxBuffPtr += sizeof(uint32_t);
- hspi->TxXferCount --;
- }
- /* Check RXWNE/EOT flag */
- if ((hspi->RxXferCount > 0U) && (hspi->Instance->SR & (SPI_FLAG_RXWNE|SPI_FLAG_EOT)))
- {
- *((uint32_t *)hspi->pRxBuffPtr) = *((__IO uint32_t *)&hspi->Instance->RXDR);
- hspi->pRxBuffPtr += sizeof(uint32_t);
- hspi->RxXferCount --;
- }
- if ((Timeout != HAL_MAX_DELAY) && ((HAL_GetTick() - tickstart) >= Timeout))
- {
- /* Call standard close procedure with error check */
- SPI_CloseTransfer(hspi);
- /* Process Unlocked */
- __HAL_UNLOCK(hspi);
- SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_TIMEOUT);
- hspi->State = HAL_SPI_STATE_READY;
- return HAL_ERROR;
- }
- }
- }
- /* Transmit and Receive data in 16 Bit mode */
- else if (hspi->Init.DataSize > SPI_DATASIZE_8BIT)
- {
- while ((hspi->TxXferCount > 0U) || (hspi->RxXferCount > 0U))
- {
- /* Check TXE flag */
- if ((hspi->TxXferCount > 0U) && (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE)))
- {
- if ( (hspi->TxXferCount > 1U) && (hspi->Init.FifoThreshold > SPI_FIFO_THRESHOLD_01DATA))
- {
- *((__IO uint32_t *)&hspi->Instance->TXDR) = *((uint32_t *)hspi->pTxBuffPtr);
- hspi->pTxBuffPtr += sizeof(uint32_t);
- hspi->TxXferCount-=2;
- }
- else
- {
- *((__IO uint16_t *)&hspi->Instance->TXDR) = *((uint16_t *)hspi->pTxBuffPtr);
- hspi->pTxBuffPtr += sizeof(uint16_t);
- hspi->TxXferCount--;
- }
- }
- /* Check RXWNE/FRLVL flag */
- if ((hspi->RxXferCount > 0U) && (hspi->Instance->SR & (SPI_FLAG_RXWNE|SPI_FLAG_FRLVL)))
- {
- if (hspi->Instance->SR & SPI_FLAG_RXWNE)
- {
- *((uint32_t *)hspi->pRxBuffPtr) = *((__IO uint32_t *)&hspi->Instance->RXDR);
- hspi->pRxBuffPtr += sizeof(uint32_t);
- hspi->RxXferCount-=2;
- }
- else
- {
- *((uint16_t *)hspi->pRxBuffPtr) = *((__IO uint16_t *)&hspi->Instance->RXDR);
- hspi->pRxBuffPtr += sizeof(uint16_t);
- hspi->RxXferCount--;
- }
- }
- if ((Timeout != HAL_MAX_DELAY) && ((HAL_GetTick() - tickstart) >= Timeout))
- {
- /* Call standard close procedure with error check */
- SPI_CloseTransfer(hspi);
- /* Process Unlocked */
- __HAL_UNLOCK(hspi);
- SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_TIMEOUT);
- hspi->State = HAL_SPI_STATE_READY;
- return HAL_ERROR;
- }
- }
- }
- /* Transmit and Receive data in 8 Bit mode */
- else
- {
- while ((hspi->TxXferCount > 0U) || (hspi->RxXferCount > 0U))
- {
- /* check TXE flag */
- if ((hspi->TxXferCount > 0U) && (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE)))
- {
- if ((hspi->TxXferCount > 3U) && (hspi->Init.FifoThreshold > SPI_FIFO_THRESHOLD_03DATA))
- {
- *((__IO uint32_t *)&hspi->Instance->TXDR) = *((uint32_t *)hspi->pTxBuffPtr);
- hspi->pTxBuffPtr += sizeof(uint32_t);
- hspi->TxXferCount-=4;
- }
- else if ((hspi->TxXferCount > 1U) && (hspi->Init.FifoThreshold > SPI_FIFO_THRESHOLD_01DATA))
- {
- *((__IO uint16_t *)&hspi->Instance->TXDR) = *((uint16_t *)hspi->pTxBuffPtr);
- hspi->pTxBuffPtr += sizeof(uint16_t);
- hspi->TxXferCount-=2;
- }
- else
- {
- *((__IO uint8_t *)&hspi->Instance->TXDR) = *((uint8_t *)hspi->pTxBuffPtr);
- hspi->pTxBuffPtr += sizeof(uint8_t);
- hspi->TxXferCount--;
- }
- }
- /* Wait until RXWNE/FRLVL flag is reset */
- if ((hspi->RxXferCount > 0U) && (hspi->Instance->SR & (SPI_FLAG_RXWNE|SPI_FLAG_FRLVL)))
- {
- if (hspi->Instance->SR & SPI_FLAG_RXWNE)
- {
- *((uint32_t *)hspi->pRxBuffPtr) = *((__IO uint32_t *)&hspi->Instance->RXDR);
- hspi->pRxBuffPtr += sizeof(uint32_t);
- hspi->RxXferCount-=4;
- }
- else if ((hspi->Instance->SR & SPI_FLAG_FRLVL) > SPI_FRLVL_QUARTER_FULL)
- {
- *((uint16_t *)hspi->pRxBuffPtr) = *((__IO uint16_t *)&hspi->Instance->RXDR);
- hspi->pRxBuffPtr += sizeof(uint16_t);
- hspi->RxXferCount-=2;
- }
- else
- {
- *((uint8_t *)hspi->pRxBuffPtr) = *((__IO uint8_t *)&hspi->Instance->RXDR);
- hspi->pRxBuffPtr += sizeof(uint8_t);
- hspi->RxXferCount--;
- }
- }
- if ((Timeout != HAL_MAX_DELAY) && ((HAL_GetTick() - tickstart) >= Timeout))
- {
- /* Call standard close procedure with error check */
- SPI_CloseTransfer(hspi);
- /* Process Unlocked */
- __HAL_UNLOCK(hspi);
- SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_TIMEOUT);
- hspi->State = HAL_SPI_STATE_READY;
- return HAL_ERROR;
- }
- }
- }
- /* Wait for Tx/Rx (and CRC) data to be sent/received */
- if (SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_EOT, RESET, tickstart, Timeout) != HAL_OK)
- {
- SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
- }
- /* Call standard close procedure with error check */
- SPI_CloseTransfer(hspi);
- /* Process Unlocked */
- __HAL_UNLOCK(hspi);
- hspi->State = HAL_SPI_STATE_READY;
- if (hspi->ErrorCode != HAL_SPI_ERROR_NONE)
- {
- return HAL_ERROR;
- }
- return HAL_OK;
- }
这是我从STM32H743的HALL库里面找出来的的SPI发送接收函数,从你进入函数开始到真正将数据开始送出,前面经历了多少校验和查询,这写都会导致时钟延时。下面我贴寄存器方式的你看看,除了定义一个局部变量,之后马上使能SPI,然后会等待一个发送区空,然后立马向数据寄存器写值,此时时钟开始响应,开始发送数据。
- u8 SPI2_ReadWriteByte(u8 TxData)
- {
- u8 RxData=0;
- SPI2->CR1|=1<<0; //SPE=1,使能SPI2
- SPI2->CR1|=1<<9; //CSTART=1,启动传输
-
- while((SPI2->SR&1<<1)==0); //等待发送区空
- *(vu8 *)&SPI2->TXDR=TxData; //发送一个byte,以传输长度访问TXDR寄存器
- while((SPI2->SR&1<<0)==0); //等待接收完一个byte
- RxData=*(vu8 *)&SPI2->RXDR; //接收一个byte,以传输长度访问RXDR寄存器
-
- SPI2->IFCR|=3<<3; //EOTC和TXTFC置1,清除EOT和TXTFC位
- SPI2->CR1&=~(1<<0); //SPE=0,关闭SPI2,会执行状态机复位/FIFO重置等操作
- return RxData; //返回收到的数据
- }
如果你想更快,初始化的时候就使能SPI,不检测发送区,直接给TXDR送数据,就会更快的让时钟起来。自己测试就知道了。还是那句话,HALL库只能保证你的代码安稳的运行,并检测出在哪出错,但是实时性巨差,是所有方式里面最慢的。如果向高速运行代码,要学会交叉使用,需要快速就自己写寄存器。其他初始化可以用HALL
|