首页 > 解决方案 > 在 stm32MP1 上以 DMA 模式通过 SPI 发送数据

问题描述

我正在尝试在 STM32MP157C-DK2 板上以 DMA 模式通过 SPI 发送数据。目标是将数据从 GPIO_PIN_8 发送到 GPIO_PIN_9 并检查它们是否相同。

我尝试使用 HAL_SPI_TransmitReceive_DMA 函数,但我不确定它是如何工作的。它将发送缓冲区和接收缓冲区作为输入。但是如何告诉我想从引脚 8(MOSI)发送到引脚 9(MISO)的功能。以及如何查看和显示我发送的数据并检查它是否在另一个引脚上正确接收。

我是否必须为发送接收功能提供 GPIOS 地址而不是 TX 和 RX 缓冲区?但是如何告诉函数我要发送的数据。

我将 GPIOS 和 SPI5 配置如下:

#define BUFSIZE 1024
#define GPIOF_OutPut_Data   (0x40010028)
#define GPIOF_Input_Data    (0x44009000)+(0x30)
 enum
{
    TRANSFER_WAIT,
    TRANSFER_COMPLETE,
    TRANSFER_ERROR
};       
/* Buffer used for transmission */
uint8_t aTxBuffer[] = "****SPI Message based on DMA ****";
/* Buffer used for reception */
uint8_t aRxBuffer[BUFSIZE];
/* transfer state */
__IO uint32_t wTransferState = TRANSFER_WAIT;
SPI_HandleTypeDef hspi5;
        DMA_HandleTypeDef hdma_spi5_tx;
        DMA_HandleTypeDef hdma_spi5_rx;
    void SystemClock_Config(void);
    static void MX_GPIO_Init(void);
    static void MX_DMA_Init(void);
    static void MX_IPCC_Init(void);
    static void MX_SPI5_Init(void);
    static uint16_t Buffercmp(uint8_t *pBuffer1, uint8_t *pBuffer2, uint16_t BufferLength);
    int main(void)
    {
     MX_GPIO_Init();
      MX_DMA_Init();
      MX_SPI5_Init();
    /**SPI5 GPIO Configuration
      PH6     ------> SPI5_SCK
      PF8     ------> SPI5_MISO
      PF9     ------> SPI5_MOSI
      */
      GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_8|GPIO_PIN_9;
      GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
      GPIO_InitStruct.Pull = GPIO_NOPULL;
      GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
      GPIO_InitStruct.Alternate = GPIO_AF5_SPI5;
      // From Alternate Function Table from Data-sheet for Port F
      HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
          //Transmit and Receive Data over SPI in DMA Mode

         if(HAL_SPI_TransmitReceive_DMA(&hspi5, (uint8_t*)aTxBuffer, (uint8_t *)aRxBuffer, BUFSIZE) != HAL_OK)
           {
             /* Transfer error in transmission process */
             printf("Entered Transmit Receive DMA Mode");
             Error_Handler();
           }

           /*##-2- Wait for the end of the transfer ###################################*/
           /*  Before starting a new communication transfer, you must wait the callback call
               to get the transfer complete confirmation or an error detection.
               This code is just waiting till the end of the
               transfer, but application may perform other tasks while transfer operation
               is ongoing. */
           while (wTransferState == TRANSFER_WAIT)
           {
           }

           switch(wTransferState)
           {
             case TRANSFER_COMPLETE :
               /*##-3- Compare the sent and received buffers ##############################*/
               if(Buffercmp((uint8_t*)aTxBuffer, (uint8_t*)aRxBuffer, BUFSIZE))
                   //if buffers are identical, the return value should be 0, otherwise go to Error handler
               {
                 /* Processing Error */

                   Error_Handler();
               }
             break;
             default :
               Error_Handler();
             break;
           }
    }
    static void MX_SPI5_Init(void)
    {

      /* USER CODE BEGIN SPI5_Init 0 */

      /* USER CODE END SPI5_Init 0 */

      /* USER CODE BEGIN SPI5_Init 1 */

      /* USER CODE END SPI5_Init 1 */
      /* SPI5 parameter configuration*/
      hspi5.Instance = SPI5;
      hspi5.Init.Mode = SPI_MODE_MASTER;
      hspi5.Init.Direction = SPI_DIRECTION_2LINES;
      hspi5.Init.DataSize = SPI_DATASIZE_16BIT;
      hspi5.Init.CLKPolarity = SPI_POLARITY_LOW;
      hspi5.Init.CLKPhase = SPI_PHASE_1EDGE;
      hspi5.Init.NSS = SPI_NSS_SOFT;
      hspi5.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64;
      hspi5.Init.FirstBit = SPI_FIRSTBIT_MSB;
      hspi5.Init.TIMode = SPI_TIMODE_DISABLE;
      hspi5.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
      hspi5.Init.CRCPolynomial = 0x0;
      hspi5.Init.NSSPMode = SPI_NSS_PULSE_ENABLE;
      hspi5.Init.NSSPolarity = SPI_NSS_POLARITY_LOW;
      hspi5.Init.FifoThreshold = SPI_FIFO_THRESHOLD_01DATA;
      hspi5.Init.TxCRCInitializationPattern = SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN;
      hspi5.Init.RxCRCInitializationPattern = SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN;
      hspi5.Init.MasterSSIdleness = SPI_MASTER_SS_IDLENESS_00CYCLE;
      hspi5.Init.MasterInterDataIdleness = SPI_MASTER_INTERDATA_IDLENESS_00CYCLE;
      hspi5.Init.MasterReceiverAutoSusp = SPI_MASTER_RX_AUTOSUSP_DISABLE;
      hspi5.Init.MasterKeepIOState = SPI_MASTER_KEEP_IO_STATE_DISABLE;
      hspi5.Init.IOSwap = SPI_IO_SWAP_DISABLE;
      if (HAL_SPI_Init(&hspi5) != HAL_OK)
      {
        Error_Handler();
      }
      /* USER CODE BEGIN SPI5_Init 2 */

      /* USER CODE END SPI5_Init 2 */

    }
    void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi)
    {
      wTransferState = TRANSFER_ERROR;
    }

    /**
      * @brief  Compares two buffers.
      * @param  pBuffer1, pBuffer2: buffers to be compared.
      * @param  BufferLength: buffer's length
      * @retval 0  : pBuffer1 identical to pBuffer2
      *         >0 : pBuffer1 differs from pBuffer2
      */
    static uint16_t Buffercmp(uint8_t* pBuffer1, uint8_t* pBuffer2, uint16_t BufferLength)
    {
      while (BufferLength--)
      {
        if((*pBuffer1) != *pBuffer2)
        {
          return BufferLength;
        }
        pBuffer1++;
        pBuffer2++;
      }

      return 0;
    }

    void Error_Handler(void)
    {
      /* USER CODE BEGIN Error_Handler_Debug */
      /* User can add his own implementation to report the HAL error return state */
    printf("No Transfer of Data");
      while(1)
         {
             setvbuf (stdout, NULL, _IONBF, 0);
             fprintf(stdout, "LED7 is blinking");
             Delay_wait(0x5000000);
             HAL_GPIO_TogglePin(GPIOH, GPIO_PIN_7);

         }
      /* USER CODE END Error_Handler_Debug */
    }

标签: cstm32

解决方案


推荐阅读