STM32F4基于DMA的多通道ADC采集——遇到的问题&解决

这几天在尝试用DMA实现规则通道多通道的ADC采集,遇到了不少问题,在这记录一下我遇到的问题,一方面理顺一下思路,也希望后人少走弯路。

一开始按照开发板资料中的程序源码编写,但无论如何配置,也无法实现功能。而后参考了CSDN和b站上上的不少文章和视频,感觉大佬们配置都很顺畅,没什么问题。(b站上的大佬主要用cube对DMA和ADC进行配置,CSDN和我一样用库函数配置)看完了网上的文章,也没啥收获。

最后,看了ST公司写的库函数(主要是stm32f4xx_dma.c, stm32f4xx_adc.c以及他们的头文件),我发现其实网上很多教程都是以ST公司给的文件为基础写的,大家可以摒弃写程序先百度的学习方法,养成先看ST公司写的库函数,再写代码的习惯,相信大家会对STM32F4有更深刻的认识。

我遇到的问题是:ADC可以正常采样,但DMA传输到内存的值一直是0(也就是说DMA没有在正常工作),昨天看了一天,也看不出问题。今天又仔细看了一遍,首先一个问题是时钟配置错误

RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_DMA1, ENABLE);

大家可以看看这个代码有几个问题。

第一个问题是ADC1对应的DMA是DMA2的数据流0,第二个问题是开启外设时钟的函数应该是RCC_AHB1PeriphClock()。很低级的错误。

把错误都改了,还是不行。我在debug的时候把DMA2_Stream0添加到观察窗中观察,单步运行。发现在初始化DMA之后,DMA2_Stream0的寄存器并没有被写入,我们知道,DMA在ENABLE状态的时候(也就是DMA2_Stream0的CR寄存器的第0位不能为1),DMA相关寄存器是不能写入的。因此,在对DMA寄存器进行配置之前,要先失能DMA,即插入如下代码:

while (DMA_GetCmdStatus(DMA2_Stream0) != DISABLE){}

但这段代码其实一直都有。而且我从观察窗中发现,在进入DMA_Init()这个函数之前,DMA2_Stream0的CR寄存器的第0位是0,执行完这个函数之后,DMA2_Stream0的CR寄存器的第0位变成1了。单步运行DMA_Init(),会发现,DMA_InitStruct->DMA_MemoryBurst 的缺省值的第0位是1,这就导致DMA2_Stream0的CR寄存器的第0位被设置成1,DMA进入ENABLE状态,不能写入值。而我不懂MemoryBurst的意义是什么,网上的教程有的也没设置这个寄存器,我也没设置。

而后在DMA初始化时,随便设置了一下DMA_MemoryBurst 的值,代码就能运行啦,至此,问题解决。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值