STM32F103 SPI DMA接收异常处理机制
背景:使用SPI从机接收数据,当SCK管脚异常悬浮的时候,SPI接收的数据总是Tx比Rx滞留1Byte.
当出现上述问题的时候,无论是重新开SPI,还是重新开DMA,总是不能恢复正常,只有重启单片机才能回复正常。但是在方案设计中又不允许芯片重启。直到用keil调试的时候把DMA相关的寄存器打印出来才发现,有个寄存器异常了。
下面先上两个寄存器的截图
—正常的时候—
—出问题的时候—
可以明显看到 Tx的CNDTR多了一个字节,导致数据延后了。所以处理的方法在调用HAL_SPI_TransmitReceive_DMA之后再回读CNDTR寄存器,如果数据不对就重新更新。
void CheckDma()
{
if( ( hdma_spi1_rx.Instance->CCR != 0x8F ) || ( hdma_spi1_rx.Instance->CNDTR != SPI_USER_DATA_LEN ) )
{
hdma_spi1_rx.Instance->CCR = 0x8E;
hdma_spi1_rx.Instance->CNDTR = 0x14;
hdma_spi1_rx.Instance->CCR = 0x8F;
}
if( ( hdma_spi1_tx.Instance->CCR != 0x9B ) || ( hdma_spi1_tx.Instance->CNDTR != SPI_USER_DATA_LEN - 1 ) )
{
hdma_spi1_tx.Instance->CCR = 0x9A;
hdma_spi1_tx.Instance->CNDTR = 0x13;
hdma_spi1_tx.Instance->CCR = 0x9B;
}
}
HAL_SPI_TransmitReceive_DMA(&hspi1, s_pTxData, s_pRxData, SPI_USER_DATA_LEN);
CheckDma();