STM32 HAL 库 SPI查询发送失败

问题遇到的现象和发生背景

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 配置生成

用回调函数