你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

基于STM32的ADC+DMA采样与板载运放跟随经验分享

[复制链接]
攻城狮Melo 发布时间:2024-5-25 13:31
之前有陆续介绍STM32的ADC采样与板载运算放大器,本期我们将二者结合,顺带再完善一下ADC采样与DMA。* G3 j! W3 |  r1 z5 q" f
& w$ ]$ ?6 f+ |6 j( L) b; C
板载运算放大器1 p7 a# x3 S* {6 q' U1 }0 b
板子使用的ST公司的STM32G474RE部分板子上没有板载OPAMP的话可以忽略运算放大器的部分。$ b) U; E' q* D* G/ G
( N4 w' f' }! w/ F
微信图片_20240525133129.png " c& ]+ N, w; \5 ^1 o( r  _
0 q2 z$ r/ Q- @! w% J7 i5 t

/ Y- w3 h$ N0 q- f. }$ @" o 微信图片_20240525133126.png
3 u) W+ Q3 e/ P' o
- X9 }, V5 @/ _$ {$ A. D  L4 A我们打开运算放大器的跟随器功能,将跟随器的输出和STM32的ADC绑定,使得我们的信号接入PA1即可通过跟随器被采样。
% H$ D6 a7 e  A; R. S' h' J$ R: k" V4 o0 E2 m* n
ADC配置
+ t5 y( V8 W  u2 u. @, P
! u# N( f& z, q5 L9 a. B 微信图片_20240525133123.png
9 O8 M! ?6 V. H8 d' p; T( J
! d4 S5 x& S5 U+ r
开启ADC1_12,这里通道12只能配置为单端输入,其他的通道可以配置为差分输入。
& C# K. w" I. O$ k. D- k+ X
4 }. s" j( h( K' {  `9 }, g  B 微信图片_20240525133120.png
* r3 Q' y) X  _2 _; c% O( V4 d) ?

/ S- f5 l2 ]5 v$ V; R添加DMA传输,模式选择正常模式,这样子我们只采集一组ADC数据,这里如果开启了Circle模式的话,环形存储区会导致DMA后面采集的数据覆盖前面采集的数据,导致数据乱飞。& `5 R' C% h7 y4 C  b  ?

8 G& O" h! y- P. K  Z/ i2 i1 M
微信图片_20240525133117.png
0 ?8 x" ]. S9 H* G" ?. L! u! q+ H% E7 D& ?! |0 }# y# `  z* o( U! \
触发方式(启动ADC转化)我们选择定时器8,这边可以是任意定时器推荐使用的是低级定时器,这样子就可以控制我们的采样率。& g8 ?  k2 q+ J) X

1 Z$ t, H" M/ O/ a$ s6 I1 G2 G6 G
定时器配置
; X8 p5 P; B! m- X% h7 ^; X) W7 `这里解释一下Timer 8 Trigger Out event.
9 [$ V7 `8 Z% q* t% R- Y5 h9 m
5 ~/ L, p7 r9 P9 m4 i9 P
定时器(Timer)的触发输出事件(Trigger Output Event)可以用于生成特定的触发信号,以触发其他外设或事件。
: Q% k) }, l5 r/ ~
- _9 V; }, j+ S- j
在STM32定时器中,可以配置不同的事件作为TRGO信号的源。常见的触发源包括:7 ]/ [4 W' v0 z7 o  \7 ~# n7 l
更新事件(Update Event). I) U$ ?% z; m7 N# c! K8 U
当定时器的计数器溢出或达到设定的周期值时产生的事件。
/ }7 u: `1 G1 V" X+ b# Y" y8 s捕获/比较事件(Capture/Compare Event)
" {* [: W* g+ X/ Z; j2 w9 V5 V当定时器捕获输入信号或计数器值与比较值匹配时产生的事件。0 y2 D; S8 B; x6 a- t7 C8 @* W. k5 J
输出比较事件(Output Compare Event)( ]% ?$ r( z2 `5 Y+ ]
当定时器的输出比较单元产生一个输出信号时的事件。# W* c- ]  [# a( }, ]
5 L3 [3 m) d# o& L/ }' ^  l. s* k
! B7 Q& h. G& Z( |' G
微信图片_20240525133114.png
# O; B7 Z/ z: A! F/ E

- U- x! F+ {+ z' [这里设置好我们的分频系数,计数值,设置一个Update Event更新事件来触发定时器采样。这里我的主频是170MHZ,分配系数是169,溢出值是100,这样子过100us触发采样,采样率固定下就是10KHZ。
+ s! i4 Y3 C9 M
& X' p9 v4 P# n" e( O0 Z4 `8 T
我们强调过好几次,根据奈奎斯特采样定律,采样率必须高于信号频谱最高的两倍,当然我们在性能充裕的情况下最好是在最高频率的倍数高一点。
4 ~3 B; l' z$ N8 l5 f2 ^# a$ o1 a+ _9 p' o1 S3 L
微信图片_20240525133110.png
# B1 c6 V/ i$ Y+ M; U
* V" S( e& V4 ?* a* Q最后别忘记开启相对应中断源的中断。
$ W( ?/ k, R# N2 Z* X* S0 g
$ }" r  d. o0 c( k; _/ Z' [% t+ V; K
接着就是创建工程。$ q) @- d% Z# S  A
: [( q9 t4 C" J9 y1 U0 ?( v
  1. #define ADC_Lenth 1024
    . q. L. k  X" v' Y$ l% r3 b
  2. int32_t ADC_Value[ADC_Lenth];
复制代码

/ W2 T& ~; a- J  b3 c4 n# u1 t5 v3 R2 `9 X
定义一个数组用以充当DMA的缓存区。
  c" S# C2 g6 a* ~
  1.   while (1)! B$ I2 \9 B" r/ g" `  v
  2.   {1 \* |8 H) b; T+ ~
  3.     /* USER CODE END WHILE */. q" w7 K" H7 d" C( D  Z4 U
  4. 2 ?7 h  z) k2 ~: E8 y  d
  5.     /* USER CODE BEGIN 3 */$ Z- ]0 u8 l# e; b. _* |
  6.     // 检查DMA传输是否完成+ R  z; A$ K5 R, Y. H: H
  7.     if (HAL_DMA_GetState(&hdma_adc3) == HAL_DMA_STATE_READY)" F0 ~4 H) o% a! _* \8 v* c
  8.     {3 t' [2 f  o2 O0 g- v0 F" [# t/ Z  T
  9.         // 处理 ADC 数据
    ( P9 f4 j+ z: k4 J6 m$ A* P
  10.         for (int i = 0; i < ADC_Lenth; i++)
    3 h2 y. p0 [7 A: j
  11.         {. U" w5 A3 W$ l* X8 d
  12.            printf("A:%d\r\n", (uint16_t)ADC_Value[i]);
    ( P7 C% ?  k  j# B/ _8 g+ k
  13.         }
    / d$ n! a8 X. p, i" P$ o
  14.         
    8 ], c% e, P4 k4 [; j
  15.         # S1 i0 V$ q& o" x1 v2 k
  16.         HAL_ADC_Start_DMA(&hadc3,ADC_Value,ADC_Lenth);
    - w0 w# K# \; M7 ^7 R
  17.         - O* f2 N6 Q, C: \' A( Y4 L8 [3 }
  18.     }
    ; v7 T# `- T7 `6 P
  19.   }
复制代码

, i0 O5 U2 C8 J3 O5 S1 {7 g# H( u在主函数中使用轮询的方式等待ADC传输完成,传输完成后我们利用串口打印。
) m& H% R8 d0 N7 g' q! p
9 l( `$ B8 ?. l; ^; N+ X0 r( W我们使用HAL_DMA_GetState函数来获取状态。
  1. - HAL_DMA_STATE_RESET:复位状态7 d5 W" d% F1 B+ x2 V
  2. - HAL_DMA_STATE_READY:就绪状态  u% s% R9 r% U' E3 O9 a5 J; T2 H- ~
  3. - HAL_DMA_STATE_BUSY:忙碌状态/ s) q% u; U2 J/ l$ N$ o! K. B+ g6 E) F
  4. - HAL_DMA_STATE_TIMEOUT:超时状态6 `! C/ v$ ~4 r
  5. - HAL_DMA_STATE_ERROR:错误状态
复制代码
当DMA属于就绪状态就说明传输结束。这里有一个坑点,关于& E  ^; H6 n' J4 j0 x
; G8 W9 D8 ]" _6 X3 v# t1 e
HAL_DMA_PollForTransfer这个函数按理来说是用来查询传输结束的,但是不知道为什么使用起来很奇怪。2 f5 @' s+ P  G) Z1 f  l
: |8 J1 j7 G" S/ E* E: e
微信图片_20240525133107.png
$ a5 g9 H; K; {: ^! G
! `% a& w# u0 M- k这是我们采集的方波信号
* c% l2 X7 }5 s2 p
3 ]1 e; {. C. d$ Z
. L5 T( _  o+ h1 O/ u1 |; {0 O
转载自:电路小白
) B) i! K' G) Z如有侵权请联系删除7 \3 m* S& F9 d5 T# v$ k

0 @! h3 }5 f% Y$ p# s$ R5 S1 y& G+ ^

8 m  d1 M2 B' x! H5 o, L" S1 s$ A" F5 v
收藏 评论0 发布时间:2024-5-25 13:31

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版