有人使用STM32U5系列MCU开发产品,在用到ADC结合DMA传输时遇到点障碍,这里针对片内ADC1和ADC4基于DMA标准请求模式和链表模式演示下实现过程,以供参考。7 e1 q4 p4 {, N7 L5 h: f; c
; O. w9 f- g4 j: o* x& O
% N P% @9 a3 y+ T& T先对ADC1基于DMA标准请求模式做演示。5 b0 _5 E* v' |! e) @# S% A
7 Y |/ w: h: p ~* e, D6 {" U) |
. q$ A; u& Y% r4 o3 [随意选择ADC1的4个通道,扫描模式,连续转换,DMA传输转换结果并令DMA工作在外设字到内存字的循环传输模式。使用CubeMx进行配置。其中DMA通道使用Channel 1。5 r; V4 h& _+ A& ]. g+ `5 y+ j9 R9 [
* E* o* p' v) u
1 K1 I2 B" |) O( S" `' H
0 T, B& p; I- e+ T5 X0 `7 k! B+ ?6 U; u4 K( _) G4 U! n$ l
2 r$ U- i8 M9 O1 x
8 Z. _: W+ \ P
. N9 N& Y' M" X9 W6 b' y ]3 ]1 b; U2 T! N
! q9 n, q1 x: o! `
相关代码: N3 ^) Q. P6 u6 j
- #define ADC_BUFFRER_SIZE ((uint32_t) 8) * r! I/ v( r( l Y9 U
- uint32_t ADC1_Result[ADC_BUFFRER_SIZE];- }0 |8 A2 P; }- Z6 Q" j7 L* e8 e9 P
$ v" x9 |$ ]) F; [$ }- ADC_HandleTypeDef hadc1;* Y) J5 m, j, Y6 q7 P( K
- DMA_HandleTypeDef handle_GPDMA1_Channel1; //For ADC1% ~5 B0 |% w9 y) |, e
- 1 K6 E5 y5 X, a, c- M$ H
- /* USER CODE BEGIN 2 */
( ?( F4 F5 l, R+ o
7 u! k5 l$ T6 E+ [6 G/ O- " b: o. p5 v- g1 C8 [
- HAL_PWREx_EnableVddA(); //add it manually with lower cubeMx version
( a! h) h8 C. }( C' G8 u3 u -
: ]3 O4 ~' M$ X/ u0 h) `1 { - __HAL_LINKDMA(&hadc1, DMA_Handle, handle_GPDMA1_Channel1);5 L% N2 X- Z7 e! e C
v3 }# |+ z# \* M+ b- if (HAL_ADC_Start_DMA(&hadc1, (uint32_t *)ADC1_Result,
; z( V# R; [* g% M$ U/ |: ` - (ADC_BUFFRER_SIZE)* C, u6 h5 r- h- g7 g! P$ c
- ) != HAL_OK)' q9 n$ ~- G) J. H0 c* d7 T% s
- {
$ O* _7 c! @* m( g5 l& O& h' h - Error_Handler();% w! y- \9 n0 y" F
- } / h8 w1 u8 B' r- K' u2 ~
- ) }, q7 ~6 V/ U
- /* USER CODE END 2 */
复制代码
4 g; o1 }0 A; v运行结果如下图所示:【目前4个通道我是悬空的】& V4 T' |2 F2 a; G. }9 U% y
/ Z4 o9 @$ k# @8 V1 _
/ B t2 ^1 m. t9 G" y) Y
; A1 U2 }& F/ c) n* E( c4 S9 s! C. B: f" H) Y. v
" R) \ h2 }( F2 x现在对ADC4基于DMA链表模式做演示,其实就一个节点。
5 k6 s: G" b$ a, v8 R% U
( \. H$ `* t% Z# H' j
x" N1 d# x- B4 J% m c# j选择ADC4的4个内部信号通道,扫描模式,连续转换,DMA传输转换结果,并令DMA工作在外设字到内存字的循环模式。使用CubeMx进行配置。其中DMA通道使用Channel 0。对于内部信号的采样,往往有最小采样时间要求,我这里的演示随便选了个参数,具体应用时请参考数据手册及当时ADC时钟具体拟定。特此提醒!
% S9 J8 f. c, Y
7 e6 O4 V4 Y9 F6 [7 H. E) ^, s, `
+ n2 K; f2 `: o, \8 `' v
5 \/ E5 ]9 c2 [3 J3 K( y3 X: m9 M% L" G
6 g5 }; e6 [+ i# D
关于DMA链表模式的配置在CubeMx界面里的Utility菜单下。! ?1 A% }" t3 p' p, u/ ~9 i
, K# g, A1 Z+ R+ q1 K
3 W, M9 Y% q( B
6 s0 W! G) r, F- p* P% d- B
4 B5 D7 U- E6 m1 A9 P6 t) [; J
. Y5 r3 g9 X! k% ]; p/ b
# h4 p; G' ?) o7 Q
$ E w/ t- v* n8 c8 w/ a
5 }7 g$ [! O( A: h6 m" h
7 x5 u2 D9 F3 G' D. g% Z4 c. M相关用户代码:
9 T7 u0 Q$ ~9 H, c/ S- /* Private variables ---------------------------------------------------------*/% I. T# x; Y% S" ~! `. R
- ADC_HandleTypeDef hadc4;# a% h `9 k H! U
- DMA_NodeTypeDef Node_GPDMA1_Channel1;
9 m' K& Y' {" r, \; T - DMA_QListTypeDef List_GPDMA1_Channel1;- u" ^& _# f* r6 ?
- DMA_HandleTypeDef handle_GPDMA1_Channel0;! s( z6 H2 z0 ~# ]5 b1 E
- /* USER CODE BEGIN PV *// w/ [0 w# `" z7 i
- 3 e7 S* t2 ]* O1 C
- /* USER CODE BEGIN 2 */* |0 p0 i( ^8 Q8 P' n: S' K
|( c* q: a( O0 @* r h- HAL_PWREx_EnableVddA(); //add it manually with lower cubeMx version* T7 ^" e7 J9 p) a8 o4 @) `
- - p1 X# A) B3 N+ s
- MX_ADC4Queue_Config();0 a1 \" W& B. O- ~
% t6 Q# m' R; w L1 A* T0 `) l5 ]6 \- __HAL_LINKDMA(&hadc4, DMA_Handle, handle_GPDMA1_Channel0);, ^8 S, m5 u6 Z+ v* H$ f& B- i/ V) B
5 M' k" [0 Y. x e- T- HAL_DMAEx_List_SetCircularMode(&ADC4Queue);2 o, L$ K8 p, I: D0 X/ H
-
; `1 A$ g% N1 c9 V" ]) l - if (HAL_DMAEx_List_LinkQ(&handle_GPDMA1_Channel0, &ADC4Queue) != HAL_OK)0 ^' e/ K6 G1 V
- {
" ]' F0 i4 h* G - Error_Handler();
& j" y* i1 I. O% h- j0 X - }& V0 e" H M$ R" D& V1 \
0 A5 R1 g n" W9 h( X x- if (HAL_ADC_Start_DMA(&hadc4,
0 P7 g W- R- u4 Q/ E2 F. Y - (uint32_t *)ADC4_Result,
, Z8 a* {0 i' ?% G t$ q, D - (ADC_BUFFRER_SIZE)
8 P4 F$ O/ }, m% Z - ) != HAL_OK)3 P; ^* [& o+ K9 q+ `, X/ `. ]
- {
. m O. H; F( x& a: @5 U0 t$ E - Error_Handler();
; i y) ^( G6 m( q) K: T - }
+ c; d" g* r3 L/ z# i; a6 Y; R; E - /* USER CODE BEGIN WHILE */
复制代码
" `+ H7 y6 Y: [( x1 I结果验证【显示了2组数据】:$ a* r* E4 g1 O7 B
) b. r& g( y$ V" ]7 C5 h$ e" z% w
8 ^2 `7 [* T' V p) ~
\ |, E* _; N+ S2 b0 A
7 T& Q5 J# P# D5 O( H4 {
# }6 ]! O* _, D5 L4 Z8 a最后还提醒下,如果CubeMx版本比较低时,HAL_PWREx_EnableVddA()函数需要自己手动添加。我目前CubeMx 6.9.0版本已经不用手动添加了,创建工程时会将其自动生成于相应位置。2 w4 |( D6 Q3 X+ }8 ~& N
5 n) o x6 t0 k# i0 P3 M* C
]8 o, s$ }( ~0 f9 j+ h
2 W/ Y: @/ @6 B# i$ z2 g如有侵权请联系删除- x2 R: K- q: ~: V9 K9 O
( I4 r2 Q V& c) i3 w3 N, S/ i0 n转载自: 茶话MCU% \* w7 C: _+ D* N
( X$ ~, D* Y8 E
: m% C9 p3 F0 \7 Y3 I |
学习一下