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

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

[复制链接]
STMCU小助手 发布时间:2022-9-5 21:02
生成例程' V7 V/ i* E( D  o
使用STM32CUBEMX生成例程,这里使用NUCLEO-F103RB开发板
" ]4 A& Z1 l1 i  m/ o
+ C; \: i+ }8 i 641406f4ab6d4ba3806608ea088511f0.png 9 g7 |9 H5 u4 g% s
7 U% U% Y( x- y
查看原理图,PA2和PA3设置为开发板的串口。
" B/ D2 p0 S+ p/ e) _) `5 F* N0 y3 a* u. Y
6cde275d970445afaa522e74e1b05da0.png 3 Z2 [" y# ^- y0 T

, r  j7 j2 k: ~- W2 \5 T4 E配置串口。6 t, y$ \4 i6 F- }2 O
: F) O5 A( F7 |8 E" S. k( d
e5a35949ea484fe782de2237f57d2198.png $ }- o9 a  s9 X. ]

; R4 V0 L& R$ K$ Q" x: z, ~开启中断。) z8 B3 Q0 c# B7 a# a) G% E0 M
( K9 {3 f! X/ }% {
4b8d8ee78fdc425485eb47d05a726d28.png
9 g. ^, O' g( o' P' C
8 @# N+ o% X  Z8 V0 W查看原理图,Arduino的接口A0-A5都是AD口。
4 |& Z0 ?! S( i. t
' e$ |6 y& l1 G$ u7 b3 H0 [ 3f6de63422a74d5985ce49db60330b90.png 8 F& @+ E! ?' y/ q( L: n9 \

. }6 z7 [; `6 A6 w% m$ tADC通道配置
$ D  ^+ {( X# K  {, Z
( \- b" r+ x) j( B) dADC1        IN0(PA0)        IN1(PA1)        IN4(PA4)) j! f" W5 t  B" u- H& D3 Z  Y6 H

; ]* [# P$ C$ q) eADC1配置。. Q( t+ ]2 V$ s8 m. Z
9 J. Y" F9 j) H. z' ]4 c' [
353986b1f8d94f9c8f54b326562e89c7.png + T( \# ~1 u$ V/ I
2 H, i( W; n2 K2 l" y
ADCs_Common_Settings:% y5 `2 @. z0 u; c
Mode:Independent mod 独立 ADC 模式,当使用一个 ADC 时是独立模式,使用两个 ADC 时是双模式,在双模式下还有很多细分模式可选,具体配置 ADC_CR1UALMOD 位。
2 @, M5 x$ l& y7 ~% q7 |" d+ G9 ~# p6 j3 B. j9 j  T/ J! ]+ ^
ADC_Settings:" D: f8 ^7 b/ Z* Z
Data Alignment:" F7 x* P  J( I: O2 s
Right alignment 转换结果数据右对齐,一般我们选择右对齐模式。
/ \% O, |% _6 X2 d$ YLeft alignment 转换结果数据左对齐。  {' E( d# g+ H! Q. C5 z) X9 [0 B
& y  y3 Q6 g$ M# \% {' e. f
Scan Conversion Mode:7 e1 j9 |' t/ ^: g' G; N
Disabled 禁止扫描模式。如果是单通道 AD 转换使用 DISABLE。: t* s# U: z0 f4 |3 X
Enabled 开启扫描模式。如果是多通道 AD 转换使用 ENABLE。5 k$ ?6 f5 Q* R! {0 g0 x4 c- K% E
Continuous Conversion Mode:: V! N+ [5 X4 t1 H2 J
Disabled 单次转换。转换一次后停止需要手动控制才重新启动转换。8 |% ~, F" N7 Y9 Q+ D/ A5 g. x  a4 v
Enabled 自动连续转换。
; V! x( w+ h1 f1 X$ _& o4 q+ h5 y. E- r  S! z, J
DiscontinuousConvMode:
3 t  `1 y; }; oDisabled 禁止间断模式。这个在需要考虑功耗问题的产品中很有必要,也就是在某个事件触发下,开启转换。! o' Q& F0 u) m: h2 b/ \
Enabled 开启间断模式。
1 D# @! q. X' L! I! i" y$ h
/ I" V' `% {7 NADC_Regular_ConversionMode:8 H# [  u) J2 k# r1 O
Enable Regular Conversions 是否使能规则转换。/ @0 y# A( D0 u  W
Number Of Conversion ADC转换通道数目,有几个写几个就行。
7 L9 R! [8 j* pExternal Trigger Conversion Source 外部触发选择。这个有多个选择,一般采用软件触发方式。1 m2 }/ J9 L* J! H, O  Q2 J

# X! A1 u- D1 ?, b: ]7 pRank:
. I  B8 ]3 c3 T8 T3 PChannel ADC转换通道/ J9 L# g0 G2 k+ F, u
Sampling Time 采样周期选择,采样周期越短,ADC 转换数据输出周期就越短但数据精度也越低,采样周期越长,ADC 转换数据输出周期就越长同时数据精度越高。
" [9 e1 H7 `) P" c7 O% [" M- K% e/ A) V
ADC_Injected_ConversionMode:
8 n) O+ r  x/ h1 U6 |% ?; LEnable Injected Conversions 是否使能注入转换。注入通道只有在规则通道存在时才会出现。
4 M4 T) O( y9 T/ _% X
  _* V- I0 r! U" U/ j2 DWatchDog:
5 `/ S7 m7 z4 ?. I' ?Enable Analog WatchDog Mode 是否使能模拟看门狗中断。当被 ADC 转换的模拟电压低于低阈值或者高于高阈值时,就会产生中断。
- i2 M" m4 S& u
3 ~: }! g9 r' Q( N3 IDMA开启。; u. u9 u; L; Y
( J3 C) R! V1 G8 O1 N
8d4d5bbaea2f4af4bfffd8dfa349c3e4.png
" z3 A7 ^/ `, ]. q1 n, C  H+ |( B# S2 {5 J
生成独立的文件。
  j, k- z5 j, a) R' j. y4 y' L' I3 {' [& x7 h1 h  v8 n
84777276815a43eeb799f7491a2f8868.png
2 }# @# M; _, ^' q1 W) r
' u" A& t& d, k6 j; ?' |, J3 DSTM32CUBEIDE配置8 Z% N+ |0 C" ]
$ u: o4 s0 b( s9 V- [- ^( ~
cef307ee88fe48e9927c8672840c37f2.png * _$ T' r$ Z5 H- F3 H' K

/ @/ g: \& U2 S' l* \若需要打印浮点型,需要勾选下面的选项。
: M1 P& B% [; m9 U$ W! E& ]$ S0 e4 e/ i* i
0f42e907240242bfbb736c31e9755617.png
1 n3 n! C. g. Q) x
. W. x# y# X3 v. x( H' ~4 U串口重定向0 u6 k3 H& F8 ~: D1 j3 V
在main.c中,添加头文件,若不添加会出现 identifier “FILE” is undefined报错。
- U  J* y6 Z8 Y! \0 X5 g6 A* \% R/ W4 w
  1. /* USER CODE BEGIN Includes */
    ; _! l5 w# S, m$ F3 M
  2. #include "stdio.h") U' I; C4 I, W
  3. /* USER CODE END Includes */
复制代码
! p5 b8 t% ~& L5 ^$ O
函数声明和串口重定向:0 I9 W3 E; e  ?2 x, v- E" J

1 d7 f: G: P# H  Z( |
  1. /* USER CODE BEGIN PFP */
    1 ]' e( w, J  @
  2. #ifdef __GNUC__                                                                        //串口重定向
    / L3 f6 F0 ]7 l7 }8 |
  3. #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
    ) T: p2 [* I- Z& h: c) ?  `5 {/ ]- ?* o
  4. #else- S( J# x8 [  ~6 G2 v- s4 q2 w/ I9 V6 E
  5. #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
    + {- k( ^- y5 [
  6. #endif
    - l* \9 ?# _7 [
  7. PUTCHAR_PROTOTYPE
    : r: H8 M% i/ r! i9 Q
  8. {
    1 X6 r' s3 A, ~; |; g  \. q/ N& Y
  9.     HAL_UART_Transmit(&huart2 , (uint8_t *)&ch, 1, 0xFFFF);- I1 ], f3 [, a1 i+ [+ @4 [' ^; R5 r+ Y
  10.     return ch;
      m' O0 q$ `9 S
  11. }% J  {+ m) [2 D7 H
  12. /* USER CODE END PFP */
复制代码

" I6 s- e# r- [7 l7 I2 i代码
" b/ D. g, X1 p8 S6 S: T. G+ n定义变量,存放采集到的数据。+ m6 H0 V8 [  c( J

& ^( S6 ^: f  l6 [0 S3 B% m$ f
  1. /* USER CODE BEGIN 0 */+ S0 N) t% P! v3 [
  2. uint32_t ADC1_1, ADC1_2,ADC1_3;//采集的三个通道的ADC
    * a" F$ S5 c6 C! z" I  F) q+ I
  3. uint32_t ADC1_Value[30];//DMA存放数组- }0 l$ T/ Q# H
  4. uint8_t i;
    - w+ C! J# m6 @% H' t& r$ t
  5. uint8_t ADC1_Flag;//dma采集完毕中断
    1 p0 n; n9 x) K  P# a6 x% K
  6. /* USER CODE END 0 */
复制代码

% N  y% z. m  }5 R. U3 {9 t7 U/ A7 u4 M
使能ADC传输。0 E- S# a* I: F; R/ r, x/ _

0 [9 Q. O2 O7 d
  1.   /* USER CODE BEGIN 2 */$ [7 X* k5 `4 H2 v
  2.   HAL_ADC_Start_DMA(&hadc1,(uint32_t*)&ADC1_Value,30);    //使用DMA传输6 p* }( t( w* Z- Y: x! m6 h
  3.   /* USER CODE END 2 */
复制代码
& g, g. z+ Y5 R( ^
主循环。* F9 j1 C* A5 v$ O3 P. V
3 m5 x* I2 p2 J5 W2 |8 L2 z# Q( G7 a
  1. /* USER CODE BEGIN WHILE */3 T2 {( J8 X8 |1 L
  2.   while (1)
    2 Q: ?0 H  x2 T- u
  3.   {3 z* p# t$ H7 G; b% X1 v& z' e
  4.     /* USER CODE END WHILE */
    ) O: l  {3 |6 p, n! r1 V

  5.   A1 E; z8 x7 A
  6.     /* USER CODE BEGIN 3 */7 t4 l( a0 S# K# D# a
  7.           if(ADC1_Flag==1)# ?9 n- u# L% R: o* N) N
  8.           {6 Q+ I4 ~1 I3 @
  9.                   ADC1_Flag=0;& B3 g& c0 @" C- g/ T7 o9 v
  10.                   ADC1_1=0;
    % g  l% B- U% `4 @
  11.                   ADC1_2=0;
    1 \& H  h! t) }! x
  12.                   ADC1_3=0;1 W# f* Q, T/ `' j( o* T
  13.                   for(i=0;i<30;)
    , g/ l$ _! ^/ B' }: Y
  14.                   {
    6 g! j, z" e! m" z" E! Z
  15.                           ADC1_1+=ADC1_Value[i++];
    5 N* i0 E/ P2 r: Q4 r9 ~
  16.                           ADC1_2+=ADC1_Value[i++];# P, _8 W& B) q9 n
  17.                           ADC1_3+=ADC1_Value[i++];5 d* ~9 ~0 V: t3 i, R/ m# u: n7 v# D
  18.                   }
    : s9 J. \9 F4 t' \" P3 D
  19.                   printf("\n");4 b6 }; b+ f' r* g# Q
  20.                   printf("adc1_IN0(PA0)=%4.0d,ADC_IN0=%1.4f\r\n",ADC1_1/10,ADC1_1/10*3.3f/4096);
    0 |, V  i" {) e/ e1 F' o8 U9 i1 G- d
  21.                   printf("adc1_IN1(PA1)=%4.0d,ADC_IN1=%1.4f\r\n",ADC1_2/10,ADC1_2/10*3.3f/4096);
    2 a# j: H/ |! P2 i! m3 i
  22.                   printf("adc1_IN4(PA4)=%4.0d,ADC_IN2=%1.4f\r\n",ADC1_3/10,ADC1_3/10*3.3f/4096);
    : L' j) y+ o4 D0 i" R3 l
  23.                   HAL_ADC_Start_DMA(&hadc1,(uint32_t*)&ADC1_Value,30);    //使用DMA传输
    : O8 m$ B2 Z/ P7 M
  24.           }( ~) @- `+ V1 T& L/ w& f
  25.                 HAL_Delay(1000);6 T: O8 h1 E% A: y1 R* L
  26.   }
    6 T! L0 m9 J/ }: D) z- H
  27.   /* USER CODE END 3 */6 N- S6 h* Z. i
复制代码
9 K. l2 a; N" n) O) |
ADC回调函数。
  T( y2 k4 T: q* r/ {0 ZDMA传输的时候如果读取内存片段,会有仲裁器的问题,加了一句关闭DMA的语句HAL_ADC_Stop_DMA(&hadc1);1 P) J3 |: H2 o' {& h
  1. /* USER CODE BEGIN 4 */3 t. p* }- c& I6 M  i
  2. void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)) p# \% o  X2 m4 C
  3. {
    & A" F) e; f7 ^* N2 J4 b6 g6 k
  4.         if(hadc->Instance == ADC1){" L- I+ q% |! F% S* {8 c6 N
  5.                 ADC1_Flag=1;
    4 T2 N; G+ N4 t; {( Y) z
  6.                 /*# Y, ?# a0 Y8 Q7 F6 P* m3 g
  7.                  * DMA传输的时候如果读取内存片段,会有仲裁器的问题,加了一句关闭DMA的语
    . n, `2 y: N3 z5 l
  8. 6 U7 o# ^9 V- u; k1 E
  9.                  */5 {% `2 Y- F  g( A0 W& T1 }
  10.                 HAL_ADC_Stop_DMA(&hadc1);6 P& w/ F3 c9 |1 H5 X% x( J7 ]
  11.         }3 }& P" Q1 T' @0 d
  12. }9 }) m6 S  I% ^0 j4 U9 x
  13. /* USER CODE END 4 */
复制代码
8 r' I. W2 w- o
测试结果
% b0 B% b5 w8 q' l% z, Q& r输入固定电压进行测试。/ v4 j! w" N( \

/ t/ D# A+ t9 V5 q X{A@KZ]UG}WSY2P]VU`_A.png - G- p0 N& D6 H6 q( v4 Q
4 x' c1 W4 d+ K3 g3 F, j1 l5 S
Normal下测试结果如下。
6 _" @: n% _! q+ W6 E' a
4 \4 S6 A# ?9 y# w4 j' | db436b7622d949f68ac746b30fced16f.png
* p( [" x8 w; M- M9 Y9 g) D
2 C5 f) D5 s5 a# r3 C9 X& j若不试用关闭DMA的语句HAL_ADC_Stop_DMA(&hadc1);. Y2 ]* f& z( c& b  h. U8 ]
会造成数据错乱。
1 F" t& Y( O- S
0 U& D7 i! }! w0 a0 Z5 S 2b0fc5e363cb4fc5956df5dd3ca626da.png
5 S* \9 N* ~  T5 n. T" h* q( a7 g$ W+ A) v4 R+ I! ]. i
Circular可以下可以一直进行采集,不需要HAL_ADC_Stop_DMA(&hadc1)都可。
9 V7 K/ Q# n3 |4 k. e. |
/ U% D6 C9 j1 I 4a094bd16f6f42fa8835d83d181804fa.png
3 s! c  ?! p* R) I! ]
( _4 v. M. J0 \/ {5 ~————————————————. b. U8 X9 L* j8 V# U. m- i$ \
版权声明:记帖0 L  ^& L; R; o: g( l. j7 W: [

3 d+ ~! c: n5 X4 Y7 S& W
7 y0 E3 S! h) ^  q4 B0 o  u
赞 收藏 评论0 发布时间:2022-9-5 21:02

举报

0个回答

所属标签

相似技术帖

官网相关资源

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