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

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

[复制链接]
攻城狮Melo 发布时间:2024-5-25 13:31
之前有陆续介绍STM32的ADC采样与板载运算放大器,本期我们将二者结合,顺带再完善一下ADC采样与DMA。$ M6 Y, B; ^% r. E1 u5 ^
* v/ A7 M4 t+ x+ ]% B, \4 ]0 ^/ y
板载运算放大器
' ?; h0 u9 ^7 p. \: K% r板子使用的ST公司的STM32G474RE部分板子上没有板载OPAMP的话可以忽略运算放大器的部分。2 x1 F* y. Z, U& W4 W  D$ Q! y, n) Q
" U/ p, k+ s7 J( p: v" r# @
微信图片_20240525133129.png . `6 T# v( x; R

7 ^# @- T. ^6 O" J! }2 ~0 a: @
微信图片_20240525133126.png
8 A1 `3 E' K6 B" u
' O. ]) m& K& V我们打开运算放大器的跟随器功能,将跟随器的输出和STM32的ADC绑定,使得我们的信号接入PA1即可通过跟随器被采样。& d  V' @9 J; C8 ]4 O0 M: w& t5 W

/ D* y1 u/ ]8 m. U, U
ADC配置
1 S% B( z9 H, |' c1 @2 f7 E! Q; r! m# p! r# }
微信图片_20240525133123.png ' u0 b' X7 |, b4 M8 e

: G& F, |7 e2 I8 l开启ADC1_12,这里通道12只能配置为单端输入,其他的通道可以配置为差分输入。( z" k: f1 q5 S6 w' l  G# v  n

  k# J- N( j6 y% p3 ?: h 微信图片_20240525133120.png " \5 B* i* K0 P* N+ ^( e

, {- D6 Q1 B" j; L添加DMA传输,模式选择正常模式,这样子我们只采集一组ADC数据,这里如果开启了Circle模式的话,环形存储区会导致DMA后面采集的数据覆盖前面采集的数据,导致数据乱飞。8 v0 c# {  Z5 x- k

4 q% o+ a8 I  S1 @* v$ Q/ M* u- B
微信图片_20240525133117.png * r* {& D. l$ B4 Z$ O* m+ j8 b- _
$ P+ q; X' F) {+ [
触发方式(启动ADC转化)我们选择定时器8,这边可以是任意定时器推荐使用的是低级定时器,这样子就可以控制我们的采样率。. b! u* W$ l& i' _3 V% \

% p  v4 c2 }& Z$ i) f
定时器配置$ k  v$ f5 d( ~$ i1 ]9 m: o  G
这里解释一下Timer 8 Trigger Out event.8 ]+ Q( x7 F. ]) R* r
* F+ t& p3 m: {
定时器(Timer)的触发输出事件(Trigger Output Event)可以用于生成特定的触发信号,以触发其他外设或事件。
6 }6 c: x1 o( T6 P( i+ v( O" [5 y
4 ]5 r3 i% \7 K1 x
在STM32定时器中,可以配置不同的事件作为TRGO信号的源。常见的触发源包括:( z* K$ H# b7 B
更新事件(Update Event)6 I+ @+ x4 n* g& V
当定时器的计数器溢出或达到设定的周期值时产生的事件。
& O: M9 @, i, ~捕获/比较事件(Capture/Compare Event)
$ b6 O* t( u2 E5 R7 |当定时器捕获输入信号或计数器值与比较值匹配时产生的事件。
/ y, G0 e! W: s; S输出比较事件(Output Compare Event); X3 X, y7 C5 j) k
当定时器的输出比较单元产生一个输出信号时的事件。
) r6 z- Z0 I- K/ f
3 G. y* B# M6 [

* B: b$ h& l" i- H1 [. ^ 微信图片_20240525133114.png
7 o( q! m! @6 a0 ^9 l  A. K

' [6 O& S/ r* i" e* R3 s这里设置好我们的分频系数,计数值,设置一个Update Event更新事件来触发定时器采样。这里我的主频是170MHZ,分配系数是169,溢出值是100,这样子过100us触发采样,采样率固定下就是10KHZ。( [& c6 H; j  v/ k+ P0 e4 V9 |# I

2 g" h2 M' W* d$ B: _6 `) p
我们强调过好几次,根据奈奎斯特采样定律,采样率必须高于信号频谱最高的两倍,当然我们在性能充裕的情况下最好是在最高频率的倍数高一点。
) e* l# y6 X( ?% l6 w7 X2 _$ c! t
微信图片_20240525133110.png
' M7 I; v7 q1 u! z( D, z) q' J" F, h3 f# L, ?% }) ?0 x4 [8 j
最后别忘记开启相对应中断源的中断。% P- [) \' O  h, D- `; t% t

4 {1 S0 c8 _/ j' ?7 D
接着就是创建工程。; ]& P1 p0 f2 l, h& s1 u
  m9 m, y9 s4 O( f2 t* ?
  1. #define ADC_Lenth 1024
    2 K! E! ~! H( z+ M) s* Q" s, f, S8 H
  2. int32_t ADC_Value[ADC_Lenth];
复制代码
9 @6 v7 Y" [% L+ p8 z, s5 y; _. v
7 i6 Y3 Y9 B5 i
定义一个数组用以充当DMA的缓存区。/ I9 i$ Y$ K: e' M
  1.   while (1)) l/ g4 h1 ~) x, X0 q( H
  2.   {6 `5 V0 U+ V) P2 h# i- t- @6 K
  3.     /* USER CODE END WHILE */! e2 ?1 V( ]+ W8 t& M8 A1 E

  4. + n2 K2 O3 ]0 _5 t# g4 S& t2 f, k* k
  5.     /* USER CODE BEGIN 3 */8 I" N. y6 S9 v3 o7 t5 T& [$ F+ x3 I
  6.     // 检查DMA传输是否完成
    , J+ J7 E6 U# Q7 \+ n9 _
  7.     if (HAL_DMA_GetState(&hdma_adc3) == HAL_DMA_STATE_READY)
    & y$ P$ o. W7 F
  8.     {
    9 ?- z* A& @* t' Y: I
  9.         // 处理 ADC 数据
    * J9 }! Q  Q' q) ~$ I6 r: ]
  10.         for (int i = 0; i < ADC_Lenth; i++)
    ; t$ K/ D& }4 \7 P; [% m
  11.         {
    % B" a& m1 R1 d7 R
  12.            printf("A:%d\r\n", (uint16_t)ADC_Value[i]);" i3 [/ I  ?" f. A4 V* ~" G2 Y3 W
  13.         }
    3 z1 p. o. j8 k1 G, q
  14.         
    , m1 D, x! p  w7 V$ |- W
  15.         7 X8 B) G6 l% X; y, }/ i6 f
  16.         HAL_ADC_Start_DMA(&hadc3,ADC_Value,ADC_Lenth);
    2 v9 r; J( r, }, w) c) Q$ Z
  17.         1 s4 g7 D  `* C6 x8 f2 {2 l- E
  18.     }
    4 Y. I8 Y( ]! O; G
  19.   }
复制代码

' r) s& l8 z/ I在主函数中使用轮询的方式等待ADC传输完成,传输完成后我们利用串口打印。
% S* {: o6 U% g. U8 E9 M
2 D# l: W" r, m$ t, D" {3 ?我们使用HAL_DMA_GetState函数来获取状态。
  1. - HAL_DMA_STATE_RESET:复位状态5 n6 q9 q7 y+ `4 i9 P9 z
  2. - HAL_DMA_STATE_READY:就绪状态8 m% y& o4 N) ~$ k+ c; X  \/ D0 g
  3. - HAL_DMA_STATE_BUSY:忙碌状态
    0 L" V! L5 o7 K! e4 C! j, t
  4. - HAL_DMA_STATE_TIMEOUT:超时状态: R! e( ~7 z6 |
  5. - HAL_DMA_STATE_ERROR:错误状态
复制代码
当DMA属于就绪状态就说明传输结束。这里有一个坑点,关于  @5 r; }4 n' y+ r! a

& I3 v" c9 }! ~  @% }3 o
HAL_DMA_PollForTransfer这个函数按理来说是用来查询传输结束的,但是不知道为什么使用起来很奇怪。
* H7 h8 A3 C' t! N9 C5 [; ^
+ k( [8 ~) s5 ]
微信图片_20240525133107.png
2 h, H+ G. n4 c- r" s' F! K
# s1 j: b1 I7 V9 S* `/ C这是我们采集的方波信号
* y# L- n6 r1 E
8 p! l' F2 D% l0 z  H6 c+ u
) |' p2 K3 p6 p8 R) y( h: ^. g
转载自:电路小白
; ~. S8 j0 w; E如有侵权请联系删除
# [6 m9 ~1 {- o! j+ }
& `5 B4 y; E) F$ d  f

9 M5 j! |1 n+ z" G" \

9 d2 q! ^# Y# I: h
+ F, K% d$ |7 _, P0 r% h# U
收藏 评论0 发布时间:2024-5-25 13:31

举报

0个回答

所属标签

相似分享

官网相关资源

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