STM32 HAL库 SPI查询发送函数的问题·
初始化函数调用如下
unsigned long device_open(void **handle, void *param)
{
unsigned long Ret;
delay_init();
Ret = spi_init(handle,param);
if(Ret !=SUCCESS)
{
return Ret;
}
Ret = cmd_rats_spi(*handle,param);
return Ret;
}
初始化函数如下
unsigned long spi_init(void **handle, void *param)
{
//spi³õʼ»¯ spiÖ÷½Ó¿ÚÐèÒªÅäÖÃÎªÍÆÍìģʽÉÏÀ£¬Êý¾Ý´óСÉèÖÃΪ8λ֡½á¹¹£¬MODE0ģʽ£¬Êý¾Ý´«Êä´ÓMSB¿ªÊ¼£¬´«ÊäËÙÂʲ»³¬18MHz¡£
//users define
SPI_HandleTypeDef *HEDSEspiHandle = *handle;
// unsigned char pdata = 0;
gpio_cs_init();
/* Set the SPI parameters */
(*HEDSEspiHandle).Instance = SPIx;
(*HEDSEspiHandle).Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4; //4
(*HEDSEspiHandle).Init.Direction = SPI_DIRECTION_2LINES;
(*HEDSEspiHandle).Init.CLKPhase = SPI_PHASE_1EDGE;
(*HEDSEspiHandle).Init.CLKPolarity = SPI_POLARITY_LOW;
(*HEDSEspiHandle).Init.DataSize = SPI_DATASIZE_8BIT;
(*HEDSEspiHandle).Init.FirstBit = SPI_FIRSTBIT_MSB;
(*HEDSEspiHandle).Init.TIMode = SPI_TIMODE_DISABLE;
(*HEDSEspiHandle).Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
(*HEDSEspiHandle).Init.CRCPolynomial = 7;
(*HEDSEspiHandle).Init.CRCLength = SPI_CRC_LENGTH_8BIT;
(*HEDSEspiHandle).Init.NSS = SPI_NSS_SOFT;
(*HEDSEspiHandle).Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
(*HEDSEspiHandle).Init.Mode = SPI_MODE_MASTER;
if(HAL_SPI_Init(HEDSEspiHandle) != HAL_OK)
{
/* Initialization Error */
return 0xff;
}
// HAL_SPI_Transmit((SPI_HandleTypeDef *)*handle, &pdata, 1, SPI_WAITTIME);
return E_SUCCESS;
}
返回值正常
发送函数调用如下
unsigned long spi_transmittx(void *handle, unsigned char* pdata,unsigned int data_len,unsigned int delay)
{
//users define
HAL_StatusTypeDef Ret;
ENSPICS;
delay_us(delay);
// while (handle->State = HAL_SPI_STATE_READY);
Ret = HAL_SPI_Transmit((SPI_HandleTypeDef *)handle, pdata, data_len, SPI_WAITTIME);
DISSPICS;
return Ret;
}
其中ENSPICS,DISSPICS为片选引脚高低电平置位变换
HAL库的发送函数如下
HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout)
{
#if defined (__GNUC__)
__IO uint16_t *ptxdr_16bits = (__IO uint16_t *)(&(hspi->Instance->TXDR));
#endif /* __GNUC__ */
uint32_t tickstart;
HAL_StatusTypeDef errorcode = HAL_OK;
/* Check Direction parameter */
assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE_2LINES_TXONLY(hspi->Init.Direction));
/* Lock the process */
__HAL_LOCK(hspi);
/* Init tickstart for timeout management*/
tickstart = HAL_GetTick();
if (hspi->State != HAL_SPI_STATE_READY)
{
errorcode = HAL_BUSY;
__HAL_UNLOCK(hspi);
return errorcode;
}
if ((pData == NULL) || (Size == 0UL))
{
errorcode = HAL_ERROR;
__HAL_UNLOCK(hspi);
return errorcode;
}
/* Set the transaction information */
hspi->State = HAL_SPI_STATE_BUSY_TX;
hspi->ErrorCode = HAL_SPI_ERROR_NONE;
hspi->pTxBuffPtr = (uint8_t *)pData;
hspi->TxXferSize = Size;
hspi->TxXferCount = Size;
/*Init field not used in handle to zero */
hspi->pRxBuffPtr = NULL;
hspi->RxXferSize = (uint16_t) 0UL;
hspi->RxXferCount = (uint16_t) 0UL;
hspi->TxISR = NULL;
hspi->RxISR = NULL;
/* Configure communication direction : 1Line */
if (hspi->Init.Direction == SPI_DIRECTION_1LINE)
{
SPI_1LINE_TX(hspi);
}
/* Set the number of data at current transfer */
MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSIZE, Size);
/* Enable SPI peripheral */
__HAL_SPI_ENABLE(hspi);
if (hspi->Init.Mode == SPI_MODE_MASTER)
{
/* Master transfer start */
SET_BIT(hspi->Instance->CR1, SPI_CR1_CSTART);
}
/* Transmit data in 32 Bit mode */
if (hspi->Init.DataSize > SPI_DATASIZE_16BIT)
{
/* Transmit data in 32 Bit mode */
while (hspi->TxXferCount > 0UL)
{
/* Wait until TXP flag is set to send data */
if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXP))
{
*((__IO uint32_t *)&hspi->Instance->TXDR) = *((uint32_t *)hspi->pTxBuffPtr);
hspi->pTxBuffPtr += sizeof(uint32_t);
hspi->TxXferCount--;
}
else
{
/* Timeout management */
if ((((HAL_GetTick() - tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U))
{
/* Call standard close procedure with error check */
SPI_CloseTransfer(hspi);
/* Unlock the process */
__HAL_UNLOCK(hspi);
SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_TIMEOUT);
hspi->State = HAL_SPI_STATE_READY;
return HAL_TIMEOUT;
}
}
}
}
/* Transmit data in 16 Bit mode */
else if (hspi->Init.DataSize > SPI_DATASIZE_8BIT)
{
/* Transmit data in 16 Bit mode */
while (hspi->TxXferCount > 0UL)
{
/* Wait until TXP flag is set to send data */
if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXP))
{
if ((hspi->TxXferCount > 1UL) && (hspi->Init.FifoThreshold > SPI_FIFO_THRESHOLD_01DATA))
{
*((__IO uint32_t *)&hspi->Instance->TXDR) = *((uint32_t *)hspi->pTxBuffPtr);
hspi->pTxBuffPtr += sizeof(uint32_t);
hspi->TxXferCount -= (uint16_t)2UL;
}
else
{
#if defined (__GNUC__)
*ptxdr_16bits = *((uint16_t *)hspi->pTxBuffPtr);
#else
*((__IO uint16_t *)&hspi->Instance->TXDR) = *((uint16_t *)hspi->pTxBuffPtr);
#endif /* __GNUC__ */
hspi->pTxBuffPtr += sizeof(uint16_t);
hspi->TxXferCount--;
}
}
else
{
/* Timeout management */
if ((((HAL_GetTick() - tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U))
{
/* Call standard close procedure with error check */
SPI_CloseTransfer(hspi);
/* Unlock the process */
__HAL_UNLOCK(hspi);
SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_TIMEOUT);
hspi->State = HAL_SPI_STATE_READY;
return HAL_TIMEOUT;
}
}
}
}
/* Transmit data in 8 Bit mode */
else
{
while (hspi->TxXferCount > 0UL)
{
/* Wait until TXP flag is set to send data */
if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXP))
{
if ((hspi->TxXferCount > 3UL) && (hspi->Init.FifoThreshold > SPI_FIFO_THRESHOLD_03DATA))
{
*((__IO uint32_t *)&hspi->Instance->TXDR) = *((uint32_t *)hspi->pTxBuffPtr);
hspi->pTxBuffPtr += sizeof(uint32_t);
hspi->TxXferCount -= (uint16_t)4UL;
}
else if ((hspi->TxXferCount > 1UL) && (hspi->Init.FifoThreshold > SPI_FIFO_THRESHOLD_01DATA))
{
#if defined (__GNUC__)
*ptxdr_16bits = *((uint16_t *)hspi->pTxBuffPtr);
#else
*((__IO uint16_t *)&hspi->Instance->TXDR) = *((uint16_t *)hspi->pTxBuffPtr);
#endif /* __GNUC__ */
hspi->pTxBuffPtr += sizeof(uint16_t);
hspi->TxXferCount -= (uint16_t)2UL;
}
else
{
*((__IO uint8_t *)&hspi->Instance->TXDR) = *((uint8_t *)hspi->pTxBuffPtr);
hspi->pTxBuffPtr += sizeof(uint8_t);
hspi->TxXferCount--;
}
}
else
{
/* Timeout management */
if ((((HAL_GetTick() - tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U))
{
/* Call standard close procedure with error check */
SPI_CloseTransfer(hspi);
/* Unlock the process */
__HAL_UNLOCK(hspi);
SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_TIMEOUT);
hspi->State = HAL_SPI_STATE_READY;
return HAL_TIMEOUT;
}
}
}
}
/* Wait for Tx (and CRC) data to be sent */
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);
/* Unlock the process */
__HAL_UNLOCK(hspi);
hspi->State = HAL_SPI_STATE_READY;
if (hspi->ErrorCode != HAL_SPI_ERROR_NONE)
{
return HAL_ERROR;
}
return errorcode;
}
根据DEBUG调试跟进发现 ,每次都卡在如下位置返回错误
if (hspi->State != HAL_SPI_STATE_READY)
{
errorcode = HAL_BUSY;
__HAL_UNLOCK(hspi);
return errorcode;
}
if ((pData == NULL) || (Size == 0UL))
{
errorcode = HAL_ERROR;
__HAL_UNLOCK(hspi);
return errorcode;
}
可以使用ST提供的例程对比,再就是确认SPI 相关的引脚是否正确初始化,一般在:xxx_msp.c 中定义,可以使用STM32CubeMX 配置生成
用回调函数