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

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

[复制链接]
攻城狮Melo 发布时间:2024-5-25 13:31
之前有陆续介绍STM32的ADC采样与板载运算放大器,本期我们将二者结合,顺带再完善一下ADC采样与DMA。
8 b5 X+ i/ x  x' j# s) i# R- P6 _9 O3 H+ [% h: |# C  ]3 x
板载运算放大器! u5 u% D* i, V
板子使用的ST公司的STM32G474RE部分板子上没有板载OPAMP的话可以忽略运算放大器的部分。) z9 X" y' ^( ^/ o

* ]/ Q' Y  s: E 微信图片_20240525133129.png
: q3 x# r+ E* a' n
  D- A" H& K  U; i8 l5 J% ?- F' E
微信图片_20240525133126.png ) t! R; t( [* v  c4 w8 O

; e- k  l9 e" i我们打开运算放大器的跟随器功能,将跟随器的输出和STM32的ADC绑定,使得我们的信号接入PA1即可通过跟随器被采样。6 {' g2 E2 V* B3 }5 K

- ]( X% i3 F% X) U- |9 `9 ^
ADC配置* f/ Z. Z) X5 g/ B2 Z2 ^7 b
' D, p( \; i$ n0 e0 s7 b
微信图片_20240525133123.png
5 R4 s0 U- @: Z$ [% F
& y( i! S& t& u2 E) P3 g, Q
开启ADC1_12,这里通道12只能配置为单端输入,其他的通道可以配置为差分输入。7 [6 O0 n: h* U* |

! G# e  H- S" W1 |6 Y 微信图片_20240525133120.png
5 F4 G5 L: R+ M: @, K" B

6 w/ f5 c7 f% S) F添加DMA传输,模式选择正常模式,这样子我们只采集一组ADC数据,这里如果开启了Circle模式的话,环形存储区会导致DMA后面采集的数据覆盖前面采集的数据,导致数据乱飞。
/ @$ u# n4 s( E3 e! D
: ~$ c! n  i: G+ r8 y" C  i2 Y
微信图片_20240525133117.png 3 L. i! j) t+ x1 V

5 C; p) I. }3 u: g5 s( s) [触发方式(启动ADC转化)我们选择定时器8,这边可以是任意定时器推荐使用的是低级定时器,这样子就可以控制我们的采样率。
3 R+ X9 s/ p* _7 r8 b1 |1 t5 K) C0 g" C# B- \% ~  @$ \# u
定时器配置
8 I9 A. K. N) `1 g, z; X! J, F+ _1 V% S这里解释一下Timer 8 Trigger Out event.
* I+ A3 c7 X0 f: p
: \4 [$ }7 A$ P% \, {  F
定时器(Timer)的触发输出事件(Trigger Output Event)可以用于生成特定的触发信号,以触发其他外设或事件。" H2 P' R1 W5 B& f$ d6 p8 y
/ F" y- S2 X+ D  s7 W  o
在STM32定时器中,可以配置不同的事件作为TRGO信号的源。常见的触发源包括:' i# v: [! Y, F( _( l
更新事件(Update Event)6 h( r. K% e* [$ Y1 R  e
当定时器的计数器溢出或达到设定的周期值时产生的事件。
4 f7 f/ e( ?0 c9 I7 H' i) k( o捕获/比较事件(Capture/Compare Event)* K; Q5 ^/ M4 J: ]+ M6 d6 e/ e% V1 c: F
当定时器捕获输入信号或计数器值与比较值匹配时产生的事件。* C" }, c6 U$ ~: T% `, C4 }) j! O  E6 s4 d
输出比较事件(Output Compare Event)/ @' L8 Q7 x3 H) K
当定时器的输出比较单元产生一个输出信号时的事件。
/ E6 V# z) b0 g
1 C$ F" p5 d" T9 ~. a2 R+ F

. m& y% t4 _0 f/ E, t0 o$ c 微信图片_20240525133114.png ) `8 a: ]0 |) ~. J# o

& J1 _; H/ Z# |& s  D这里设置好我们的分频系数,计数值,设置一个Update Event更新事件来触发定时器采样。这里我的主频是170MHZ,分配系数是169,溢出值是100,这样子过100us触发采样,采样率固定下就是10KHZ。
5 u$ g3 q5 X8 X# K( g( k4 A6 l' a7 g7 H) I- X& b, `, r
我们强调过好几次,根据奈奎斯特采样定律,采样率必须高于信号频谱最高的两倍,当然我们在性能充裕的情况下最好是在最高频率的倍数高一点。
: y( }0 a) W" U7 V  k6 }2 w# c! n' F2 c/ F6 Y! T
微信图片_20240525133110.png
( F0 G& r6 W0 O/ a
& a; R* y7 |+ h3 ]最后别忘记开启相对应中断源的中断。! N9 d" Z7 s0 S3 ?/ A: a

3 P3 U, r& h4 z5 N! C
接着就是创建工程。
+ C0 V) C8 N. [9 I7 |! q* O
, u! M; O" m% b/ S: v
  1. #define ADC_Lenth 1024' B! d8 J- [  h9 a( ~1 Y' B
  2. int32_t ADC_Value[ADC_Lenth];
复制代码
7 \# W8 M8 M2 W# @

7 m) x7 T0 {4 C, ~8 v
定义一个数组用以充当DMA的缓存区。
7 T& }$ ^: P% a2 B2 w) ^
  1.   while (1)4 }) A, @+ J3 K
  2.   {& f6 ^! _" v) d: b! [' q8 O; O, k
  3.     /* USER CODE END WHILE */
    , l1 w) R% J5 g0 ^

  4. 3 m: P. I& Y; W" A
  5.     /* USER CODE BEGIN 3 */! E$ A! s( e4 ]( v
  6.     // 检查DMA传输是否完成
    . G7 g* _( a& k" S% Z9 }# o
  7.     if (HAL_DMA_GetState(&hdma_adc3) == HAL_DMA_STATE_READY)
      H" r, K2 X# C6 A$ W
  8.     {' y- B  j, Q- U% S' ~
  9.         // 处理 ADC 数据
    1 t3 N- W" L  [4 D
  10.         for (int i = 0; i < ADC_Lenth; i++)
    9 q. p" \4 J' Y  ?( Y: r7 z# V
  11.         {1 F" i3 Q5 [+ H4 R, q2 ~# i$ u
  12.            printf("A:%d\r\n", (uint16_t)ADC_Value[i]);' z) m) F$ A  v- C) i& V7 ?! o
  13.         }
    / d* K/ ]* x; H5 w& `) J+ }5 {: V0 ^
  14.         * }7 J' x' W; [
  15.         ' T" V% o! ^4 [9 r
  16.         HAL_ADC_Start_DMA(&hadc3,ADC_Value,ADC_Lenth);* R5 ]2 b& D6 ?/ a4 L
  17.         
      {3 _5 J( w" @$ h2 S
  18.     }
    $ ^1 n" o, @( a1 h) ]
  19.   }
复制代码
1 j: f5 T, `3 `! o2 C' `6 n
在主函数中使用轮询的方式等待ADC传输完成,传输完成后我们利用串口打印。
- e! B8 p, i$ i5 B% M( ]9 b2 Z# Z* a' C' T/ N2 u  R  R
我们使用HAL_DMA_GetState函数来获取状态。
  1. - HAL_DMA_STATE_RESET:复位状态
    * w5 s9 I" \) e- d, c& F- f* N
  2. - HAL_DMA_STATE_READY:就绪状态
    $ _6 V9 M4 N6 X' [
  3. - HAL_DMA_STATE_BUSY:忙碌状态
    + j  C4 j! I7 [; a0 l
  4. - HAL_DMA_STATE_TIMEOUT:超时状态
    1 w; i$ E% U- z' p; C" N
  5. - HAL_DMA_STATE_ERROR:错误状态
复制代码
当DMA属于就绪状态就说明传输结束。这里有一个坑点,关于
7 W0 N! u6 S- W+ L5 Y1 ?- g( c
3 S+ v. h& i7 ~3 A0 B+ b7 u
HAL_DMA_PollForTransfer这个函数按理来说是用来查询传输结束的,但是不知道为什么使用起来很奇怪。
6 ]# _4 K. h( c' }( t
. G) E. I( t- \: \9 @, Q
微信图片_20240525133107.png ! I0 x" n' _# i: O1 J8 S

) Z) i' T4 f% H这是我们采集的方波信号
1 V9 p# X, y" t. R' \
" R: s, F  u+ b& P; n

( t2 N, Z, \4 g1 I0 w+ x5 j4 f转载自:电路小白" s9 ?, e' c; d9 J
如有侵权请联系删除
$ l1 b- o8 J4 E8 r1 S- A4 r

! u) V- @/ ^! U2 I& [3 p; G" |9 m0 M2 r3 |1 A
, ]2 @$ x- V/ M  y% J

. ]6 p/ x/ s  H3 L& R
收藏 评论0 发布时间:2024-5-25 13:31

举报

0个回答

所属标签

相似分享

官网相关资源

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