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

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

[复制链接]
STMCU小助手 发布时间:2022-8-18 15:57
生成例程
# z+ U- t6 N$ o+ r& L使用STM32CUBEMX生成例程,这里使用NUCLEO-F103RB开发板
' v0 }6 Q: h( ]7 S. y 641406f4ab6d4ba3806608ea088511f0.png 6 U) s( r3 k& Z
4 B# i* M5 H" S8 s5 e4 t6 W) [
查看原理图,PA2和PA3设置为开发板的串口。& A5 i( G, V6 _* h8 c
  P% q- v, B3 _& b
6cde275d970445afaa522e74e1b05da0.png
; h8 N4 u  j* k! j0 n) E6 \
6 F: \' C3 l4 T配置串口。
  y9 i" X/ h' c% X* N
' j9 }! G1 ^- ]! R2 }) @; H  N7 m8 } e5a35949ea484fe782de2237f57d2198.png
2 i8 \: p" W% _& M( j
( f2 H/ P& f2 k! }; x. [! @开启中断。
+ h& T  O/ l6 P1 u$ ^- f
4 H  [% t- `9 N% w3 d 4b8d8ee78fdc425485eb47d05a726d28.png
. C8 W* P& C1 Z" @, Q
. Z" o! M) _0 z3 K. Q查看原理图,Arduino的接口A0-A5都是AD口。+ b- p, ]" L: q3 `; N
! N/ S) {; U. K  }) }$ x
3f6de63422a74d5985ce49db60330b90.png + Y! B6 Q  \5 T* ~3 J$ {

5 I9 N7 D: t3 _9 p' rADC通道配置& I, g7 B# U) z9 E

% P2 h" O% Z- O  U; J4 e! r5 ~ADC1        IN0(PA0)        IN1(PA1)        IN4(PA4)
9 {( S: L+ X4 F" q' v
& j2 m8 _' l4 L5 UADC1配置。# A; o8 ~- H& L  s7 V( B! i- Q

  X3 A' P3 m5 V! Z: _4 Q4 r 353986b1f8d94f9c8f54b326562e89c7.png 4 u. V! h4 c' |1 C! V) k' ]% h
! q4 \* C0 L8 _9 G
ADCs_Common_Settings:" G; \$ R% [4 _" y  F7 t4 d3 X
Mode:Independent mod 独立 ADC 模式,当使用一个 ADC 时是独立模式,使用两个 ADC 时是双模式,在双模式下还有很多细分模式可选,具体配置 ADC_CR1UALMOD 位。6 H4 b$ [: y1 G: x) R

4 @7 E3 r& J! L' Y: pADC_Settings:8 P1 v/ h+ E6 f& j1 z4 ~
Data Alignment:; t1 F' p) q% Y2 ^& o* k
Right alignment 转换结果数据右对齐,一般我们选择右对齐模式。. b1 Z5 E6 h  ]0 Y
Left alignment 转换结果数据左对齐。
0 q: W& |) i7 KScan Conversion Mode:1 I% t( o- t8 t7 u9 M
Disabled 禁止扫描模式。如果是单通道 AD 转换使用 DISABLE。
# t' g% x" J! g7 K4 z* n, q+ zEnabled 开启扫描模式。如果是多通道 AD 转换使用 ENABLE。$ K0 }9 B2 W4 Z9 Z4 E; e
Continuous Conversion Mode:. u9 G5 `% ~8 C* O) m6 ]/ E8 b  {: N* j
Disabled 单次转换。转换一次后停止需要手动控制才重新启动转换。
$ `  o; Z% U$ n  e& ]0 OEnabled 自动连续转换。
  t. P/ }5 z' e+ E$ `, J! uDiscontinuousConvMode:) d5 E( F- h. U
Disabled 禁止间断模式。这个在需要考虑功耗问题的产品中很有必要,也就是在某个事件触发下,开启转换。; ~' N9 t+ u0 T2 D) b
Enabled 开启间断模式。
# Q$ {7 q/ I" Q9 `' I) C( D8 K; ]" F' m6 A! \: v8 z0 }
ADC_Regular_ConversionMode:
% Y3 \5 @3 n/ LEnable Regular Conversions 是否使能规则转换。5 D, W% c' @/ {7 u
Number Of Conversion ADC转换通道数目,有几个写几个就行。
% o) c& i/ y7 U' RExternal Trigger Conversion Source 外部触发选择。这个有多个选择,一般采用软件触发方式。) K6 }- R& o  _% Q2 a" Y

+ C* Z7 F9 F2 U! H: }Rank:/ ]  R+ B  G/ L, t& X- z/ R
Channel ADC转换通道
- w- r, c/ ?) D' w6 ~7 cSampling Time 采样周期选择,采样周期越短,ADC 转换数据输出周期就越短但数据精度也越低,采样周期越长,ADC 转换数据输出周期就越长同时数据精度越高。9 _* x% J$ I3 _2 D

; u! {5 z4 U; a1 }5 yADC_Injected_ConversionMode:
; N% E  D; p  ^3 o4 OEnable Injected Conversions 是否使能注入转换。注入通道只有在规则通道存在时才会出现。
, \2 B  S8 s  ^) p  q4 n8 Y0 L" ^! a0 ^3 E: B  e
WatchDog:
6 {* k$ p+ l, _  PEnable Analog WatchDog Mode 是否使能模拟看门狗中断。当被 ADC 转换的模拟电压低于低阈值或者高于高阈值时,就会产生中断。# D- o! n$ x6 E, l9 ^5 N0 Z* q( B/ |

! m# z+ X1 ~0 [DMA开启。
& v  p, E! L  N3 e% W) L8 ?  R0 f/ E, |9 |! I% D" e* C, V
8d4d5bbaea2f4af4bfffd8dfa349c3e4.png : w) i( W. r6 s2 F

: l0 U5 t+ B. K% B4 g# b3 K生成独立的文件。: `1 q7 S; l1 g# |2 e: r2 \% g
8 r) F! w8 d1 S. L
84777276815a43eeb799f7491a2f8868.png / p* q  ~) S; j9 c# D! ]3 J! U

) G% c, c/ l. `) X) E2 E% S* T1 USTM32CUBEIDE配置; C7 y  ?* K  _3 T4 t+ e% x
( U( }  }' S" m/ F6 T
cef307ee88fe48e9927c8672840c37f2.png 1 o: c. _& g9 h/ C  j6 |1 C
若需要打印浮点型,需要勾选下面的选项。) B) ^8 D2 l2 u* o% q
& I# w" H+ s! f0 w' p( r! e
0f42e907240242bfbb736c31e9755617.png
9 S. I" |$ a" E- n) T! ^0 o- w: ?+ e* C! p: `7 \
串口重定向  r) o& m: H1 k8 Q6 w, U% o2 ^
在main.c中,添加头文件,若不添加会出现 identifier “FILE” is undefined报错。
  1. /* USER CODE BEGIN Includes */6 \2 @: ~& V7 s9 U
  2. #include "stdio.h"3 |+ T2 w- k" G6 [5 w( ^" o* F) `$ w
  3. /* USER CODE END Includes */
复制代码
5 \! F- Z  ]4 @4 J5 R) c% E; _
函数声明和串口重定向:8 a6 m- P' d7 H8 D( f
, |: Y3 @% |3 O  u) h" b7 a& B
  1. /* USER CODE BEGIN PFP */2 Z9 i8 B' L8 K! i' v
  2. #ifdef __GNUC__                                                                        //串口重定向3 d, E( t; O. H3 o
  3. #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)) J- [* {" g' |* E, z
  4. #else
    . S. S/ v3 j' Y7 M
  5. #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
    * ^* z8 @7 E& Q2 a, l
  6. #endif ! |% S& A; r& `$ z% R( l
  7. PUTCHAR_PROTOTYPE5 m  D4 G! |% X4 B- \- `) c5 p3 C9 d
  8. {8 ^0 |+ w* k2 w
  9.     HAL_UART_Transmit(&huart2 , (uint8_t *)&ch, 1, 0xFFFF);: A& }  J% [0 m+ R6 L6 t! P' R
  10.     return ch;
    1 u' E* C' Z5 q
  11. }
    + u. Y* K( ~& J0 j
  12. /* USER CODE END PFP */
复制代码
" ~, S, S; ?! L6 }( Q) A: M. T
代码4 U$ O7 k* _6 o0 N
定义变量,存放采集到的数据。

0 B" o. V$ }) i& y- Q" s1 i. _' f5 K" j
1 K6 B9 b& n) a
  1. /* USER CODE BEGIN 0 */
    ( n0 n) ~# q8 |) i* `$ S
  2. uint32_t ADC1_1, ADC1_2,ADC1_3;//采集的三个通道的ADC
      h  w$ o. ^" l( U9 B) \9 h8 b
  3. uint32_t ADC1_Value[30];//DMA存放数组/ h, |4 ?& t+ b  B. j" G# A
  4. uint8_t i;/ h) ]8 W- ]2 K
  5. uint8_t ADC1_Flag;//dma采集完毕中断' }5 O/ h, |  @' f
  6. /* USER CODE END 0 */
复制代码

4 ]1 p8 g6 m* l& D使能ADC传输。* P7 }# J. K* M3 @% K* o' {
" W# D. B) R# Q; V. c! q, P, ^
  1.   /* USER CODE BEGIN 2 */
    3 R  q( j+ v. B0 P* a
  2.   HAL_ADC_Start_DMA(&hadc1,(uint32_t*)&ADC1_Value,30);    //使用DMA传输
    % ~. s( Y2 ?7 W0 @: V$ @5 ]
  3.   /* USER CODE END 2 */
复制代码

+ ^' \; L6 G# _5 q2 t) @主循环。
3 T+ i- J0 W: q( R7 ?
' g3 R: n5 ~1 s( ^" `3 v$ j2 w
  1.   /* USER CODE BEGIN WHILE */! \" ]- q$ D; k1 Y# ^
  2.   while (1)4 a' X5 ~/ {5 K6 {$ J
  3.   {
    + b) `$ Z" r! }1 F2 P7 G
  4.     /* USER CODE END WHILE */
      h6 C; e, L/ }$ O% L

  5. # f3 ~0 r0 k5 H' r2 |
  6.     /* USER CODE BEGIN 3 */
    , X, Y: s2 e' B* }# B4 O/ p
  7.           if(ADC1_Flag==1)
    ; `8 `; G' y' D* v" m, U$ m
  8.           {
    2 |2 r% n* L- W+ ~" u1 _) T
  9.                   ADC1_Flag=0;
    + w/ D) f7 {4 U
  10.                   ADC1_1=0;4 i+ ]. R1 l- ^% A
  11.                   ADC1_2=0;
    # h0 ]1 Z3 {& c; a; N& L; K+ z
  12.                   ADC1_3=0;7 d( v2 J4 ~& e" N8 b5 V$ r
  13.                   for(i=0;i<30;)) {- ]) g9 L! [$ r
  14.                   {
    ' f% }+ |1 h+ ]3 l
  15.                           ADC1_1+=ADC1_Value[i++];
    + |* `4 v* A! c( F& V* ]! @5 n
  16.                           ADC1_2+=ADC1_Value[i++];4 _* G7 w* U- b( l" B1 P- g) [
  17.                           ADC1_3+=ADC1_Value[i++];7 \+ S- T+ w/ o2 V) g4 K: z$ `
  18.                   }9 ~. o; z2 A2 D/ Q. ~  |
  19.                   printf("\n");2 k, {. }( L4 @. I) u0 R
  20.                   printf("adc1_IN0(PA0)=%4.0d,ADC_IN0=%1.4f\r\n",ADC1_1/10,ADC1_1/10*3.3f/4096);9 f3 B1 _' F2 v* {/ P
  21.                   printf("adc1_IN1(PA1)=%4.0d,ADC_IN1=%1.4f\r\n",ADC1_2/10,ADC1_2/10*3.3f/4096);7 m' Z. ?6 ]( J2 i$ J; \! [" w2 n
  22.                   printf("adc1_IN4(PA4)=%4.0d,ADC_IN2=%1.4f\r\n",ADC1_3/10,ADC1_3/10*3.3f/4096);$ d  a9 u+ V4 t' R1 F: o3 |
  23.                   HAL_ADC_Start_DMA(&hadc1,(uint32_t*)&ADC1_Value,30);    //使用DMA传输: R/ S: |4 c3 H2 y, v) ^
  24.           }4 E+ l$ X& P' b/ p8 y/ z2 T8 d9 N
  25.                 HAL_Delay(1000);0 J5 l1 Q: W! R
  26.   }
    6 `, m6 ?% l6 O
  27.   /* USER CODE END 3 */
    7 U) g: o4 {5 r. O  L0 n
复制代码

7 J$ H7 V) i  {$ sADC回调函数。
  k: ?  y- v' S1 MDMA传输的时候如果读取内存片段,会有仲裁器的问题,加了一句关闭DMA的语句HAL_ADC_Stop_DMA(&hadc1);
0 A) f/ W1 v  j1 |
5 H6 z8 w$ Y, f$ }- R  |/ X- I
  1. /* USER CODE BEGIN 4 */. c3 g# L. y6 G& }4 n' |
  2. void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)  L7 A. x* f8 O0 M, p8 E
  3. {2 p9 K3 c$ v+ Z7 d, D7 ~
  4.         if(hadc->Instance == ADC1){2 K5 |' U: s7 x8 |( W1 a* v8 a
  5.                 ADC1_Flag=1;
    5 \+ Q7 p0 I# S5 c' T& K
  6.                 /** k' y$ P. L, B( e2 @
  7.                  * DMA传输的时候如果读取内存片段,会有仲裁器的问题,加了一句关闭DMA的语
    % N: P# s# e! Q- m. R9 }
  8. 9 }) B. S% M. W  w9 x
  9.                  */
    9 b8 g# ?' j# [* j7 e
  10.                 HAL_ADC_Stop_DMA(&hadc1);
    2 G8 {$ |" z- U1 f( p
  11.         }
    2 }  d6 y9 m8 g( l9 {, e( f! t$ _
  12. }, `. u0 l6 p" E2 c2 ^
  13. /* USER CODE END 4 */
复制代码
' _0 v6 j% Y' W; l1 |
赞 收藏 评论0 发布时间:2022-8-18 15:57

举报

0个回答

所属标签

相似技术帖

官网相关资源

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