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

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

[复制链接]
STMCU小助手 发布时间:2022-9-5 21:02
生成例程
$ J! f) m3 G/ {. C: z7 k  X使用STM32CUBEMX生成例程,这里使用NUCLEO-F103RB开发板  z, \; C- R( T: G
( O) P1 H1 \% T: H1 f
641406f4ab6d4ba3806608ea088511f0.png
' d; s8 R- A, t1 W
, K6 ]. t4 Q8 S6 M查看原理图,PA2和PA3设置为开发板的串口。$ t# a4 I* E% r* x' d

2 B0 p2 \5 Y+ r- e: `9 E) g$ x 6cde275d970445afaa522e74e1b05da0.png $ `+ J% c5 I& u) L+ T* E
1 k) Z: ~( I0 Z. d4 w$ A( O
配置串口。
$ i; V4 T/ c& i! T8 \6 E. ?- {6 `6 m* U- b6 b" Z
e5a35949ea484fe782de2237f57d2198.png
) U6 M8 I, V) a$ d) |
/ Q, t/ J! X& W5 U. Y( c: k5 c/ l开启中断。
6 I4 s9 K" E2 _9 z! n( ^7 h
- U# k, C5 V1 B9 x 4b8d8ee78fdc425485eb47d05a726d28.png
% W6 ?/ D# n. S$ `1 @2 N/ Z  T" k7 W3 G2 s1 Z3 k
查看原理图,Arduino的接口A0-A5都是AD口。
$ D. f" j# g5 [1 u  g) K4 ^; n5 u
7 W+ j+ R6 q  Z: Q- N# p 3f6de63422a74d5985ce49db60330b90.png
) ?! |3 r3 _( U% M9 }1 Y
2 [4 P3 F& {2 t$ L6 c$ e# H5 @ADC通道配置- F1 K+ D, g/ }

9 p$ [- l7 R7 F* H* j& ^( bADC1        IN0(PA0)        IN1(PA1)        IN4(PA4)7 t) u2 f0 x8 F7 K# t% V

. ^7 Q% i* v" D/ n6 @1 jADC1配置。
$ j9 y* e9 I* `, c
0 v# l* F) i$ i5 S. k0 F( o 353986b1f8d94f9c8f54b326562e89c7.png * w# P# I0 n, Q% F( ?3 x) a
+ ^% |' h, k  r$ M
ADCs_Common_Settings:
; L# Y  l- e! e9 ~2 TMode:Independent mod 独立 ADC 模式,当使用一个 ADC 时是独立模式,使用两个 ADC 时是双模式,在双模式下还有很多细分模式可选,具体配置 ADC_CR1UALMOD 位。
% X; I9 r+ U, k, V2 y
: [9 e: I% k/ c! I  |8 ?ADC_Settings:
9 o3 `+ b8 G+ X' O  DData Alignment:
0 B" N4 \7 r9 VRight alignment 转换结果数据右对齐,一般我们选择右对齐模式。/ B/ \" T& B2 `& t9 g
Left alignment 转换结果数据左对齐。$ c2 X6 l/ f6 Q8 f( T: M
0 n2 r8 G& }- y  L, x$ H  z
Scan Conversion Mode:
3 L$ s4 Y9 c& p+ q1 q7 `, E! zDisabled 禁止扫描模式。如果是单通道 AD 转换使用 DISABLE。
  J( I% H: `$ L+ |* TEnabled 开启扫描模式。如果是多通道 AD 转换使用 ENABLE。- z; {/ T- P0 s( `- ]$ }
Continuous Conversion Mode:+ `: O; `* ^: g) J2 @
Disabled 单次转换。转换一次后停止需要手动控制才重新启动转换。9 t% H! U8 h& [
Enabled 自动连续转换。) ?) N5 V* G( A6 W

0 {6 S& I3 x* UDiscontinuousConvMode:- v0 k; x; F9 `3 J4 ?
Disabled 禁止间断模式。这个在需要考虑功耗问题的产品中很有必要,也就是在某个事件触发下,开启转换。
8 E$ Y" j" m2 x" KEnabled 开启间断模式。
9 B4 d/ @4 k$ q9 Q+ E0 E$ |, w! F( @  ^% G+ q) [* z. t9 l; _
ADC_Regular_ConversionMode:% E6 ~4 e  r3 a
Enable Regular Conversions 是否使能规则转换。
5 }4 K. \9 h/ {$ G6 V1 l% W# P) B8 lNumber Of Conversion ADC转换通道数目,有几个写几个就行。3 |+ L; |6 V' {
External Trigger Conversion Source 外部触发选择。这个有多个选择,一般采用软件触发方式。9 g& w8 r$ `$ h- r7 c
+ o2 B, l7 V% ^, @1 ~; b
Rank:
0 g+ n# V" w/ kChannel ADC转换通道
6 ], U5 u& x! e. [3 }% v$ ?Sampling Time 采样周期选择,采样周期越短,ADC 转换数据输出周期就越短但数据精度也越低,采样周期越长,ADC 转换数据输出周期就越长同时数据精度越高。% D0 F2 K: ^7 @' i

0 C  b' F2 V0 ]* e5 t/ }: `ADC_Injected_ConversionMode:
3 J" T0 j; ^* eEnable Injected Conversions 是否使能注入转换。注入通道只有在规则通道存在时才会出现。
  E0 c" b, N) S: _7 ^3 g
2 B( t3 c2 M9 _WatchDog:* X5 A4 e7 Z- r+ G9 g3 x& H  M5 D
Enable Analog WatchDog Mode 是否使能模拟看门狗中断。当被 ADC 转换的模拟电压低于低阈值或者高于高阈值时,就会产生中断。
; T* g) Z7 s* U9 h2 U# r3 H- D& H% P! X0 c
DMA开启。. {4 w/ K# L0 k" _; r/ [" F

+ w$ \+ G7 X% f$ ]: j2 r 8d4d5bbaea2f4af4bfffd8dfa349c3e4.png 7 |. d5 F8 U$ v, E

1 Q8 f6 V# |5 k0 }1 Z0 P生成独立的文件。, |4 p1 r8 F  S! p8 D
" }3 C+ h% t7 W: C+ z7 U5 c
84777276815a43eeb799f7491a2f8868.png
/ B; X, ?% S9 k( `5 u4 C6 }: n5 y( e8 l
STM32CUBEIDE配置4 I7 ]  w1 Q3 t+ Z2 U0 U% C; Q
  \3 b7 J2 H% O& j0 D8 f( I
cef307ee88fe48e9927c8672840c37f2.png 3 P' w. Q3 G) ]8 g

" S  r  y0 F  o3 ?9 k6 [若需要打印浮点型,需要勾选下面的选项。: u4 k: w; A: ?8 y6 X9 A
) i- C+ a& P$ R' d
0f42e907240242bfbb736c31e9755617.png ( ?" d8 z9 s, l: z1 [# A
6 G) f  w3 _' B6 s
串口重定向* @9 |6 O2 K, z: @6 Z: I4 o
在main.c中,添加头文件,若不添加会出现 identifier “FILE” is undefined报错。
! @+ w" s) K$ G4 q0 y: F9 r# _3 x3 y& i$ \: C0 c
  1. /* USER CODE BEGIN Includes */; D" b5 r9 j% J6 ~2 q
  2. #include "stdio.h"
    ! h. a% S6 q& A; Y
  3. /* USER CODE END Includes */
复制代码

! g  |, k! C$ V  c函数声明和串口重定向:+ `8 J- r, p% G  L& M
. B) b( H# N" [' f6 _! R/ c6 E
  1. /* USER CODE BEGIN PFP */& L7 Q$ J6 {; ?) t: R, n! E
  2. #ifdef __GNUC__                                                                        //串口重定向
    ! Z* r4 @0 V! d* q, `
  3. #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
    , i9 G: S3 s0 A
  4. #else2 _9 D# X9 R# S# P& C6 p; _9 Y4 l
  5. #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
    % t5 `& n6 [( m& y0 U5 x( B
  6. #endif 9 H+ g/ y5 W' _7 }7 k) {; `
  7. PUTCHAR_PROTOTYPE
    & P8 y& ?" ?2 U; y* j4 F) ?
  8. {
    1 l1 |+ C2 H. @( i5 b; Q+ k6 F; ^
  9.     HAL_UART_Transmit(&huart2 , (uint8_t *)&ch, 1, 0xFFFF);
    ; z: q. O6 ?' r4 b  V
  10.     return ch;( r& J+ a2 m' Q+ W+ k
  11. }
    % _% s8 k' d/ K9 e& X
  12. /* USER CODE END PFP */
复制代码

! F% V! P: S; W* X代码9 g7 v4 x- L9 o8 H  ]3 [( K0 K
定义变量,存放采集到的数据。
& _$ \6 P! X1 |: O) W# h4 D; K& S2 H
/ H9 T+ _. o. I% y9 t# q
  1. /* USER CODE BEGIN 0 */
    ; X, @6 J; g/ [& V) p
  2. uint32_t ADC1_1, ADC1_2,ADC1_3;//采集的三个通道的ADC  s" X6 ~1 _$ n
  3. uint32_t ADC1_Value[30];//DMA存放数组) k9 F7 _6 P/ G8 ^1 r8 C
  4. uint8_t i;
    . M. P2 }. I" S$ Q  B$ |* J8 b! b( |
  5. uint8_t ADC1_Flag;//dma采集完毕中断
    " _5 V" t3 C2 S3 s+ ^
  6. /* USER CODE END 0 */
复制代码
% p. O- \0 t! [6 t5 S7 N* G
3 b3 S) U1 h# c# n; M9 A* \
使能ADC传输。
4 K* [8 b3 g5 a3 c0 R# L. b& \5 C4 @/ v/ Q( _2 ^
  1.   /* USER CODE BEGIN 2 */5 o' U+ }: [) q' d7 B& v) o& H  n0 ?
  2.   HAL_ADC_Start_DMA(&hadc1,(uint32_t*)&ADC1_Value,30);    //使用DMA传输! _! w# H& X. O) O
  3.   /* USER CODE END 2 */
复制代码
( ?# [$ p8 n6 y5 D) [% M& V$ [
主循环。8 u, ^8 Z4 \- |. {- H

9 w2 {' k) K$ B) ]: _5 h5 A* d8 m
  1. /* USER CODE BEGIN WHILE */% Q+ I$ b! L. a# m) [, o
  2.   while (1)
    ! e( k3 P0 y! ?- R
  3.   {- ~) a0 H$ a& E) q2 }
  4.     /* USER CODE END WHILE */
    * i" X% k9 k% v( [
  5. ) t( g  \2 @( z" M" m6 {9 D  B
  6.     /* USER CODE BEGIN 3 */% Q2 c1 {$ ?& I$ W/ {
  7.           if(ADC1_Flag==1)
    + M, a8 @) Z0 u9 T3 n( ^  g& K
  8.           {+ k) ^" h6 f! i( M( m+ d" P7 E
  9.                   ADC1_Flag=0;: \3 o9 u/ E) m9 g; ?1 w
  10.                   ADC1_1=0;$ L1 e  N. l: D
  11.                   ADC1_2=0;
    1 y% p# k- W2 N
  12.                   ADC1_3=0;
    ! Z5 x; B# |/ [1 O
  13.                   for(i=0;i<30;)8 Y) \7 k9 j- O* w+ R
  14.                   {6 r/ D0 i$ ^* M
  15.                           ADC1_1+=ADC1_Value[i++];
    - K- Y$ R: c5 D
  16.                           ADC1_2+=ADC1_Value[i++];. k# G+ C2 f7 N
  17.                           ADC1_3+=ADC1_Value[i++];1 S; S: O/ ?8 G4 _% ?* `3 U! p- v
  18.                   }8 u. M$ m/ M% `/ [% y
  19.                   printf("\n");
      W  S0 y0 l& L
  20.                   printf("adc1_IN0(PA0)=%4.0d,ADC_IN0=%1.4f\r\n",ADC1_1/10,ADC1_1/10*3.3f/4096);
    & ^) J' o% U" Z1 h& k
  21.                   printf("adc1_IN1(PA1)=%4.0d,ADC_IN1=%1.4f\r\n",ADC1_2/10,ADC1_2/10*3.3f/4096);
    # L0 a& L% W8 [& ~7 M5 Y8 p" P
  22.                   printf("adc1_IN4(PA4)=%4.0d,ADC_IN2=%1.4f\r\n",ADC1_3/10,ADC1_3/10*3.3f/4096);
    . e! P  T. a' ^& B1 F/ `$ s+ `
  23.                   HAL_ADC_Start_DMA(&hadc1,(uint32_t*)&ADC1_Value,30);    //使用DMA传输, y* Q" U6 d7 q$ ?
  24.           }
      p. T" Z5 y: h( c
  25.                 HAL_Delay(1000);, Y0 e) n: F; ^4 Q+ F5 `
  26.   }# \$ o2 I, b3 o: O2 ]! z, w2 n& X
  27.   /* USER CODE END 3 */
    ! q, @* {+ a  C( ^+ A" K$ Z
复制代码

& v' {  E0 N9 ^ADC回调函数。
) e6 T5 p7 y1 R! A7 H4 fDMA传输的时候如果读取内存片段,会有仲裁器的问题,加了一句关闭DMA的语句HAL_ADC_Stop_DMA(&hadc1);
2 A+ l) B3 `. o# S- u# q: W- R
  1. /* USER CODE BEGIN 4 */; Z) h: F% [+ l" x: {: [! n$ e
  2. void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
    + L1 e9 m( v% n8 ^! e
  3. {
    + j% c0 ]9 Q7 k- l# B% N5 A6 ]
  4.         if(hadc->Instance == ADC1){# k4 [# ?7 E) ~! r' L/ B, Q
  5.                 ADC1_Flag=1;9 k8 |7 q' \* F/ ?+ F
  6.                 /*3 F2 G" N7 V1 b9 T
  7.                  * DMA传输的时候如果读取内存片段,会有仲裁器的问题,加了一句关闭DMA的语8 i5 Q. `/ _) B7 i2 P5 I% _

  8. 6 I, r" t6 P9 s8 e% f2 W
  9.                  */5 e2 w4 J" E: S! _4 U
  10.                 HAL_ADC_Stop_DMA(&hadc1);
    7 t) \9 I- m! ]1 ?) l* u# U
  11.         }
    $ k$ a- b0 |$ |& @
  12. }, P) m4 P0 e: s' }% X. G& D3 |! j
  13. /* USER CODE END 4 */
复制代码
  b+ S: W- i7 R) G  Z
测试结果8 M# u  |/ @: i& _2 n0 a; w; j
输入固定电压进行测试。$ M0 w* R5 Y/ z. F7 l
! M$ ?! `+ E5 o- D$ F3 P, O
X{A@KZ]UG}WSY2P]VU`_A.png
% |# ], c8 B% h  M
( \% p) u, S$ C2 G1 H  o( CNormal下测试结果如下。8 T  L1 U; v" z8 b$ a

9 z, D9 k" a1 }8 q db436b7622d949f68ac746b30fced16f.png
! q) c: M8 N* g/ f: |, Q: _
5 J2 i6 n1 [; h0 _3 `' d4 |: ?$ S2 c若不试用关闭DMA的语句HAL_ADC_Stop_DMA(&hadc1);
0 M; [; L8 M7 Y' v$ q; r会造成数据错乱。
0 i# Y- U  s" K, {" c3 W! w0 A9 R  s  o% O
2b0fc5e363cb4fc5956df5dd3ca626da.png 4 M1 U9 g, m$ y# V" x6 b9 A
3 D8 o# w* F( g! d* B
Circular可以下可以一直进行采集,不需要HAL_ADC_Stop_DMA(&hadc1)都可。
! \6 r4 l0 ^9 [
: K6 |( L% l+ p: d 4a094bd16f6f42fa8835d83d181804fa.png
2 ~9 m  U- m% [0 M
7 t2 {. B; k$ [( ]3 n1 u* l————————————————3 z( z3 c8 U7 G" Q$ m
版权声明:记帖! a% M4 ?: |! G7 X

3 t$ ?; A& Y+ i3 l# U; Z- Y5 T& ~- l8 ?  f, j) d3 v
收藏 评论0 发布时间:2022-9-5 21:02

举报

0个回答

所属标签

相似技术帖

官网相关资源

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