STM32
直播中

刘辉

8年用户 1161经验值
私信 关注
[问答]

STM32G070的SPI CRC 16位校验功能使用DMA方式传输,数据接收发生错误的原因?

使用SPI CRC校验功能,DMA发送和接收,如果是CRC 8位校验没有问题,改成16位就发生接收数据错误,跟踪调试是进入到SPI_DMAReceiveCplt函数执行到SPI_WaitFlagStateUntilTimeout判断RXNE标志没有置起,记录为CRC错误


有谁用过这个功能吗?求指点!!!

if (hspi->Init.CRCLength == SPI_CRC_LENGTH_16BIT)
        {
          if (SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_RXNE, SET, SPI_DEFAULT_TIMEOUT, tickstart) != HAL_OK)
          {
            /* Error on the CRC reception */
            SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
          }
          /* Read 8bit CRC again in case of 16bit CRC in 8bit Data mode */
          READ_REG(*(__IO uint8_t *) hspi->Instance->DR);
        }



代码配置如下:SPI半双工传输
spi主机配置
  hspi1.Instance = SPI1;
  hspi1.Init.Mode = SPI_MODE_MASTER;
  hspi1.Init.Direction = SPI_DIRECTION_1LINE;
  hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
  hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
  hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
  hspi1.Init.NSS = SPI_NSS_SOFT;//SPI_NSS_HARD_OUTPUT;//
  hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256;
  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_ENABLE;
  hspi1.Init.CRCPolynomial = 7;
  hspi1.Init.CRCLength = SPI_CRC_LENGTH_16BIT;
  hspi1.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
  if (HAL_SPI_Init( hspi1) != HAL_OK)
  {
    Error_Handler();
  }


spi从机配置
  hspi2.Instance = SPI2;
  hspi2.Init.Mode = SPI_MODE_SLAVE;
  hspi2.Init.Direction = SPI_DIRECTION_1LINE;
  hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
  hspi2.Init.CLKPolarity = SPI_POLARITY_LOW;
  hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;
  hspi2.Init.NSS = SPI_NSS_SOFT;//SPI_NSS_HARD_INPUT;//
  hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256;
  hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
  hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_ENABLE;
  hspi2.Init.CRCPolynomial = 7;
  hspi2.Init.CRCLength = SPI_CRC_LENGTH_16BIT;//
  hspi2.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
  if (HAL_SPI_Init( hspi2) != HAL_OK)
  {
    Error_Handler();
  }


DMA配置
    /* SPI1 DMA Init */
    /* SPI1_TX Init */
    hdma_spi1_tx.Instance = DMA1_Channel1;
    hdma_spi1_tx.Init.Request = DMA_REQUEST_SPI1_TX;
    hdma_spi1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
    hdma_spi1_tx.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_spi1_tx.Init.MemInc = DMA_MINC_ENABLE;
    hdma_spi1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;//DMA_PDATAALIGN_HALFWORD;//
    hdma_spi1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;//DMA_MDATAALIGN_HALFWORD;//
    hdma_spi1_tx.Init.Mode = DMA_NORMAL;
    hdma_spi1_tx.Init.Priority = DMA_PRIORITY_LOW;
    if (HAL_DMA_Init( hdma_spi1_tx) != HAL_OK)
    {
      Error_Handler();
    }

    __HAL_LINKDMA(hspi,hdmatx,hdma_spi1_tx);


/* SPI2_RX Init */
    hdma_spi2_rx.Instance = DMA1_Channel3;
    hdma_spi2_rx.Init.Request = DMA_REQUEST_SPI2_RX;
    hdma_spi2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
    hdma_spi2_rx.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_spi2_rx.Init.MemInc = DMA_MINC_ENABLE;
    hdma_spi2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;//DMA_PDATAALIGN_HALFWORD;//
    hdma_spi2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;//DMA_MDATAALIGN_HALFWORD;//
    hdma_spi2_rx.Init.Mode = DMA_NORMAL;
    hdma_spi2_rx.Init.Priority = DMA_PRIORITY_HIGH;
    if (HAL_DMA_Init( hdma_spi2_rx) != HAL_OK)
    {
      Error_Handler();
    }

    __HAL_LINKDMA(hspi,hdmarx,hdma_spi2_rx);

主函数调用:
if (HAL_SPI_Receive_DMA( hspi2,(uint8_t *)spisalver_receive_array, 10) != HAL_OK)  
{
        /* Transfer error in transmission process */
        Error_Handler();
}
                        
if (HAL_SPI_Transmit_DMA( hspi1, (uint8_t *)spimater_send_array,10) != HAL_OK)
{
        /* Transfer error in transmission process */
        Error_Handler();
}





回帖(1)

微风挽雨

2024-4-2 17:02:24
在使用STM32G070的SPI CRC 16位校验功能时,发生数据接收错误的可能原因可能有以下几点:

1. 硬件问题:检查SPI接口的硬件连接是否正确,包括信号线的接线是否正确,电源供应是否稳定等。
2. DMA配置问题:确保DMA的配置是正确的,包括DMA通道和传输方向是否正确配置,传输大小是否正确配置等。
3. 中断优先级配置问题:如果使用了中断来处理SPI数据的接收,确保SPI接收中断的优先级配置正确,避免优先级与其他中断冲突。
4. DMA传输完整性问题:确保DMA的传输长度和缓冲区的大小是正确匹配的,避免数据溢出或不完整的传输。
5. 超时错误处理问题:在执行SPI_WaitFlagStateUntilTimeout函数时,由于超时时间的设置等原因,可能导致函数返回不成功,进而导致CRC错误的判断。可以尝试调整超时时间,或者使用其他方式判断接收是否完成。
6. SPI配置问题:确保SPI的配置是正确的,包括时钟极性、相位的设置是否正确,数据位宽是否设置正确等。


举报

更多回帖

发帖
×
20
完善资料,
赚取积分