使用SPI CRC校验功能,DMA发送和接收,如果是CRC 8位校验没有问题,改成16位就发生接收数据错误,跟踪调试是进入到SPI_DMAReceiveCplt函数执行到SPI_WaitFlagStateUn
tilTimeout判断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();
}