发新帖本帖赏金 30.00元(功能说明)我要提问
返回列表
打印
[STM32F4]

STM32F407 ADC采集+DMA传输

[复制链接]
1906|18
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 woai32lala 于 2022-11-27 12:04 编辑

[url=home.php?mod=space&uid=760190]@21小跑堂 #申请原创#
STM32F407  ADC采集+DMA传输

前言
       有的项目中需要对多个通道的电压进行一定频率的AD采样。
第一种:是使用定时器去读取,通过检查转换完成标志位来读取,但这样就会加重整个系统的负担,占用CPU资源。
第二种:是采用定时器触发多通道ADC扫描采样,且采样数据由DMA传到RAM中的缓存,通过DMA中断来获取数据。比如我们这次项目中就要1kHz的速度读取DMA,并通过DMA传输。
这样做有以下几个好处:
1、由定时器触发ADC采样,这样采样的频率可控,且定时器触发不会占用任何CPU资源;
2、DMA进一步降低了任务对CPU的占有率。

1、硬件原理
1.1定时器
    该项目中,我们选择TIM2的TRGO为触发源来触发ADC的转换。
即使用该函数:
   
下图为ADC转换的触发条件:

1.2 ADC
STM32F407的ADC的有规则通道和注入通道,规则通道扫描采样,配置好规则通道后,定时器更新后
触发ADC转换,ADC转换完成后触发DMA传输。

如下图为ADC 内部使用框图:

1.3 DMA传输
STM32F407有DMA1 和DMA2两个控制器,下图为 DMA的请求映射。


我们使用的ADC1,也就是DMA的数据流stream0 通道0,用ADC的转换完成标志触发DMA数据传输。

2、代码部分
2.1定时器
2.1定时器初始化
我们采用的10K hz的读取频率,定时器使用的是TIM2,TIM2是挂载在APB1总线上面,时钟频率为84M。
我们设置TIM2时钟分频为84,即1秒钟计数1M个,每计数100个触发一次定时器中断(这里只是用于测试,
与触发ADC转换没有必然的联系)。



2.12 定时器中断函数
为了测试定时器是否正常中断,我们加了定时器中断函数,并通过IO口的电平翻转进行测试。

通过逻辑分析仪可以看出,定时器按照设定的时间周期定时中断。
可以看出方波的频率5Khz,则进入定时器的频率为10Khz,则1秒钟触发了10Khz次ADC转换。

2.2 ADC部分
每个通道都可以单独配置为不同的采样时间,我们获取ADC的频率为10khz,一共要转换的规则通道数为4,
也就是说留给每一路的转换时间最大是25us。


由上图可得,在30M的ADC时钟频率下,12位ADC的最大转换时间为16.40us,虽然我们采用的是21M时钟
时间也不会多到哪里去,依然满足我们的采样要求。ADC初始化代码部分

设置规则转换通道和单路转换时间

我们设置规则转换 通道数为4,转换优先级根据ADC_RegularChannelConfig函数
void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime)中、

bank的大小而决定。
每一路的采样时间为84个时钟周期,约等于5us左右,符合25us范围。
2.3 DMA部分


2.4 main函数部分
我们定时DMA传输数据的个数 len 为64个字节   1ADC通道是2个字节,则4个通道就是8个字节
64个字节需要8次DMA传输,则会触发DMA传输中断。数据存储的输出uint16_t ADC_Rx[100];//接收的数据,即原地址
即DMA传输来的数据会存在该数组中。

下图为仿真数据,我们将通道2接在GND上,因为为四个通道,所以每间隔3个位,会得到几乎相同的数据,
也就是0V所对应的ADC值,数值在0左右,如下图所示。




附加知识
    ADC注射转换
    ADC注射转换最大可以插入四个通道。

设置注入转换的通道数为1,通道号为14。

   ADC_AutoInjectedConvCmd(ADC1,ENABLE)该函数作用是在规则ADC转换完成后,自动执行插入ADC通道的转换。
  插入ADC通道的转换值位于ADC的JDR寄存器

总结
以上流程就是使用STM32的ADC+DMA+timer实现自动定时采样模拟电压的配置使用流程,若读者发先任何疑问,妄指教。
下面附代码。




TIMER_ADC_DMA.zip

5.58 MB

使用特权

评论回复

打赏榜单

21小跑堂 打赏了 30.00 元 2022-10-09
理由:恭喜通过原创审核

沙发
21小跑堂| | 2022-10-9 10:04 | 只看该作者
多通道DMA方式采集ADC在实际应用中是非常实用的技能,可有效避免采样时间对整个系统的影响。作者可注意代码通过编辑器的代码框输入,效果会更好。

使用特权

评论回复
板凳
uiint| | 2022-11-17 21:25 | 只看该作者
采样的数据能用DMA传输到外扩的sram吗

使用特权

评论回复
地板
wangdezhi| | 2022-11-19 15:29 | 只看该作者
如何配置库函数stm32adc的dma传输   

使用特权

评论回复
5
uytyu| | 2022-11-20 11:28 | 只看该作者
多通道采集 使用dma 为什么只显示一个通道的值

使用特权

评论回复
6
woai32lala|  楼主 | 2022-11-20 11:51 | 只看该作者
uytyu 发表于 2022-11-20 11:28
多通道采集 使用dma 为什么只显示一个通道的值

是不是没有初始化好

使用特权

评论回复
7
woai32lala|  楼主 | 2022-11-20 11:52 | 只看该作者
uytyu 发表于 2022-11-20 11:28
多通道采集 使用dma 为什么只显示一个通道的值

建议先看看初始化问题

使用特权

评论回复
8
maudlu| | 2022-11-20 12:38 | 只看该作者
多通道采集到的数据相互有干扰,该怎么破?  

使用特权

评论回复
评论
woai32lala 2022-11-20 12:54 回复TA
可以把采样时间改长一点 
9
mikewalpole| | 2022-11-20 17:23 | 只看该作者
adc多通道采集可以不采用dma吗  

使用特权

评论回复
10
fengm| | 2022-11-20 17:46 | 只看该作者
用dma传输adc数据为什么都为0 ?

使用特权

评论回复
评论
woai32lala 2022-11-21 08:33 回复TA
那就是没读取成功呗 
11
微信13267226716| | 2022-11-21 13:53 | 只看该作者
国产替代机会有没,用pin to pin  小华HC32F4AO系列

使用特权

评论回复
12
backlugin| | 2022-11-23 23:28 | 只看该作者
如何使用ADC+DMA每隔一小段时间连续采集两个通道的数据

使用特权

评论回复
13
woai32lala|  楼主 | 2022-11-24 08:33 | 只看该作者
backlugin 发表于 2022-11-23 23:28
如何使用ADC+DMA每隔一小段时间连续采集两个通道的数据

这不就是定时器触发ADC采集嘛

使用特权

评论回复
14
youtome| | 2022-11-24 15:40 | 只看该作者
使用ADC+DMA采样不知道为什么一直失败

使用特权

评论回复
15
woai32lala|  楼主 | 2022-11-24 16:25 | 只看该作者
youtome 发表于 2022-11-24 15:40
使用ADC+DMA采样不知道为什么一直失败

什么现象

使用特权

评论回复
16
xu@xupt| | 2022-12-10 13:36 | 只看该作者
学习啦,感谢分享

使用特权

评论回复
发新帖 本帖赏金 30.00元(功能说明)我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

105

主题

528

帖子

5

粉丝