(一)问题描述:
目前一个项目中,需要采集两路ADC的信号。为了使采集的信号稳定,笔者采用多次采集求取平均值,再加其他软件滤波方式。所以使用了ADC的循环采集和DMA传输。
想要达到的效果:
两路ADC个采集64个(2路总共128个)数据,然后使用DMA传输完成,触发中断。停止采集,等待数据处理完后再启动下一次采集。
实际效果:
采集完这128个数据,且DMA传输完成后,进入了中断。等我处理完这些数据再次开启DMA传输的时候,传输完成后对应的数据却错位了,就是两个通道的数据相互错位了。
(二)配置和使用
实际工程是使用的STM32CUBE配置生成的,配置ADC为循环扫描,连续转换模式,并且使用DMA单次传输。
相关配置
相关程序:
1.启动ADC的DMA传输:
开启ADC转换,并且开启DMA传输。
2.DMA传输完成的中断函数
在ADC转换完这两个通道总共128个数据并且使用DMA传输时,进入该中断回调函数。
(三)出现问题
进过上述两个过程,ADC采集的两个通道的数据保存在了adc_buf中了。
里面的数据分布应该每次都是:CH0,CH1,CH0,CH1,CH0.CH1 ..... 这样交替分布的。
但是实际情况却并不是这样,两者数据会随机错位。
(四)解决方法
在回调函数中加入如下语句,这样问题得以解决,不会再出现通道数据错位的现象了。
(五)问题分析
笔者的配置是:ADC循环转换,DMA单次传输(传输指定的数据量,触发中断会就不再启动DMA传输了)。
在使用的时候,先使用HAL_ADC_Start_DMA();函数去开启ADC转和DMA的单次传输。
当DMA传输完成后,因为是单次转换,如需继续转换,那么还需要使用HAL_ADC_Start_DMA();再次开启传输才行。这里就会有一个问题,DMA传输的确是停止了,但是ADC是循环转换,ADC仍然在转换,当我处理完数据以后使用HAL_ADC_Start_DMA();再次开启传输时候,这个时候对应ADC转换完成的数据,具体是哪一个通道的其实是随机的,但是DMA还是会把这个数据传输到adc_buf[0]中,所以我们的数据就是这样错位了。
加入了HAL_ADC_Stop_DMA();实际上是停止了ADC的转换了,在下一次开启转换的时候,就不会出现错位的问题了。