之前有陆续介绍STM32的ADC采样与板载运算放大器,本期我们将二者结合,顺带再完善一下ADC采样与DMA。2 E2 y) K% Z% T# K. j( [ 板载运算放大器 板子使用的ST公司的STM32G474RE部分板子上没有板载OPAMP的话可以忽略运算放大器的部分。2 }1 n0 w0 A; [5 M* L . }% O# T7 D4 k9 g* s9 a" r ' }5 d- B3 d5 P. g7 t7 ~, `, b* c2 E ' X1 B1 `; J, n. c( W4 i/ S 我们打开运算放大器的跟随器功能,将跟随器的输出和STM32的ADC绑定,使得我们的信号接入PA1即可通过跟随器被采样。 ' h/ n/ u/ T$ e) v) d6 t! N3 f ADC配置 ; V' o' X( l3 D5 J, E0 | 开启ADC1_12,这里通道12只能配置为单端输入,其他的通道可以配置为差分输入。 + y) e7 p4 m6 n! X" H( D' G * ?2 R, A5 g: y 添加DMA传输,模式选择正常模式,这样子我们只采集一组ADC数据,这里如果开启了Circle模式的话,环形存储区会导致DMA后面采集的数据覆盖前面采集的数据,导致数据乱飞。2 b0 a3 U3 |" j - K! W* F% o8 j+ y! N 触发方式(启动ADC转化)我们选择定时器8,这边可以是任意定时器推荐使用的是低级定时器,这样子就可以控制我们的采样率。 8 D; U& @% x1 }8 B" N2 S1 |, \9 [ 定时器配置 这里解释一下Timer 8 Trigger Out event. 定时器(Timer)的触发输出事件(Trigger Output Event)可以用于生成特定的触发信号,以触发其他外设或事件。: Z0 E+ s3 P, N7 k 在STM32定时器中,可以配置不同的事件作为TRGO信号的源。常见的触发源包括:* ]4 u! l1 N3 s+ M2 L# q a8 ]3 B 更新事件(Update Event)8 ^4 b/ ~ T ]& w( a4 M+ M/ b 当定时器的计数器溢出或达到设定的周期值时产生的事件。/ @5 `7 ]7 R) S' ]/ h5 X2 Q- Y7 X 捕获/比较事件(Capture/Compare Event) 当定时器捕获输入信号或计数器值与比较值匹配时产生的事件。 输出比较事件(Output Compare Event); J ?7 p' d& {: X; E 当定时器的输出比较单元产生一个输出信号时的事件。 }) n! I( z* @# j' t 这里设置好我们的分频系数,计数值,设置一个Update Event更新事件来触发定时器采样。这里我的主频是170MHZ,分配系数是169,溢出值是100,这样子过100us触发采样,采样率固定下就是10KHZ。/ @5 U$ h5 [8 L, B2 f3 W 我们强调过好几次,根据奈奎斯特采样定律,采样率必须高于信号频谱最高的两倍,当然我们在性能充裕的情况下最好是在最高频率的倍数高一点。( k+ D( c( \- v# t8 F4 y$ C 最后别忘记开启相对应中断源的中断。, m# @2 B8 |" f. f8 } + x; G( d7 `5 V5 N# f5 }0 E 接着就是创建工程。) w. M" b( _' F/ x( d H7 X
定义一个数组用以充当DMA的缓存区。: }1 @/ l- ~# Y8 a3 b; a) k; ]+ D) J
在主函数中使用轮询的方式等待ADC传输完成,传输完成后我们利用串口打印。' r9 c! w( e+ G' v/ r 我们使用HAL_DMA_GetState函数来获取状态。
HAL_DMA_PollForTransfer这个函数按理来说是用来查询传输结束的,但是不知道为什么使用起来很奇怪。 2 W( e( y8 T; T: ? 这是我们采集的方波信号 转载自:电路小白 如有侵权请联系删除 - l& X( L" D' n + W& ^& x! \* m+ r V' c 0 b' `8 H+ H" F |
STM32的DMA双缓冲模式详解
基于STM32使用ADC的多通道采样经验分享
基于STM32的心率计以DMA方式获取传感器数据经验分享
基于STM32利用ADC+DMA采样显示经验分享
【经验分享】STM32使用DMA接收串口数据
基于STM32的DMA经验分享
基于STM32的ADC+DMA采样与板载运放跟随经验分享
基于STM32F407和Cubemx的ADC采集+DMA传输实现简易示波器经验分享
基于STM32CubeMX实现ADC的经验分享
基于STM32F407的DMA采样+FFT时域经验分享