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

STM32CUBEIDE----ADC在DMA模式下扫描多个通道

[复制链接]
STMCU小助手 发布时间:2022-9-5 21:02
生成例程
" e5 |+ d0 o; m$ s5 o使用STM32CUBEMX生成例程,这里使用NUCLEO-F103RB开发板
/ ]3 ^. m% N( ~% e3 I. a
( g3 O& k) f: `- O- ], c 641406f4ab6d4ba3806608ea088511f0.png
: X+ a2 a, h8 X7 H
. h/ N. U# _9 D1 m查看原理图,PA2和PA3设置为开发板的串口。) A4 e3 P+ \" [! k! o, D

2 U* ^- B% j! [( n' D2 T 6cde275d970445afaa522e74e1b05da0.png 7 K, G* _9 d. x1 d' i

7 K. P# K$ q3 D! K& o2 G! e' V配置串口。  s' z1 g: _1 @# S, N  i

* B" L! |* Y( c1 s2 @1 X e5a35949ea484fe782de2237f57d2198.png
& M* _$ I: b1 V. @% x# A$ H( O& S0 V0 d# g6 A2 m4 V* x' f
开启中断。
0 a) @5 @9 N  ]+ ?" o  H1 Z; X/ Z9 [, B
4b8d8ee78fdc425485eb47d05a726d28.png
5 W7 _% j, I) Y
# B4 O2 P& O, I7 G查看原理图,Arduino的接口A0-A5都是AD口。
' q: R/ q6 e  M' J) w8 E
3 L) Z0 H0 O0 |. E, w 3f6de63422a74d5985ce49db60330b90.png 1 A# y* J- w8 m6 h7 o7 n! E

( W1 N4 ^3 M  B" T# ^ADC通道配置; g4 S/ [9 I1 h( a  Z6 @
  j: a1 V* x) v4 s* Z
ADC1        IN0(PA0)        IN1(PA1)        IN4(PA4)
$ w# g2 c& C8 t
2 z# Q& z" _+ ]8 VADC1配置。* y/ x, I, G: m8 W' p* g2 b6 n
+ `: A0 Q7 c) E
353986b1f8d94f9c8f54b326562e89c7.png
% |; M( P" B3 f5 L% S4 n0 s. o6 `2 i9 I# c$ X
ADCs_Common_Settings:
& o, S9 }! S% R  ?# MMode:Independent mod 独立 ADC 模式,当使用一个 ADC 时是独立模式,使用两个 ADC 时是双模式,在双模式下还有很多细分模式可选,具体配置 ADC_CR1UALMOD 位。( o5 u4 E9 H2 U. D. E+ v9 J5 y# t

7 l, {0 U, ~! O/ l: H7 Y; lADC_Settings:
6 W) H; F$ Z( [$ `6 sData Alignment:
; ]4 v" C6 X+ N' i, I8 R0 kRight alignment 转换结果数据右对齐,一般我们选择右对齐模式。
8 T: }$ d+ s/ f6 P1 H  GLeft alignment 转换结果数据左对齐。
' E! \& H1 Z7 a& G' m
* I; W7 p& e: L3 o. rScan Conversion Mode:
7 d8 \( q3 x3 c1 cDisabled 禁止扫描模式。如果是单通道 AD 转换使用 DISABLE。
8 }7 L1 p" r3 O2 m+ z: x) e& z; A2 iEnabled 开启扫描模式。如果是多通道 AD 转换使用 ENABLE。6 x+ M9 j4 ~* U
Continuous Conversion Mode:
( L7 P$ w0 q' ~+ JDisabled 单次转换。转换一次后停止需要手动控制才重新启动转换。; a. k9 @# e; H# b% W+ Z
Enabled 自动连续转换。3 m, c, Q: f( y# p1 W4 `

& j0 l! J+ W1 ]5 _5 J: g% YDiscontinuousConvMode:; {3 Z8 C7 i* M, b- i/ }
Disabled 禁止间断模式。这个在需要考虑功耗问题的产品中很有必要,也就是在某个事件触发下,开启转换。
- Y* J& a" n+ p- \. {Enabled 开启间断模式。
9 F# j% H1 T  A: `0 a5 r. W
. U. V" t$ {" n3 jADC_Regular_ConversionMode:
( H; e2 Q( m+ f+ n; G! }Enable Regular Conversions 是否使能规则转换。1 K6 B& t2 B. T% x4 s# }
Number Of Conversion ADC转换通道数目,有几个写几个就行。
2 U( d1 }4 |- nExternal Trigger Conversion Source 外部触发选择。这个有多个选择,一般采用软件触发方式。/ d6 A  ]- T5 v8 q$ g

% V2 G) f7 c1 `) C- sRank:1 a+ p& j: d) M/ l1 _# R
Channel ADC转换通道) c. X6 a" J! ^; b1 _7 J. [+ F
Sampling Time 采样周期选择,采样周期越短,ADC 转换数据输出周期就越短但数据精度也越低,采样周期越长,ADC 转换数据输出周期就越长同时数据精度越高。9 ]' l8 d8 D+ |7 B# a1 K
; ]# m/ m5 i8 z" F% P) U3 o
ADC_Injected_ConversionMode:  g$ A/ F7 u6 h: Q4 ~9 ?
Enable Injected Conversions 是否使能注入转换。注入通道只有在规则通道存在时才会出现。6 n' |8 t  E3 c9 L+ e7 z! N, \

4 f5 ]5 }1 Z2 Z5 ~# {WatchDog:6 E  L7 T2 l4 i9 I8 h
Enable Analog WatchDog Mode 是否使能模拟看门狗中断。当被 ADC 转换的模拟电压低于低阈值或者高于高阈值时,就会产生中断。
+ e$ l- x9 d8 F2 a5 S! l1 T8 S6 ?- l- e4 ^, V
DMA开启。  D/ R) V6 E) V, j* k
% a4 R8 H. J0 j# q
8d4d5bbaea2f4af4bfffd8dfa349c3e4.png - m5 K2 V& t0 }! Z' ?

( e8 d& D! `% ^* x% [生成独立的文件。
3 i7 Q4 N2 O2 i2 b* T8 y! F% l6 `: ~9 o  S/ O9 f0 J
84777276815a43eeb799f7491a2f8868.png ( m) A" K4 O8 i# V* X

! @6 q  s2 K8 O/ @& ESTM32CUBEIDE配置
# B" D9 @4 o# a- }" r$ p
* ?& `5 P& b% Z+ X) X, y cef307ee88fe48e9927c8672840c37f2.png . X/ w( t% e: G  v( K

  V5 z8 V" Y* a6 B若需要打印浮点型,需要勾选下面的选项。
2 T* m; z- [2 u/ P% F0 y  ]8 ^/ L1 w
0f42e907240242bfbb736c31e9755617.png # w- o% z8 ^+ |+ [) S% @
- ]- a' G) V( _, K3 h' O% Z0 N
串口重定向
5 C5 Q: j5 H& P" _3 A) V在main.c中,添加头文件,若不添加会出现 identifier “FILE” is undefined报错。  ?& W5 x% {8 e  m" @( Z. N
( J" m, ]- _, o- l" u3 p' J
  1. /* USER CODE BEGIN Includes */
    ( q- E! K0 ?2 B0 O. @* s
  2. #include "stdio.h"
    & Z. N/ _7 {: i. J, J5 u
  3. /* USER CODE END Includes */
复制代码

8 J  A$ c0 @; P+ i函数声明和串口重定向:6 U# h, A, Q' L- o9 B9 s

# U' E9 I7 z7 Q1 N) J$ j. P& m) i
  1. /* USER CODE BEGIN PFP */
    & d3 `, V" j: [' ~7 I
  2. #ifdef __GNUC__                                                                        //串口重定向3 h4 @1 _2 E! Y2 A" H
  3. #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)' T# o8 F' n. T; B# Q! m0 W% D( Q" Z
  4. #else+ _5 O. X  m  V
  5. #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
    " z5 }% g8 D3 D
  6. #endif
    5 M" ^1 n9 Q2 {; v5 ]
  7. PUTCHAR_PROTOTYPE
    # l, p" U2 e$ Q9 V. q3 p  X% z
  8. {
    . e' B4 _" Y$ g4 d9 N3 R
  9.     HAL_UART_Transmit(&huart2 , (uint8_t *)&ch, 1, 0xFFFF);
    ! B6 }+ J$ `0 \7 a/ _" ?3 `% _
  10.     return ch;
    ! M& y5 V. B' v% v) }! K+ H6 L
  11. }& ?. a* ~& I5 k
  12. /* USER CODE END PFP */
复制代码
# Z" n; |- b, Z8 L. d
代码
/ k& X( Y# \- b% {定义变量,存放采集到的数据。
* K, r% G! l3 z, s1 L) m4 y* k- A! U/ @
  1. /* USER CODE BEGIN 0 */$ a& l5 S% m( H! x* r6 N) q
  2. uint32_t ADC1_1, ADC1_2,ADC1_3;//采集的三个通道的ADC0 M# A2 `  h$ I& e/ \- j  E
  3. uint32_t ADC1_Value[30];//DMA存放数组
    0 |( J, Q/ C/ {
  4. uint8_t i;
    3 A& r9 S$ e& }0 {( k/ f
  5. uint8_t ADC1_Flag;//dma采集完毕中断
    : L% g, p3 l3 ]- K3 v
  6. /* USER CODE END 0 */
复制代码

6 [- w6 |& U2 p$ S  V4 n' t; a0 D" U
使能ADC传输。
: k  y8 i9 I' y$ y7 J7 ~' y; J# n+ G3 [# g: l
  1.   /* USER CODE BEGIN 2 */) O& W2 J3 H8 M5 X$ k' O4 m4 N
  2.   HAL_ADC_Start_DMA(&hadc1,(uint32_t*)&ADC1_Value,30);    //使用DMA传输
    # s  T2 S- k! f, O2 ?
  3.   /* USER CODE END 2 */
复制代码
7 p9 F) S: w/ a' G4 F# L, E; v( M
主循环。1 l+ ]2 I$ ~5 O* M  s& A
7 T* c; U7 s0 }4 ^  u
  1. /* USER CODE BEGIN WHILE */
    + p! c" _5 a- c
  2.   while (1)
      ~. U' X, G$ q1 }2 U, I+ I
  3.   {
    ! R0 `9 {: k9 V' A- j3 c3 `) V+ P
  4.     /* USER CODE END WHILE */
    1 w5 d0 N) R0 R. @( u, n$ r

  5. 3 v" Z" A/ W5 w. ]6 h% d
  6.     /* USER CODE BEGIN 3 */
    3 w% m5 w$ J: B0 C: |: c4 Y
  7.           if(ADC1_Flag==1)' P( }" @5 c" u0 V
  8.           {
    8 a" r3 N4 V0 y, y! Z
  9.                   ADC1_Flag=0;
    # y0 r, c2 s$ n7 W5 z* [
  10.                   ADC1_1=0;
    # C8 C' e0 W" k" D5 x$ M# E
  11.                   ADC1_2=0;
    9 a! D; y& s7 X5 c8 j
  12.                   ADC1_3=0;% y8 i# m- m- y, R+ v/ L' |
  13.                   for(i=0;i<30;)
    ; x5 M6 H7 K8 L7 L) |4 T9 T3 _
  14.                   {
    % f1 Z. P4 m5 g3 H
  15.                           ADC1_1+=ADC1_Value[i++];
    & F8 j" p# }/ Z. u' T7 m
  16.                           ADC1_2+=ADC1_Value[i++];
    5 S. y/ t7 T4 N* A
  17.                           ADC1_3+=ADC1_Value[i++];
    $ ^, `$ s) O" }
  18.                   }" S' q' @& J) d+ S
  19.                   printf("\n");
    ) m# K6 a# c( N5 |+ [1 h+ X
  20.                   printf("adc1_IN0(PA0)=%4.0d,ADC_IN0=%1.4f\r\n",ADC1_1/10,ADC1_1/10*3.3f/4096);7 Z2 X# N' x% A
  21.                   printf("adc1_IN1(PA1)=%4.0d,ADC_IN1=%1.4f\r\n",ADC1_2/10,ADC1_2/10*3.3f/4096);
    - a1 I: z$ m& Y2 Z" f. S9 y: ?
  22.                   printf("adc1_IN4(PA4)=%4.0d,ADC_IN2=%1.4f\r\n",ADC1_3/10,ADC1_3/10*3.3f/4096);/ Z8 B' X& J4 f
  23.                   HAL_ADC_Start_DMA(&hadc1,(uint32_t*)&ADC1_Value,30);    //使用DMA传输
    9 j* C$ s3 u4 o- I; S. ~
  24.           }
    . e% h5 N% e, _7 w, ]. `
  25.                 HAL_Delay(1000);6 m% C/ d( E6 g* }9 r+ a" N
  26.   }5 X5 a7 k! s' p+ Q, r# c
  27.   /* USER CODE END 3 */
    0 P, j  U* d3 {+ x
复制代码

; Q. i9 S& e& G# _7 p% z2 SADC回调函数。
" w6 q) A3 e( b0 q  H" {3 tDMA传输的时候如果读取内存片段,会有仲裁器的问题,加了一句关闭DMA的语句HAL_ADC_Stop_DMA(&hadc1);# l* n8 G, Q$ ?7 k, g6 p  \
  1. /* USER CODE BEGIN 4 */0 k1 o& b- D# S* H
  2. void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)9 N+ g, |+ j; n9 \( X
  3. {; V3 J: c, P+ Z" Z$ {& {% h
  4.         if(hadc->Instance == ADC1){; p9 w  k; z8 n5 X, {
  5.                 ADC1_Flag=1;4 x/ j0 T5 d  x4 x4 c" u2 `
  6.                 /*
    * {6 E% [2 V4 J# y
  7.                  * DMA传输的时候如果读取内存片段,会有仲裁器的问题,加了一句关闭DMA的语  A& l8 @3 g& t6 p3 E

  8. : ]: |& J% ~2 e% O
  9.                  */9 d  F) C* S8 ~  g7 B
  10.                 HAL_ADC_Stop_DMA(&hadc1);
    % s# U1 B, t$ j. E" R
  11.         }
    1 \9 P3 ]6 Q: B/ Q
  12. }
    # C* y+ i- l/ w$ z& L5 g& T
  13. /* USER CODE END 4 */
复制代码

8 `7 a9 I& ~3 m. X" L0 u% F测试结果# d% n2 n5 m3 A
输入固定电压进行测试。
, Z+ d% F3 w2 z+ ^" t1 x
" H9 y, z. F$ |* W X{A@KZ]UG}WSY2P]VU`_A.png
  K/ o  w; b4 Z3 l& W4 ]# p6 k; |* p7 b+ Z) I: r# e9 B
Normal下测试结果如下。. D+ U8 ]2 r3 V8 K5 g; j( V3 y' W% w

$ i; p5 x0 I$ _ db436b7622d949f68ac746b30fced16f.png
* b5 ^8 D6 @/ U6 j- w6 e1 s
, }1 {0 j, n8 l* Z若不试用关闭DMA的语句HAL_ADC_Stop_DMA(&hadc1);
3 Y2 K5 P' `# |5 f: Z: I会造成数据错乱。
; `! h' ]4 Q& }3 Q, f5 B3 k7 _
0 P' X. n# e3 U) [- p 2b0fc5e363cb4fc5956df5dd3ca626da.png 4 e+ S5 m" M) C. U* Q8 @
+ X- v  w3 d6 @5 u; ]' |' C
Circular可以下可以一直进行采集,不需要HAL_ADC_Stop_DMA(&hadc1)都可。- k  o# O6 @* u. O' h) u/ q
$ R* `6 U# s5 s
4a094bd16f6f42fa8835d83d181804fa.png
' _; Y9 V9 L- b; P
* [( Z5 T' P. a8 t2 h————————————————
2 r5 Z- j' A- m9 ]/ L5 q版权声明:记帖
6 B6 G6 V, _+ u% k; T2 E+ p; ^7 |7 j2 L& D

3 v6 ~0 `" T# p7 p& g  q4 W
赞 收藏 评论0 发布时间:2022-9-5 21:02

举报

0个回答

所属标签

相似技术帖

官网相关资源

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