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

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

[复制链接]
攻城狮Melo 发布时间:2024-5-25 13:31
之前有陆续介绍STM32的ADC采样与板载运算放大器,本期我们将二者结合,顺带再完善一下ADC采样与DMA。
+ U9 O) G& N; ?! l, B* ?1 S* E7 m( m. @# P/ m$ B
板载运算放大器
4 N' [" K) C+ h" T2 C- g  O( t板子使用的ST公司的STM32G474RE部分板子上没有板载OPAMP的话可以忽略运算放大器的部分。
- h: \5 c1 x1 `7 @) j( Q0 [2 U
. T# w6 b& W2 b% U4 m* [# e 微信图片_20240525133129.png   b5 v: i: B" g) e, a1 [

# S, \9 e2 Y2 n/ a; Z% }0 ]) l; U  i- l$ ], {
微信图片_20240525133126.png
7 w8 q' l2 V9 u9 u9 L/ P! Y
1 l, C9 Z( B6 `; e9 a9 _我们打开运算放大器的跟随器功能,将跟随器的输出和STM32的ADC绑定,使得我们的信号接入PA1即可通过跟随器被采样。( X# i% L; Q6 O! b" I7 @, @8 v
* i- U  F8 J5 @# V4 ]/ H
ADC配置
+ _7 ~9 J# Z6 C0 ?/ X
9 M7 T$ }) X4 @3 _. @% m5 t 微信图片_20240525133123.png
$ T$ l3 R1 l9 h# r6 |
5 V. H' t5 ~. s7 g
开启ADC1_12,这里通道12只能配置为单端输入,其他的通道可以配置为差分输入。
$ n) O9 ]# F& S) d' K  L8 Z: J0 A$ }8 R6 Z1 ]
微信图片_20240525133120.png ( K0 U) `& ?3 p  J5 I( {

! F: F: `" D5 N4 k添加DMA传输,模式选择正常模式,这样子我们只采集一组ADC数据,这里如果开启了Circle模式的话,环形存储区会导致DMA后面采集的数据覆盖前面采集的数据,导致数据乱飞。3 d* @" Q* {* M
4 s" b, F9 E, A( d
微信图片_20240525133117.png
9 b, w$ i7 @8 A' b) W. \" f5 ^! H4 P9 G' t7 I+ p$ j3 Y
触发方式(启动ADC转化)我们选择定时器8,这边可以是任意定时器推荐使用的是低级定时器,这样子就可以控制我们的采样率。% p  Q; z7 E) @% U& N2 {& t# p, b

% m" g; Z$ e) \: d
定时器配置8 c5 C7 S9 F/ z& R  ]$ n3 P* n
这里解释一下Timer 8 Trigger Out event.
' p8 i9 N6 U6 }. r; b$ M4 ~* y7 Z  D& a8 Q4 t
定时器(Timer)的触发输出事件(Trigger Output Event)可以用于生成特定的触发信号,以触发其他外设或事件。% }; D0 a/ Y, t8 y+ P
$ s0 F' [4 R4 B2 l$ b
在STM32定时器中,可以配置不同的事件作为TRGO信号的源。常见的触发源包括:
  `3 x' m6 H# O" o3 {  G2 m- B更新事件(Update Event)
4 M) H1 g4 W( x$ f  I  O5 I1 p' P当定时器的计数器溢出或达到设定的周期值时产生的事件。, L, x: v; U$ R0 g
捕获/比较事件(Capture/Compare Event)0 D  I% P% O3 D5 K6 z
当定时器捕获输入信号或计数器值与比较值匹配时产生的事件。: i/ _1 F/ M  z' s2 [/ X  N
输出比较事件(Output Compare Event)
3 ^) w. U) o% Y2 {5 \. P当定时器的输出比较单元产生一个输出信号时的事件。5 i' N/ I' M5 M7 h+ e- ~  m

; L5 ~6 Y, l$ t+ p  x

8 n7 n4 M) l% I5 k; W% z 微信图片_20240525133114.png ! \3 T. }7 F/ ^' Z( L6 T0 J: ?

& h. Q( G% [/ @; q8 {$ g8 J这里设置好我们的分频系数,计数值,设置一个Update Event更新事件来触发定时器采样。这里我的主频是170MHZ,分配系数是169,溢出值是100,这样子过100us触发采样,采样率固定下就是10KHZ。
- C& r: G/ {5 U# g3 M9 d$ ]  |! A; J' a4 z+ ]& ?' B! T9 A" t9 u4 Y( q
我们强调过好几次,根据奈奎斯特采样定律,采样率必须高于信号频谱最高的两倍,当然我们在性能充裕的情况下最好是在最高频率的倍数高一点。
$ X# D/ I  ]7 h1 O" V" L% W2 P2 h- _0 q; X
微信图片_20240525133110.png
% ]) y: Q, p! \) p* [( {6 i$ l, E% B3 A1 d8 y4 A3 G
最后别忘记开启相对应中断源的中断。. s2 _+ Q* G7 l7 z! K; }
3 e4 H# v0 D+ O+ i! w4 y) s
接着就是创建工程。" v+ I0 y8 e7 X  I7 g

' N& x8 @: h9 H7 I3 H$ @) Y0 r! Z
  1. #define ADC_Lenth 10248 [( N; Q7 C3 J" b! q8 W! G+ x9 d
  2. int32_t ADC_Value[ADC_Lenth];
复制代码
, I' |$ H: T: Q+ f

) ~' `0 i5 H- x! I
定义一个数组用以充当DMA的缓存区。3 Z1 P$ b3 W  t8 ?' P% D! V/ a
  1.   while (1)/ b: o7 n7 A+ L: Y2 p
  2.   {
    " @2 _% r6 D. K. X3 p$ k6 Q, {. F
  3.     /* USER CODE END WHILE */
    ' f7 ?0 X7 [: O. e' r' x$ C. d
  4. 1 o. t) j) s; z
  5.     /* USER CODE BEGIN 3 */$ O% W$ N+ `# x" m8 i4 ^
  6.     // 检查DMA传输是否完成6 N2 [) @8 l- d# s1 I
  7.     if (HAL_DMA_GetState(&hdma_adc3) == HAL_DMA_STATE_READY)
    + U0 Q, Q; u1 ~8 V  `3 Y
  8.     {
    . J7 z6 }! x7 e7 s* ^
  9.         // 处理 ADC 数据; l$ D. d4 X7 m& a% D. d2 Z
  10.         for (int i = 0; i < ADC_Lenth; i++)& T8 j2 E) R- X0 ^. m5 ?  l9 b
  11.         {
    0 g$ x+ |% s/ Z5 v2 d
  12.            printf("A:%d\r\n", (uint16_t)ADC_Value[i]);
    ! ]0 D. f: N- c8 j# Q. w
  13.         }
    8 E+ S8 K9 S" |- y' ~
  14.         
    4 X2 x$ s! E3 |$ e, g; M9 o
  15.         # M; e% ?6 _: r1 V1 f' V# q
  16.         HAL_ADC_Start_DMA(&hadc3,ADC_Value,ADC_Lenth);3 `3 ^& T4 g/ t% D
  17.         
    5 a3 h  ]" u$ o( D( Q
  18.     }: f- \* F, |: }6 g% k7 g  T' }' G
  19.   }
复制代码

. G0 F2 u9 j/ F5 h在主函数中使用轮询的方式等待ADC传输完成,传输完成后我们利用串口打印。$ [; j, B0 G/ }  g; m3 U) d" r3 s5 b

: b0 q- c9 ~, f6 H3 ]我们使用HAL_DMA_GetState函数来获取状态。
  1. - HAL_DMA_STATE_RESET:复位状态$ m7 p2 r# }# d* j$ @+ S) F
  2. - HAL_DMA_STATE_READY:就绪状态# e5 P. ?+ i4 H% I& C; I& A
  3. - HAL_DMA_STATE_BUSY:忙碌状态
    # d7 z' Z( p0 |. C
  4. - HAL_DMA_STATE_TIMEOUT:超时状态6 w6 V3 t! W4 R. B6 J' Y( z
  5. - HAL_DMA_STATE_ERROR:错误状态
复制代码
当DMA属于就绪状态就说明传输结束。这里有一个坑点,关于) z9 b/ ]8 p  R: H3 _( d9 n

6 N" @6 S2 n5 I# g
HAL_DMA_PollForTransfer这个函数按理来说是用来查询传输结束的,但是不知道为什么使用起来很奇怪。! p( F) [* v( Q0 p) {. P
; x) n( a% S1 O: Y* z
微信图片_20240525133107.png 2 C1 S& @7 Y' s/ _* ?1 y

  O8 e1 a1 s/ X: D* B+ A这是我们采集的方波信号
) H% s+ n6 I) k) _+ `+ O2 `) y0 P  r4 Z" b

+ K  q; Z# O+ u, V转载自:电路小白' j* v0 C$ _  d; E! K( _' Z+ z
如有侵权请联系删除
+ F( I& V8 D& W6 _
( G1 q/ ~  ~  }6 b- ?: {* v, Y

  i2 l7 D# X! ^  }5 S8 H
; `, U# \( ~2 e/ R7 \

9 X' D' q( g5 `+ [! X
收藏 评论0 发布时间:2024-5-25 13:31

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版