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

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

[复制链接]
攻城狮Melo 发布时间:2024-5-25 13:31
之前有陆续介绍STM32的ADC采样与板载运算放大器,本期我们将二者结合,顺带再完善一下ADC采样与DMA。
+ G  M- w+ u# z
" P& X2 T2 x3 q$ V
板载运算放大器
, @% K/ S6 l  Q; _3 h板子使用的ST公司的STM32G474RE部分板子上没有板载OPAMP的话可以忽略运算放大器的部分。3 G7 l; J( P0 O# q- |( L
- g0 ]) A3 a* o% X; r
微信图片_20240525133129.png , M5 r! b& _$ v
0 U5 f, S" X" m, _/ a

/ ]0 _. D  m6 }. v1 z" j 微信图片_20240525133126.png
' k5 `! ^: O0 O0 |4 z
3 T+ j  x: ]- D我们打开运算放大器的跟随器功能,将跟随器的输出和STM32的ADC绑定,使得我们的信号接入PA1即可通过跟随器被采样。
' v3 |0 A% b) }6 R" l; l$ E
: l5 Y, C! E' s3 z/ [. a  U) q) q
ADC配置7 ~) t' K/ ?5 _3 u- E- z
. q. A/ ~# C3 z% a5 N
微信图片_20240525133123.png
) o$ i- ?# U# @( J$ y7 ?9 C

3 z2 H( ^0 y9 i9 ?" Z3 G- Y1 n开启ADC1_12,这里通道12只能配置为单端输入,其他的通道可以配置为差分输入。
0 U. Z, r' g- M( |3 U9 F$ G0 i) ]" I% P/ {2 _/ ]8 E) a
微信图片_20240525133120.png
& @; k2 b* e" P8 h6 |

/ w! u' Z7 _  [8 o& U% D添加DMA传输,模式选择正常模式,这样子我们只采集一组ADC数据,这里如果开启了Circle模式的话,环形存储区会导致DMA后面采集的数据覆盖前面采集的数据,导致数据乱飞。+ N% }* j, i# R" u
2 K, f4 y' k. R3 d, Q
微信图片_20240525133117.png
: U5 G, A/ o- `  {; a! K* u0 s+ V
% t- c  t, Y/ l  e2 k9 Q触发方式(启动ADC转化)我们选择定时器8,这边可以是任意定时器推荐使用的是低级定时器,这样子就可以控制我们的采样率。
) A0 q$ d) z+ S  O6 X" f$ R* C# U3 h4 y5 F' K
定时器配置6 P+ B2 U7 |7 U# e
这里解释一下Timer 8 Trigger Out event.4 |' g: [  _5 P2 ~3 L7 b

; g3 i, j% H; W: o5 c' ^9 W
定时器(Timer)的触发输出事件(Trigger Output Event)可以用于生成特定的触发信号,以触发其他外设或事件。
* A$ S( m: I+ ~5 a* B' }% L) ?: i0 W' m, Q6 k, ?# Z" x$ a
在STM32定时器中,可以配置不同的事件作为TRGO信号的源。常见的触发源包括:
6 [& N3 X5 C+ W$ u3 r更新事件(Update Event)) N$ s: E5 h* F+ A) o9 J
当定时器的计数器溢出或达到设定的周期值时产生的事件。( m1 z9 o/ Q2 c' H* w$ d* I; {
捕获/比较事件(Capture/Compare Event)
+ j; B! H8 h: t! |当定时器捕获输入信号或计数器值与比较值匹配时产生的事件。  D: ~6 Q3 o; A( _0 C# o4 b
输出比较事件(Output Compare Event)8 ?  x  j( p1 C2 W2 o: y( M& k! |; p& V
当定时器的输出比较单元产生一个输出信号时的事件。/ R! X( F- s+ o, W& m- f: D2 L( O

$ a; z. [8 f/ j4 T% ^' J5 N

& o9 m. p: m/ ~: S, p 微信图片_20240525133114.png
" E; k) I( O) V/ T0 V! x" T

: T+ ^8 R7 f2 A$ W( B: q- z6 s这里设置好我们的分频系数,计数值,设置一个Update Event更新事件来触发定时器采样。这里我的主频是170MHZ,分配系数是169,溢出值是100,这样子过100us触发采样,采样率固定下就是10KHZ。
% {  {9 Z4 C3 A% T: i; f6 V, Z
: }9 Y) ^/ W- M: j2 a: }5 h
我们强调过好几次,根据奈奎斯特采样定律,采样率必须高于信号频谱最高的两倍,当然我们在性能充裕的情况下最好是在最高频率的倍数高一点。
8 _' h7 |- x0 `" q% J. S5 g0 D- L
微信图片_20240525133110.png 2 C5 ^6 E* m$ |0 o; `. K% C) x* c
  h& V6 M- L" ?( B; K) ~! l
最后别忘记开启相对应中断源的中断。2 w/ ~; l" s( v  y- U
7 d; @) f2 T) H% |, j) i7 z. ^4 K8 ^
接着就是创建工程。
6 y3 t( ?% P  C* ?
) `" n9 a6 N# A+ S
  1. #define ADC_Lenth 10241 S* a- L5 d3 b% u
  2. int32_t ADC_Value[ADC_Lenth];
复制代码

/ Y" F; w9 |- N7 ?5 ^5 j' s4 i3 y8 g7 j: B* L. m* E% n3 M
定义一个数组用以充当DMA的缓存区。
* R1 P6 v) P* V# f3 d8 G/ c# x
  1.   while (1)8 L8 _6 @; E4 D
  2.   {, Y+ z5 p  F5 F' p# [
  3.     /* USER CODE END WHILE */
    . G4 T8 ]8 e% H
  4. # Z- t  s: z; V4 k2 b; I" t* w+ y
  5.     /* USER CODE BEGIN 3 */
    ' j, i/ h9 ]: a& @
  6.     // 检查DMA传输是否完成7 v% `" Z7 q- }4 H2 p' h7 V
  7.     if (HAL_DMA_GetState(&hdma_adc3) == HAL_DMA_STATE_READY)# t; `  O/ G+ c; V
  8.     {
    * B( Y7 U! \; C! Z( A" ^7 k, A! V
  9.         // 处理 ADC 数据
    7 S9 s% X% F+ q- z+ l& Y$ g! x: W
  10.         for (int i = 0; i < ADC_Lenth; i++)
    6 U, L3 p8 i# q3 z0 c8 w: w: i
  11.         {
    ( h9 k' b0 D% Z/ L/ M6 @7 T
  12.            printf("A:%d\r\n", (uint16_t)ADC_Value[i]);9 v, F! L4 z% ]3 @: f6 ]
  13.         }
    + Z8 p) s, p* V* ?5 K
  14.         7 C$ @/ N4 H* X& V. W, {" i, F
  15.         + {, Z6 O$ X: p8 k  u# z1 [
  16.         HAL_ADC_Start_DMA(&hadc3,ADC_Value,ADC_Lenth);
    ! k" t5 |6 _  t/ t9 M. Z/ s
  17.         3 i+ g; `. z( ?  L. D  h
  18.     }, w* W4 W% h; q1 _/ T) ~$ \
  19.   }
复制代码

* X0 @3 v7 |: S/ q& T- |- x+ G在主函数中使用轮询的方式等待ADC传输完成,传输完成后我们利用串口打印。) W7 A% ?2 |) f8 |6 d& i
" |) u) L- y0 l0 |6 u) w5 B2 j* ~
我们使用HAL_DMA_GetState函数来获取状态。
  1. - HAL_DMA_STATE_RESET:复位状态' \7 Z% B' Y, T; I
  2. - HAL_DMA_STATE_READY:就绪状态
    6 |+ a% k6 S% D; F6 s
  3. - HAL_DMA_STATE_BUSY:忙碌状态
    6 n% _" B+ p2 m
  4. - HAL_DMA_STATE_TIMEOUT:超时状态% J( y! Z; n- c6 b3 G; n
  5. - HAL_DMA_STATE_ERROR:错误状态
复制代码
当DMA属于就绪状态就说明传输结束。这里有一个坑点,关于: Z3 Z0 _$ Y+ f1 V2 `4 q4 }
' o, f, C$ T8 Z% S0 k
HAL_DMA_PollForTransfer这个函数按理来说是用来查询传输结束的,但是不知道为什么使用起来很奇怪。
+ J6 X; E: I$ ]
% o3 L; \  I2 l: p/ P% r: @" U4 |
微信图片_20240525133107.png & m% [$ {0 n4 k0 k% Q
( M* d  U7 z$ s# U( \; Q
这是我们采集的方波信号
0 h# E) a7 @. l* [$ {3 R
. u! X3 s7 W0 o3 ~9 G1 w0 _
3 p  m9 \. ~: p) D" H' Q* a6 ^
转载自:电路小白& U5 P! w5 C6 F6 t, Z( Q& q0 ^! A
如有侵权请联系删除+ T/ W, e0 s3 h" B) U! O) E( H, r

. ?8 Q' C3 K* N6 f
+ a$ B) r3 \; w" i2 P9 V- Z) s% c

/ U) K2 ?9 \" @
% [0 e' |# e$ m) V, w) \+ A" ~: _
收藏 评论0 发布时间:2024-5-25 13:31

举报

0个回答

所属标签

相似分享

官网相关资源

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