
之前有陆续介绍STM32的ADC采样与板载运算放大器,本期我们将二者结合,顺带再完善一下ADC采样与DMA。& p, h9 _" g% E2 K- z w 板载运算放大器4 W2 n4 W4 x) {" g3 t0 J/ n" J 板子使用的ST公司的STM32G474RE部分板子上没有板载OPAMP的话可以忽略运算放大器的部分。 ![]() ![]() 我们打开运算放大器的跟随器功能,将跟随器的输出和STM32的ADC绑定,使得我们的信号接入PA1即可通过跟随器被采样。 ADC配置3 w0 y, v! j) c) D3 g6 O7 q ![]() & I5 R1 T3 `2 ?' }; ^ 开启ADC1_12,这里通道12只能配置为单端输入,其他的通道可以配置为差分输入。+ q( ]2 w2 Y6 } ![]() ; b& H# ]0 H6 f6 u( E' x 添加DMA传输,模式选择正常模式,这样子我们只采集一组ADC数据,这里如果开启了Circle模式的话,环形存储区会导致DMA后面采集的数据覆盖前面采集的数据,导致数据乱飞。 ![]() 触发方式(启动ADC转化)我们选择定时器8,这边可以是任意定时器推荐使用的是低级定时器,这样子就可以控制我们的采样率。4 p. {( V1 y2 f4 A ) x! R8 X. |' ], G# ~3 v5 d# p 定时器配置 这里解释一下Timer 8 Trigger Out event.* t# h* u% g i- v# T 定时器(Timer)的触发输出事件(Trigger Output Event)可以用于生成特定的触发信号,以触发其他外设或事件。; l& a& k: {" t) L* g2 I 1 {9 v' T8 k3 n6 }# L 在STM32定时器中,可以配置不同的事件作为TRGO信号的源。常见的触发源包括:8 R8 k8 T; R/ U0 x 更新事件(Update Event) 当定时器的计数器溢出或达到设定的周期值时产生的事件。) B# n! v. O& M7 R6 C, J 捕获/比较事件(Capture/Compare Event) 当定时器捕获输入信号或计数器值与比较值匹配时产生的事件。( C' L. |, `) f. g: ^5 Y 输出比较事件(Output Compare Event): p o: \8 i9 I. [: w& Q8 Y+ ` 当定时器的输出比较单元产生一个输出信号时的事件。% y0 e7 [; i/ z. Q4 z/ z 2 R' r" S2 V- d6 `0 U) T" B ![]() 这里设置好我们的分频系数,计数值,设置一个Update Event更新事件来触发定时器采样。这里我的主频是170MHZ,分配系数是169,溢出值是100,这样子过100us触发采样,采样率固定下就是10KHZ。 我们强调过好几次,根据奈奎斯特采样定律,采样率必须高于信号频谱最高的两倍,当然我们在性能充裕的情况下最好是在最高频率的倍数高一点。 ![]() ! R+ f* H0 p+ {1 K+ R2 } 最后别忘记开启相对应中断源的中断。6 e% F7 W3 u7 _5 `0 `. n. U 接着就是创建工程。$ l2 |) [) Q9 Y; i8 H7 A
定义一个数组用以充当DMA的缓存区。
在主函数中使用轮询的方式等待ADC传输完成,传输完成后我们利用串口打印。 ( O% F L6 o* T% X 我们使用HAL_DMA_GetState函数来获取状态。
当DMA属于就绪状态就说明传输结束。这里有一个坑点,关于 HAL_DMA_PollForTransfer这个函数按理来说是用来查询传输结束的,但是不知道为什么使用起来很奇怪。 : h) Z O+ d4 `3 D6 l q$ m ![]() " q7 D* C }: t/ z# a9 @9 | 这是我们采集的方波信号。3 ]/ R& a$ J5 D. W 转载自:电路小白; T) ?. ^; _7 V# D7 `2 a$ U% L 如有侵权请联系删除/ F Y7 [7 K* m * O' Y$ N! H# d+ Z* e |
【STM32U3评测】SPIDMA发送
实战经验 | TrustZone应用中串口通信的DMA传输失败问题
狂欢三】STM32C031使用TIM定时器DMA方式实现WS2812彩灯输出(三)
stm32使用定时器触发dma传输,启动dma没反应的几种情况的解决方法
STM32的DMA双缓冲模式详解
基于STM32使用ADC的多通道采样经验分享
基于STM32的心率计以DMA方式获取传感器数据经验分享
基于STM32利用ADC+DMA采样显示经验分享
【经验分享】STM32使用DMA接收串口数据
基于STM32的DMA经验分享