非dma方式adc多通道采集的文档(图)
优采云 发布时间: 2021-08-16 01:20非dma方式adc多通道采集的文档(图)
我之前写过一篇关于非dma adc多通道采集的文档:
不过之前是基于stm32F1系列的。当使用L0系列按照前面的步骤操作并没有成功时,只能通过中断或DMA来实现。与原来的F1系列ADC相比,L0有一些精简的变化,所以adc的操作也不完全一样。
对于adc来说,还有一些比较难理解的转换模式:连续模式、单次转换模式、不连续模式等,这些概念必须先搞清楚。为此,请参考我之前的文章文章中的链接。然后你可以参考L0系列的参考手册,看看哪种模式适合你的应用。
我的应用场景比较简单:有两个adc通道,两个通道同时采集然后过滤计算。核心是采集两个通道,每次采样多次。
按照正常思路,应该使用for循环。在for循环中,采集分别在两个通道上执行,结果存放在数组缓冲区中。测试中发现HAL_ADC_PollForConversion函数会在EOS序列转换结束标志置位后退出,或者超时错误退出。结果,当我在非连续模式下调用该函数时,我只有采集得到了ch2,并没有触发采集ch3。最终无法设置EOS(标志设置要求所有选择的通道为采集完)并发生超时错误。所以我只是改变了主意,不再使用上面提到的文章方法。
在使用非 DMA 之前,然后切换到 DMA。这样也可以大大简化步骤,降低cpu消耗。实现的思路也很简单,就是使用DMA+连续模式。连续模式是指连续扫描选定的通道。比如我选择ch2和ch3。那么连续模式的采集序列将是这样的:ch2->ch3->ch2->ch3->ch2->ch3-ch2->ch3...... 所以如果我们想要ch2和ch3 be 采集5 次 以上述循环 5 次为基础,DMA 共传输 10 次。
stm32cubemx的配置如下:
DMA 配置如下:
这里的半字不固定。这取决于您的 AD 使用的采集 模式的位数。我使用 12 位,所以一个样本值占用两个字节。当然也可以用word,但是会造成一些内存浪费。
stm32 dma采集的接口如下:
HAL_ADC_Start_DMA(ADC_HandleTypeDef* hadc, uint32_t* pData, uint32_t Length);
最终代码如下:
<p>uint16_t adc_value[10];
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
for(uint8_t i=0;i