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

STM32的ADC用法,你知道几种?

[复制链接]
STMCU小助手 发布时间:2021-8-5 11:16
AD采样在电路中是一种比较常见的功能,可以用于电池电压检测、传感器值读取、信号采集等。STM32的ADC,由于引入了DMA,以及多种触发源,功能自然强大,用法也多种多样。这里简单说下单通道情况下,AD采样的几种用法。
/ i! o8 V9 Z4 i1 |' x
7 j; c3 h, t( l; ]" }
1、AD单次转换+软件启动
- x! K1 A, F/ v& q9 j! d0 ^最基本的用法,通过程序启动AD,AD采集一次,我们就去读一次。这种情况,建议开启AD转换完成中断,在中断中读出AD值并做处理。
& s3 q0 p+ ~. S, a8 l0 ^9 T1 b" Y* Y. R" d5 r
6 M! I+ K8 K6 R1 [  |( h7 W
这种方式的优点是配置简单,缺点么,太T么简单~
3 d# w8 C" t/ v+ ~5 t; V7 I- ] 1.png
$ W3 ^  k$ f$ J; c初始化的时候,启动一次。然后在主循环里,每隔一秒启动一次。! b) M/ }6 d  p. s  P
2.png
1 _4 R. W: f" A4 e! G) ^, D8 h( s# c  l' i- n1 g8 R

: S+ t) O. q1 m' V3 d0 r在中断回调函数里,进行相关处理:: ]5 a+ i7 B/ G2 }9 w! @% d/ H
3.png 6 \7 A' O- i5 u% B" c2 X. @
' h2 Q3 v  |# p" O4 j" h3 }

( o# ]6 @! E0 H5 t2 h, [电脑输出如下:
! b( w, ~5 U  U: _ 4.png
( l  y1 l! i* T0 ]: z& T
7 ?" [7 Q9 [: X" s. i7 l

9 a3 w  I* d+ N/ x8 h2 d9 W
2 F' \3 g- X' e" b: i* Q9 B
( m0 P3 s/ Q! t# R
2、连续转换+软件启动. h. T4 r8 W" U1 z1 d  S
在方法1的基础上做调整,从单次转换,变成连续转换。也就是说,只需要开启一次,它就能一直转换,直到程序让它停止。/ ]% [$ s! M8 N, O% e
3 }, H4 w# _4 r  M" J

! j( {" x( f/ G  |/ s$ n. a优点么,省去了频繁开启中断的麻烦。缺点么,需要频繁进入中断去读AD值。配置如下:
1 s: E  R( p& _6 L  t+ C 5.png - L" o8 k, Y/ P5 p/ X8 u$ a6 p2 g/ N

8 w% s* Y1 T1 p' T2 d1 q
: [7 k+ l/ u* P% p' v, Q2 p& B
初始化的时候开启AD即可,后面无需再频繁开启。
$ D9 m3 Q: Q: P9 r8 z# Q 6.png 3 L8 S% ~  z9 j5 s) F( v
* \/ y& P* m  _5 y0 u+ O, I
! w+ f0 O5 W" M- Y& a
在中断中进行处理,当AD转换次数达到1000次的时候,停止转换。
/ b1 b! T- P- B: M
$ `( [% Q9 j5 f# M0 c

% c* D' A; ?$ K9 c+ H注意事项:函数HAL_ADC_Stop_IT(&hadc1)  需要在中断内调用,中断外调用不起作用。2 X2 {0 a# S  B7 Z( J
7.png # c6 g- D( D* y" I: b. |7 |  e
8 H  c- T, q5 i: X( E/ N) F+ H

1 C: i3 C/ ^* _9 _. f  d9 Q
: |6 E7 Q8 q. p' `! S3 N+ b8 F# w

: j  Y4 W* M9 C5 |& A3、连续转换+DMA+手动启动# A0 h2 _* o5 c* q5 o; d

& e# q4 p& P, E, t) S  \- o# ~
4 v4 K) E8 h0 O' Y7 _  s. B
在方法2的基础上,引入DMA这个东西。不得不说,DMA真的是很方便,省去了很多手动操作的麻烦。可以直接把指定数量的AD转换值存入数组里,可以单次存入,也可以循环覆盖。4 Z0 E9 R: I/ w2 v
' x( A3 P: a: s0 p4 T' W) b

4 \* ]- d7 D/ Q在方法2里面,每次转换完成,需要我们手动去读一下AD值;启动DMA之后,完全省掉了这个过程,只需要等待1000个值全部转换完成之后触发一个中断即可。. \( k/ n& v( R! m

9 A. g: ^# l, @& o" J1 X
" O& N( \7 R# F; B8 C6 q" O
8.png 7 |/ P9 h& r# W9 \) v  A
. |: l+ ~0 V  v$ o$ B, c, p

* V0 c  S+ p% q# ]  |初始化阶段,开启DMA传输:
, M* `( B8 p6 B/ K8 i: h3 P! m1 y* f

9 G0 d# p6 }$ n# c2 W 9.png
& g  Y/ ]+ X1 t3 ]; t  m* U. r/ j0 G7 Y1 v) e
5 }4 s4 n* U4 F0 W
传输完成之后产生一个中断:9 p" Q) U. D& X$ ?6 Q% H! a

6 G; r% R& K# P; c( K1 I# O

) |/ f+ m+ ], \( D 10.png
' c, T6 ~9 [' s( |! J2 d" ]% ^& M/ P( g

0 v6 N2 {; P. O; a这时候看数组里面的值:
1 h* E; Y1 x8 j; Q) }6 w 11.png . {$ }' S) X; w
( }3 }8 C+ E* h9 C4 F( Y1 C3 B

, ~& C, R( \& p/ ^, v# K% f
9 t! o! K2 `+ B: d) j# g" v

1 S2 o; @5 D5 J- W, f! i) K* W4、连续转换+DMA+定时器+手动启动' g* m, N; g7 i  a

% j: J# u/ Z8 x( u! G9 U$ L2 A1 [

. l/ S) D8 q& f% H方法4是在方法3的基础上稍微做了一些调整,主要面向的需求是:固定时间间隔的AD采样。比如说,每隔0.1秒,需要连续采样100次。6 ^% m# }& Y. S) r

: o' ^) w* [$ G# Q' E
/ h6 z, W1 }7 d5 v) t& m
通常的做法是,使用定时器做一个定时中断,在定时中断里,调用函数:/ Z( i% l" q; D6 A
- _1 C) N) C9 J1 E1 `, V0 q: b; j

9 D9 ~" P" E8 O3 {HAL_ADC_Start_DMA(&hadc1,(uint32_t *)ad_value,1000); //启动,同时开启中断
1 B: Q3 ?; @. i+ v0 y$ l; r6 B- q, [' J
1 Q, y% B; `; E3 I
* P- ^& P( w6 c2 |$ r
方法和原理都比较简单,就不细说了。  A4 P% M7 {! z6 Q6 a

9 X1 I- \- C7 L* w
# n" ?7 G  e7 ?; D8 r
4 {; o  `# D8 e; @

; n8 `0 u) h" I8 o4 [. R) w5、连续转换+DMA+定时器触发0 ?) [2 d# q6 V3 h
* l/ C% l7 g- C( [8 J# y/ h, ?1 B3 r
& w) e; R6 }' s/ g
方法5是对方法4里面的需求的实现过程进行了优化。STM32的定时器可以自动触发AD转换,省去了手动启动的麻烦。例如STM32的TIM1,TIM2,TIM3和TIM4,以及外部中断,都可以做为启动AD转换的触发源。
  r& I  c8 D2 X( \8 d: H) }$ W9 @  w- k9 a) S: k/ Q* `3 L: ^7 R
9 g+ O7 w( s7 z  D, H
以TIM3做为触发源为例,如下:0 E1 ~! H- G$ ~# ?3 I
12.png
* O& u' p: z. I
* _" l3 z8 j$ m3 v# ?

& m  F/ y2 V6 A! M% f7 _% H5 xDMA这里要开启循环模式:. H& l. L/ F! ?  \  n' f
13.png - Q- [/ {$ n5 x5 [" v- f# p
0 f9 E5 H! y$ u+ U

2 X# J+ r8 p5 l8 C6 B, G% R4 {TIM3的配置如下,这里实现了一个1ms的定时,也就是说每隔1ms自动触发一次AD转换:) G7 g; C& G% F& F
14.png 2 m* b$ V* m. j0 ?6 I
/ f7 i) T/ b: p+ X% t6 L1 N% x
; }& X) F% y/ P5 Z, J( i
主函数里代码如下:
  \1 Z- k' F* H% M5 y 15.png / L8 S% J6 @8 P  t5 s& ]
2 z; `7 m% q  C0 ~. H

3 H3 _0 `' d, a" x: s然后中断里做一下处理即可:
' z7 z1 c) K3 P 16.png
' ?- |1 `# y7 u, j1 O
3 d8 I1 [6 t  \! A' b
" p/ }4 ^$ K: q. s  `
好了,对ADC的使用方法做了一下简单的整理,当然肯定不止这些,必然还有别的玩法。这篇文章以思路为主,没提供代码感兴趣的可以慢慢研究!
% t. D+ t5 {) Q1 P% ?* V! }  C2 Y  w( N* G* ?* }% b: @
4 @5 H/ ~" \6 q- U

! g, g8 X1 l5 V+ S# v$ K

( C! H# _( C. O8 S
+ {* G/ U  _0 b, k. R. A
' A, m: Y, L8 u. C
# g9 n* X. c3 }

4 i; v: w2 U7 R, ]9 ?- r: O4 Q9 H# y5 Q2 D* v; c

  m9 W) F1 l& W  H  G, K' m- c0 B; _: |, e4 }9 \. e) [
2 I2 z3 z/ w4 t" X" C

  @4 w+ s/ T: \
0 ^/ U  i8 P4 }' m8 }2 Z
赞 收藏 评论0 发布时间:2021-8-5 11:16

举报

0个回答

所属标签

相似技术帖

官网相关资源

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