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

基于STM32使用ADC的多通道采样经验分享

[复制链接]
攻城狮Melo 发布时间:2024-5-25 15:47
本期我们介绍使用ADC的多通道采样。
& W! g% ~4 j5 V: s1 c1 n8 C; h( X6 J
! l0 O6 l( n( _' Z- j. u  M$ x8 M 微信图片_20240525154648.png ; P4 ?$ J8 b  j, i

1 |# m+ h) J+ k6 C7 R2 z首先我们需要明白一个ADC外设通常有许多个通道,合理的使用这些通道可以实现多个采样点的采样和利用多通道弥补采样率不足的问题。2 B% r- n) j* o2 I5 Z- d4 l$ Q: B
9 i9 y5 [- H/ j* o) f6 |0 K' P, V
首先我们需要知道,我们并不能直接获取某个通道的值。+ E( d" E0 V( L2 f5 f
/ S3 R$ g5 J9 p, O2 h+ s- ?
微信图片_20240525154645.png ; {1 H& E$ A0 p" X7 f
2 E: Z+ ?  d0 U3 s) v& q' h: r
我们HAL库中的函数的函数仅有一个参数需要传入,因此我们不能直接的获取ADC的值,这时候我们就需要明白我们的ADC的转化规则。
5 S+ ^  |4 w! i' y% {
+ |5 z9 g3 N* C% Y/ Z 微信图片_20240525154642.png 3 J) E# d/ A5 F& r$ V

. r6 x* O6 ~6 g+ T' @  J0 ?) N在CubeMX中我们开启两个(或多个)ADC通道
3 s! y/ |. w. `" K# D$ G7 ~& R: o
# u7 S$ W* c0 ? 微信图片_20240525154638.png 2 v1 M* u5 @* U# E
, J; ~6 _4 n. V/ @
开启扫描模式和离散转换模式,重点是这个离散转换模式。
0 W7 R( ]4 d# K* Y; j  t. o1 B
, m7 {2 i$ B2 w+ Z: [  R$ \; W  \, r' L
允许在单个触发事件中执行多个ADC转换,而不是在每个触发事件中执行一次转换。这对于需要连续获取多个通道的数据时非常有用,因为可以在单个触发事件中获取多个通道的数据,而不需要多次触发。
- }/ }, Q! c; v: ?3 u/ f$ g+ C* f
9 i% B8 t6 S1 o2 ]& v
这里的触发事件我们可以选择软件触发4 S. P9 u# f6 a' d$ n. \, ]" h" x) L
2 T) z7 t. f3 w3 @* J  w
微信图片_20240525154635.png
6 U  d7 K# k( y0 L0 O5 ~
- z7 U% f  Q6 c0 ]- y8 h: B
这样子我们调用HAL_ADC_Start的时候就会开启ADC转化。; |" t! Z, `4 ^" T6 v

! i; ?5 R4 F0 [8 a4 X 微信图片_20240525154630.png 5 T5 I% W& q! s% }/ A

# p0 N7 q5 I  a在下面的规则中规定我们的转换规则,这里我们是先测量Channel13再测量Channel11,我们调用HAL_ADC_GetValue的时候就会按照13->11->13->11.....的顺序获取我们的ADC的不同通道的值。
( |! x* D9 N: u( D
* d8 |) `& t/ M% i
所以假如我们开启了4个通道,那么我们的多通道采样代码即可这样子写:
! @% g# l0 [3 Z2 \
  1. uint32_t adc_values[4]; // 存储4个通道的ADC值
    , _& ?; j4 @% M. O  q  |4 _; r. K; R
  2.   1 V2 P3 l1 [8 S
  3.   while (1)' ]7 ~9 R9 S0 M- S( N
  4.   {" M# Y$ C0 m" S
  5.     // 开始ADC转换
    . h" ]% \, b+ \; c2 L
  6.     HAL_ADC_Start(&hadc1);- F2 U6 s2 y& t0 a
  7.    
    5 `" c5 f! w  z: |! \
  8.     // 依次转换4个通道
    4 n% u) }0 y! V% T6 E/ M  X6 ?0 n
  9.     for (int i = 0; i < 4; i++)
    ! e! u1 A( p2 X% S/ U/ w; [/ k
  10.     {) u) }! ]5 N6 X$ E5 \) R2 }! v! [
  11.       // 等待转换完成
      Z7 J4 R+ y& y- F" n- @
  12.       HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY);  r8 t0 z9 p2 W) y1 D- U+ n8 |
  13.       // 获取ADC值
    - R' E: K/ y/ d0 I
  14.       adc_values[i] = HAL_ADC_GetValue(&hadc1);" A) Z( @( d3 _, H9 J$ A
  15.     }
    * [. C7 b) k& k4 m' F
  16.    
    : J+ s! S& b: j
  17.     7 B' l$ C. A. ]+ q- G5 Q
  18.     HAL_ADC_Start(&hadc1);//再次开启采样
    8 o# g, Y7 O) _# R/ Y3 j% ]) L- q
  19.    
    # l1 j" o, F. h( h/ p# t1 D
  20.     // 在这里处理ADC值; L# s+ w# v. L( E1 p
  21.     // adc_values数组包含了4个通道的ADC值
    " n' q# q1 ~  a  v
  22.   }
    : Q. N, g/ F# M3 P  v3 ]6 r
  23. }
复制代码
3 r  g( \8 X3 E0 Y. H
这样子我们就可以获取四个通道的ADC采样的值了。
9 Y% H5 E, a. [! g( @# J" U* v. _. E8 A- f/ Z/ |% q
DMA
* g$ v4 K$ }% B! J5 @
同样,如果当我们配置了多通道DMA的时候,并且设置定时器实现采样率设置。$ q- Y( p, r7 G6 f* E
4 x0 D$ b- Z. l- |) u# U5 l
我们需要明白的是,DMA只是帮助我们为ADC的数据提供存储区,这样子就不需要利用MPU进行读取数据存放数据的操作了。& U- |% a4 V  ], X
, }0 e$ F6 \" @! q; I
因此配置DMA并不影响ADC的采样规则,只是存入DMA缓存区的顺序发生了变化。
+ {0 F9 T- A% q( w0 L4 d0 t
  1. for(int i = 0;i<Lenth/2;i++)6 K: h! q+ Q, k! \) p2 d* {; q  z
  2.     {$ S6 U" Y9 C' ~- n3 w* I6 P
  3.       ADC_V1[i] = ADC_Value[i*2];  T7 Q/ w; ^/ r8 G4 V
  4.       ADC_V2[i] = ADC_Value[i*2+1]$ c( k% T5 H% k# t6 E/ k5 c9 `
  5.       
    0 {6 d7 R" v( P- [  g
  6.     }
复制代码
' `+ u. k4 f6 ]! v
因此了解DMA的本质与多通道ADC采样的规则就可以实现多通道的ADC连续采样啦(不过这样子采样率会减半)。
7 B& j. M5 @  W9 M$ h! o
  M; H) z+ J8 \9 F' ^5 T- t
8 ?) E  Y" q8 Y9 X( o+ y
转载自:电路小白! x5 a3 [7 x0 W( R+ \% ]  W
如有侵权请联系删除
0 V" i' s& M# x

0 J7 w, `% @& i1 Q& u) f+ c  X  J* V& m( c

* \# |# L" |. A+ K
收藏 评论2 发布时间:2024-5-25 15:47

举报

2个回答
喻皓文 回答时间:2024-7-12 14:23:01

stm32F104测试,四个通道数值都一样,感觉不太对,而且接3V3后,只有最后一个通道数值有变化

image.png

![image.png](image.pngimage.pngdata/attachment/forum/202407/12/142159m8ssww2jk1269m3j.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "image.png")

9991 回答时间:2024-9-10 16:28:34

喻皓文 发表于 2024-7-12 14:23
stm32F104测试,四个通道数值都一样,感觉不太对,而且接3V3后,只有最后一个通道数值有变化</p>
<p>![image. ...

[md]没读取一个通道都要开启一次ADC,把他也放到for循环里面试试

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版