STM32L15x——ADC采集DMA数据只第一次正确(已解决)

时间:2022-10-06 15:53:12

前提:我用的芯片是STM32L系列,可能对其它STM32系列不完全适用,仅供参考!

一、问题描述

我在使用DMA方式读取单ADC单通道采集的数据时,发现只能正确的采集一次数据,后来的就一直与第一次的相同。
配置DMA时,用于保存转换数据的16位变量的地址和ADC_DR寄存器的地址都没问题,DMA模式是DMA_Mode_Circular(循环模式),存储器地址自增也关闭了,一切我能查到的都配置好了,但是还是不行。

二、发现问题

按理说配置出问题应该先去查手册,但是无奈手册只有英文,我在网上找不到解决方案就只能硬着头皮看手册了,最后把STM32L151xx的参考手册ADC章节关于DMA的部分给翻译了一遍,才找到了问题的解决方案。

手册原文(P286):
STM32L15x——ADC采集DMA数据只第一次正确(已解决)

翻译过来大体意思:

STM32L15x——ADC采集DMA数据只第一次正确(已解决)

所以问题就出来,因为我只需要将每一个AD转换的值保存在一个16位的变量中,所以将DMA_BufferSize=1,这就导致我传输一次就结束了,而ADC_CR2的DDS位也没配置,默认是0,即传输完一次后就不会在接受新的DMA请求了。
STM32L15x——ADC采集DMA数据只第一次正确(已解决)

三、解决问题

了解了原因所在后,解决方法就很简单了,你可以直接在ADC初始化的直接给ADC_CR2的DDS位置1,当然我也在标准库中找到了一个函数:

ADC_DMARequestAfterLastTransferCmd(ADC1,ENABLE);

其实内部也是对DDS位操作的,效果是相同的。

void ADC_DMARequestAfterLastTransferCmd(ADC_TypeDef* ADCx, FunctionalState NewState)
{
/* Check the parameters */
assert_param(IS_ADC_ALL_PERIPH(ADCx));
assert_param(IS_FUNCTIONAL_STATE(NewState)); if (NewState != DISABLE)
{
/* Enable the selected ADC DMA request after last transfer */
ADCx->CR2 |= ADC_CR2_DDS;
}
else
{
/* Disable the selected ADC DMA request after last transfer */
ADCx->CR2 &= (uint32_t)~ADC_CR2_DDS;
}
}