stm32f407做spi从机的时候,开启dma接受后即等待主机的时钟以完成接受。如接受16个字节,则需要16个跳变沿(根据配置决定上升沿或下降沿)。由于在stm32f407的spi传输中并没有对时钟的脉宽限制,所以在此过程中,如果在时钟上产生干扰(额外的跳变沿),则会发生数据移位的bug,即下次采样时,寄存器中还有几位上次留下来的数据,导致数据移位。
看了很多帖子,有说可以通过SPI_CR1->SPE置高再置低来解决,有说在传输完成时关闭dma(HAL库中有HAL_SPI_DMAStop()这个函数。这样也许就算时钟多出来几位,也不会发成传输),然而以上两个方法实测并没有解决问题。
解决方式是先切换成主模式再切换成从模式,即SPI_CR1->SSI & MSTR先置高再置低,此时寄存器随之重置,问题解决。每次传输前都进行一次“从-主-从”的切换,就算一次传输中时钟线引入干扰,此次数据失效,依然不影响下一次的传输。
时钟线引入干扰后,极端情况下数据大小变为原数据的两倍(0x80->0xFF),如果干扰信号出现的不频繁,可以通过多次数据的掐头去尾来去除影响。若是干扰信号频繁出现,也可通过均值滤波降低对数据的干扰。