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

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

[复制链接]
攻城狮Melo 发布时间:2024-6-15 13:34
之前有陆续介绍STM32的ADC采样与板载运算放大器,本期我们将二者结合,顺带再完善一下ADC采样与DMA。
5 H& k/ N" \2 G$ w' P6 e( Y
9 r- _. Z, w  G  A+ q板载运算放大器
* X9 E3 ?7 P/ C( l. {板子使用的ST公司的STM32G474RE部分板子上没有板载OPAMP的话可以忽略运算放大器的部分。9 G8 W+ b0 z$ z1 ?' V2 W
+ [3 s7 p2 c, D/ @
微信图片_20240615133357.png
) l9 V6 w8 ]1 M& p% |# N& a6 x' @, Z& H% u" d1 t
微信图片_20240615133353.png
' |) \7 ?+ @: j; N
9 @6 v1 V, {; I我们打开运算放大器的跟随器功能,将跟随器的输出和STM32的ADC绑定,使得我们的信号接入PA1即可通过跟随器被采样。
" O0 ?9 c( w) W* z; k& i+ g4 E2 ?6 y7 O8 n' M# }
ADC配置

/ z/ J  r$ N$ E" [8 w' Y
$ l. t# U# z$ {! y0 { 微信图片_20240615133349.png 2 k  V/ ]0 Y$ N- K0 g
; P5 g3 M5 K: M. c* j( ]" }
开启ADC1_12,这里通道12只能配置为单端输入,其他的通道可以配置为差分输入。; j0 p  P' F+ E5 [" w$ X  F

2 g* B, x. m" u& Y- s- k 微信图片_20240615133346.png " G  n" F( {# D7 [& ?
% \* s4 {, V6 Z9 {
添加DMA传输,模式选择正常模式,这样子我们只采集一组ADC数据,这里如果开启了Circle模式的话,环形存储区会导致DMA后面采集的数据覆盖前面采集的数据,导致数据乱飞。
+ N. e- f0 i: z( ^$ l4 d3 b; t0 U7 Q$ w+ Y' X( n
微信图片_20240615133343.png ! R1 \' l5 ^. N2 W9 o' w, L2 e
- D1 W: u) ?6 Q% i) b1 U
触发方式(启动ADC转化)我们选择定时器8,这边可以是任意定时器推荐使用的是低级定时器,这样子就可以控制我们的采样率。
9 x3 D; V7 n7 u9 l3 t1 ]7 P
: A, _+ ^$ J2 Z: u. x定时器配置
3 |! n) F; W6 J' Q5 B" g
这里解释一下Timer 8 Trigger Out event.' C! M) y4 b  r, W
3 j: e, F- z3 U! T
定时器(Timer)的触发输出事件(Trigger Output Event)可以用于生成特定的触发信号,以触发其他外设或事件。

, ]( E& m- P) f6 C! T
3 j1 z- Y+ u( Q) K  |在STM32定时器中,可以配置不同的事件作为TRGO信号的源。常见的触发源包括:
& \! o+ W- i; s- C3 U4 ~6 A
更新事件(Update Event)1 W2 I5 Z* G) I5 J3 v# h
当定时器的计数器溢出或达到设定的周期值时产生的事件。( {( T# ^; K" D6 l7 L$ W' @. @0 Y" O
捕获/比较事件(Capture/Compare Event)2 p3 H) \* C+ D8 X
当定时器捕获输入信号或计数器值与比较值匹配时产生的事件。
% Y$ V7 u! j, G输出比较事件(Output Compare Event)# ~  ?+ K1 Z* l  R2 X9 [  Q
当定时器的输出比较单元产生一个输出信号时的事件。
: `, e0 H% Y% F' I- ^( [" X4 ?/ b  T: p
微信图片_20240615133339.png ! R1 k' w- t8 c4 q
- m. g* M& P! s9 m$ Q+ H' j
这里设置好我们的分频系数,计数值,设置一个Update Event更新事件来触发定时器采样。这里我的主频是170MHZ,分配系数是169,溢出值是100,这样子过100us触发采样,采样率固定下就是10KHZ。) Q/ Y7 A6 {& H2 C0 p
* j$ j3 }# u' ]
我们强调过好几次,根据奈奎斯特采样定律,采样率必须高于信号频谱最高的两倍,当然我们在性能充裕的情况下最好是在最高频率的倍数高一点。
" c) }: ]' }+ V& \$ E" u

+ Z8 W7 S& C& K  s+ C7 j" H# u 微信图片_20240615133333.png
& x8 t0 T' A8 k8 y7 g( g8 c6 |, C) @6 V6 F9 E, v9 \
最后别忘记开启相对应中断源的中断。# J, u+ g; Z- t2 _( D  o
* w5 N& G$ G) P5 g
接着就是创建工程。
: r& E  d& Q0 a; s
  1. #define ADC_Lenth 1024
      F9 T& y( v) m+ ?7 x7 Z
  2. int32_t ADC_Value[ADC_Lenth];
复制代码
9 q- \2 \' q" j0 J) R
定义一个数组用以充当DMA的缓存区。
! I& I/ Q0 v2 A. m5 f5 B2 G$ O$ h
  1. while (1)* Y6 o5 y( Y! t, c
  2.   {
    - h+ A  Z6 e/ }2 J
  3.     /* USER CODE END WHILE */% @, y4 H8 ~! `0 L/ z# E: n

  4. - l) I1 w$ J) r6 o0 H
  5.     /* USER CODE BEGIN 3 */
    # y( A) l* {2 G, V
  6.     // 检查DMA传输是否完成
    , q5 a5 k% f; c, g/ z
  7.     if (HAL_DMA_GetState(&hdma_adc3) == HAL_DMA_STATE_READY)
    1 N, E6 D, P" c9 L8 o9 o- ^* }
  8.     {! o. l( T" r$ C% A! W
  9.         // 处理 ADC 数据
    - E; k5 z3 g; {7 W, H
  10.         for (int i = 0; i < ADC_Lenth; i++)
    1 _+ g* N- l$ F/ ]' G* \
  11.         {' e& S% D  e' E
  12.            printf("A:%d\r\n", (uint16_t)ADC_Value);
    3 ?4 t3 m, A1 X5 j4 n  R
  13.         }4 a6 o* ?+ e% k! i
  14. 7 e% G, U3 }8 f! N  u+ [

  15. + J$ d) R$ g9 ^( H6 f, L  g3 w- l
  16.         HAL_ADC_Start_DMA(&hadc3,ADC_Value,ADC_Lenth);
    * a3 J/ r9 D, C. h

  17. ' Y. b4 {2 ^* X, U
  18.     }
    1 X' I# y3 f* Z% c+ k
  19.   }
复制代码

4 m0 g: c2 K7 y: f% d在主函数中使用轮询的方式等待ADC传输完成,传输完成后我们利用串口打印。
0 j, y( u7 K6 [% {" r' k/ T  U/ I% A; h7 P9 O5 m. i% X' L" T
我们使用HAL_DMA_GetState函数来获取状态。
  O0 A, B/ ~( a) C* O* J  f
  1. - HAL_DMA_STATE_RESET:复位状态
    4 e6 }: U. ?; D( [; C# }, j
  2. - HAL_DMA_STATE_READY:就绪状态
    + w3 w9 `& M9 e1 w4 z8 E- H
  3. - HAL_DMA_STATE_BUSY:忙碌状态
    * P2 H( b$ X% F' O$ f
  4. - HAL_DMA_STATE_TIMEOUT:超时状态" l* ?5 H4 r3 V8 J) s
  5. - HAL_DMA_STATE_ERROR:错误状态
复制代码

6 K& C' S$ a  {. D- _当DMA属于就绪状态就说明传输结束。这里有一个坑点,关于
" b9 g; k# D( i2 U; w6 ^4 IHAL_DMA_PollForTransfer这个函数按理来说是用来查询传输结束的,但是不知道为什么使用起来很奇怪。( |- w2 h$ |* S1 d7 l2 g
2 n* q8 w( Z6 n* ~& @* t5 g
微信图片_20240615133330.png
" o: p) i; R( m- x$ v: b
* o8 z+ M( Z8 }% G8 o* `这是我们采集的方波信号。

- Z0 b  K( t4 A3 T3 N, m; y& }. \' {' A& a$ u5 f
: t+ d* L( @% E0 C+ Z4 Q- n+ s
转载自:电路小白
2 d) Q. j7 [- H2 ~+ D. x如有侵权请联系删除
1 B6 p5 w) d. k; ~8 F7 X% c
& i- h% y' i1 }' l, ], u. g+ X
2 i, @5 h, D: e! s, i
赞 收藏 评论0 发布时间:2024-6-15 13:34

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版