有人使用STM32U5系列MCU开发产品,在用到ADC结合DMA传输时遇到点障碍,这里针对片内ADC1和ADC4基于DMA标准请求模式和链表模式演示下实现过程,以供参考。6 A. }9 z+ L, Y4 b# K1 P# M' }
% d& S4 _% a! [0 r% G
9 }! m( `. `" ^) i5 _6 h6 s2 M/ B先对ADC1基于DMA标准请求模式做演示。
. O2 u9 v5 k9 a% Z% j) ^/ {! g; X/ ^* m7 c- P, [
( T& E$ }# ~3 N$ v9 G4 K3 z3 |
随意选择ADC1的4个通道,扫描模式,连续转换,DMA传输转换结果并令DMA工作在外设字到内存字的循环传输模式。使用CubeMx进行配置。其中DMA通道使用Channel 1。4 W& U) I6 j+ O+ u: ^% t- o ^
, o! K3 P a9 G0 `/ }$ w5 Z. K3 ~2 m ^# u
$ i4 F+ p3 v/ E" y; ^5 ]5 X" ?+ G& x1 ? ^- R
' }1 |* i X$ z$ X+ ^* W v
/ y/ ^* G) B1 O6 N! V. |- V+ `0 e
# Q# |4 z4 O3 _
" Z) g" c% B" t) l
y: j* j$ p! a相关代码:3 w+ H0 Z' T; m( W% g% @0 L: `
- #define ADC_BUFFRER_SIZE ((uint32_t) 8)
: b! R3 G- K) G4 A3 y - uint32_t ADC1_Result[ADC_BUFFRER_SIZE];6 P( u4 H- N2 L; P" b' b; z
- 1 J# G5 k& G5 R' O8 R
- ADC_HandleTypeDef hadc1;& n3 }! @9 d- ~+ f3 |) U
- DMA_HandleTypeDef handle_GPDMA1_Channel1; //For ADC1
+ W2 ~7 j( h( K - 5 A, x0 [2 w, ^3 S$ o1 j
- /* USER CODE BEGIN 2 */4 ], q# m5 f' E4 x
- " Q, F& {$ v9 d3 l+ e
! f( M" Q* o" U+ P1 q4 v- ^: h- HAL_PWREx_EnableVddA(); //add it manually with lower cubeMx version
% L# F! k+ y6 J" a8 `3 x$ U( \ - P, [5 i. T0 Z
- __HAL_LINKDMA(&hadc1, DMA_Handle, handle_GPDMA1_Channel1);% @! u! c @. X
. H$ s/ y8 Q7 e7 @: N" n+ n9 A- if (HAL_ADC_Start_DMA(&hadc1, (uint32_t *)ADC1_Result,
' t. p& S; F6 X, s - (ADC_BUFFRER_SIZE)5 x2 V% E/ G. u1 o% \
- ) != HAL_OK)
: d: D% w: j; B$ a9 v% A7 q; s - {
- J7 Q) t7 t5 @( Y* M2 Q6 e/ p8 P - Error_Handler();! n- _9 V- @! \' h+ `
- } 0 H& D3 F, B$ f: ]% Q4 R1 @
- 4 E2 } ~9 h4 y7 d8 w
- /* USER CODE END 2 */
复制代码 " d& X- o; B/ W& u) b. o
运行结果如下图所示:【目前4个通道我是悬空的】
& O" P ~6 K- D& \( c4 b# r) X' x S& x5 t
# y( R. w" D5 t0 C; A' ^# ~
* I/ A- @) w. w: S
! W, Z: U% W0 U7 C8 C) l+ q) t# l3 [+ I; ?$ Q ~, z' Z
现在对ADC4基于DMA链表模式做演示,其实就一个节点。% S, {7 p C4 y
/ {1 ~( P8 O5 \, l& O0 T
! _ B( S- b, ]% ~9 f2 A选择ADC4的4个内部信号通道,扫描模式,连续转换,DMA传输转换结果,并令DMA工作在外设字到内存字的循环模式。使用CubeMx进行配置。其中DMA通道使用Channel 0。对于内部信号的采样,往往有最小采样时间要求,我这里的演示随便选了个参数,具体应用时请参考数据手册及当时ADC时钟具体拟定。特此提醒!
% U. Z. T, ?: F2 ?
6 n: m( @ S) m9 W4 b
/ {& F( \! u$ `
{; V" ^% l" t1 g: ^, ~3 c+ D+ k6 o0 ^+ @& p
) x9 h9 A) O: c0 D
关于DMA链表模式的配置在CubeMx界面里的Utility菜单下。% A4 [9 k4 p7 n, n* D; R6 b
, X" k: T* h! y3 Z2 `6 { {- \" |
?0 T3 ]) H; `8 F9 I" R; d4 H2 W
3 u6 h- Z$ h3 d: I0 \2 e4 _
+ C: {& p: I2 l" J; r
) s4 Y/ d$ L8 Y' t/ `
5 V9 ` a/ W+ b4 p! e! z% t. {
* p5 | O* \& C& o9 q4 ^
: C2 k. `- `8 D0 b% `6 N% B' @% V7 I
相关用户代码:
( ~9 R( F' |( y) n6 t- _" F$ e0 B% X- /* Private variables ---------------------------------------------------------*/
% j8 ^- b: z( {, M6 B% b - ADC_HandleTypeDef hadc4;
. ]& Q7 S, E& X9 l/ s( }* s3 | - DMA_NodeTypeDef Node_GPDMA1_Channel1;% c/ B9 ]* [& J, R
- DMA_QListTypeDef List_GPDMA1_Channel1;
2 p! S5 U' I' ^' `; a- s - DMA_HandleTypeDef handle_GPDMA1_Channel0;
9 J) t/ y! `8 M$ w9 Z - /* USER CODE BEGIN PV */# v+ U& |9 L- n) z) Z3 q; n, Y& j
1 d+ L8 y/ D+ @) j- /* USER CODE BEGIN 2 */2 @& j, j2 C: J+ `/ o% M
/ x; g* G% f R! D6 |- HAL_PWREx_EnableVddA(); //add it manually with lower cubeMx version
7 p. f4 C [, a - 8 g- h1 d6 t' H
- MX_ADC4Queue_Config();* F3 }7 d0 ]4 {
) R# q. S+ h3 _9 `' w( Y- __HAL_LINKDMA(&hadc4, DMA_Handle, handle_GPDMA1_Channel0);' v" H4 y) `! X5 P" @! @
% ^! j1 z2 c* X7 w0 B5 {% f- HAL_DMAEx_List_SetCircularMode(&ADC4Queue);8 \3 {- G2 L9 b' |0 B. \: P
- 1 H7 l# H" H9 n; u" F. r
- if (HAL_DMAEx_List_LinkQ(&handle_GPDMA1_Channel0, &ADC4Queue) != HAL_OK)
8 @' C# N. I5 E% m8 `8 f - {
! Y# f8 I1 Z M& M - Error_Handler();
8 d" | f3 _5 D3 s: x9 i - }
2 p' l+ s( K: j9 m7 c - ( O& J& X: o+ T2 H9 A
- if (HAL_ADC_Start_DMA(&hadc4,- @, N/ b$ Y& S3 D
- (uint32_t *)ADC4_Result,
/ D) E1 I- i/ G7 `1 f. j - (ADC_BUFFRER_SIZE)
) c. N2 f _' H5 \5 R' c - ) != HAL_OK)8 S9 j7 K2 p7 u* y ~- q0 [
- {* Q- f" n4 R8 o! S
- Error_Handler();
: {; F$ @4 E- h& F# \) \" ^ - }
- q q( n1 b0 Q# p; t6 @# j* ?3 y - /* USER CODE BEGIN WHILE */
复制代码 1 I+ Y! c {0 h5 j1 ?5 ?
结果验证【显示了2组数据】:
, O- @6 f+ s/ S4 d" F' ] \4 f
% u4 m9 ?# ?: a' w
' U6 F. t* J; y% V
) J `. @( H( ^( w6 c# h8 E
) Z I/ g! G/ }+ y% ] Q
' S @: S- h' v9 |最后还提醒下,如果CubeMx版本比较低时,HAL_PWREx_EnableVddA()函数需要自己手动添加。我目前CubeMx 6.9.0版本已经不用手动添加了,创建工程时会将其自动生成于相应位置。! K! F7 r/ l! w' o- ^, G! A" e* J8 A0 Y
# G0 y' j8 ^# `; ^& V# N: ^ J9 m. @7 I2 V5 i- ~# \
" |8 B; j/ i& J6 ^$ V9 D( T
如有侵权请联系删除
" V2 t- `9 u6 E- Y3 y* {
1 x4 E# `$ l' k" X1 Z( ~9 D转载自: 茶话MCU
- c/ P1 |! \3 p2 n2 J Y* r: ?' X. ?
/ R4 i5 u7 G/ H, _) C
|
学习一下