有人使用STM32U5系列MCU开发产品,在用到ADC结合DMA传输时遇到点障碍,这里针对片内ADC1和ADC4基于DMA标准请求模式和链表模式演示下实现过程,以供参考。
& E) D, ~% e' Y$ J2 O+ A, p/ K- \2 s# p- \
/ l$ R# V$ {2 Y7 I$ w( `9 O6 ~先对ADC1基于DMA标准请求模式做演示。
6 F+ k6 q) r$ u& ]$ q2 t$ ^9 K
6 ~- Z' _3 b5 p( z# `
' m$ U6 o8 V6 R8 G1 t随意选择ADC1的4个通道,扫描模式,连续转换,DMA传输转换结果并令DMA工作在外设字到内存字的循环传输模式。使用CubeMx进行配置。其中DMA通道使用Channel 1。
' L0 Z6 _. k, Z, f/ Z9 }2 o5 I( f9 k9 ^5 [( V% |9 n
3 {! u0 Z" o# ]4 ~, q& d. }0 Y
; R* n0 B+ A' @5 Z* Y, N
; J4 S" b; \& ~( I5 N+ P0 H
0 J# y: E% S8 g: R
9 k" ?, O7 P* J6 h+ e' U) D
8 }6 M9 f q' E' q0 U- M# r' a6 v$ \/ A. C' [' U. ?! Z
% {/ h9 ~, R9 x1 C3 \6 J' z相关代码:
3 U# R- A" [ t- #define ADC_BUFFRER_SIZE ((uint32_t) 8)
0 F5 [3 N$ |+ O- M- o& N4 J) b+ Q - uint32_t ADC1_Result[ADC_BUFFRER_SIZE];
) @" _4 L9 @' Z& a
7 y% R+ Y4 ]1 A8 I; i J" x- ADC_HandleTypeDef hadc1;
! Z! z& O& I' f6 G - DMA_HandleTypeDef handle_GPDMA1_Channel1; //For ADC15 P# N3 w. Q% N( N
& p! J3 |: n* }9 L! x$ S- /* USER CODE BEGIN 2 */. [+ g! n, e- |& P, Z1 Y
' Z! T: G- n* G/ q! a" {7 _: F7 M/ X! Y
8 A" `, G; q. J7 B; H: l4 v- HAL_PWREx_EnableVddA(); //add it manually with lower cubeMx version' K: C$ {; w; b2 I: l5 P
- 2 R3 x& G! y! ^7 ]
- __HAL_LINKDMA(&hadc1, DMA_Handle, handle_GPDMA1_Channel1);0 C! L1 ?; @5 [* ^4 T$ v1 \' A
- 7 V! c/ Q3 P- [6 d' T8 T; O9 l0 h
- if (HAL_ADC_Start_DMA(&hadc1, (uint32_t *)ADC1_Result,# p, p# m, D* S8 Z! y
- (ADC_BUFFRER_SIZE)
6 C! v' M% o' Y - ) != HAL_OK)
7 K( |! p& b- F2 x2 l. |. [+ { - {: q- }( T: W' G/ B; ]. R* ?' H
- Error_Handler();( Z0 d5 s+ G: U) Q1 O! v0 g' S
- }
) z, m' r9 @( L - 9 B; T5 I' M5 Z+ l: n6 T$ z
- /* USER CODE END 2 */
复制代码 5 `1 W0 D2 h( Q' k
运行结果如下图所示:【目前4个通道我是悬空的】
# `+ e% Z. A# B5 `$ Q# I0 R3 s4 P( ~
5 ?3 J% Q- k& I9 X0 z1 N
# T- z8 d4 N2 u2 }* G( v3 b
# l" M' [& N0 j6 r& @- I% i/ U
, i6 t1 W. {% ^& b
现在对ADC4基于DMA链表模式做演示,其实就一个节点。
$ t S8 O: D9 e( ~( l5 V* s, N v& s* u) m5 R: b" p) M. r; Z
3 u" d0 ~4 \% C* T& R
选择ADC4的4个内部信号通道,扫描模式,连续转换,DMA传输转换结果,并令DMA工作在外设字到内存字的循环模式。使用CubeMx进行配置。其中DMA通道使用Channel 0。对于内部信号的采样,往往有最小采样时间要求,我这里的演示随便选了个参数,具体应用时请参考数据手册及当时ADC时钟具体拟定。特此提醒!/ d2 E, X) U& v2 j6 G. Q* \
$ T" @, k: V/ o% H1 |4 R% u9 G
" n( G$ c; Z6 f! K& x) H
N0 D3 n8 Q2 b! v6 @% q
" b% j' S* [ K. n. N$ ^* s. S2 b' p+ Y
关于DMA链表模式的配置在CubeMx界面里的Utility菜单下。
T' o: | W+ A8 [9 g. a5 ^; T; @4 i7 ~- L# P# H8 P8 z* `
/ \% y! i- D/ ?' B+ P4 U
' D2 F1 t) W$ c; u) ]9 y2 F7 [# X, J
* V! |$ T O' W- L7 l+ \0 Y8 h7 I( P; t9 c: P; O" y
" x/ |1 g4 q# Z) T+ i+ P0 p. Y, N) _1 [
' j# L9 A2 \& ~/ ^8 j相关用户代码:, ?3 L; c4 s9 n! {4 ]- x
- /* Private variables ---------------------------------------------------------*/
# i# M$ n- V2 L& z+ | - ADC_HandleTypeDef hadc4;: D4 k6 j& |8 j! p2 ^) t0 b
- DMA_NodeTypeDef Node_GPDMA1_Channel1;7 u% _$ P3 u) T; ]; I. j: H" z) a' ]
- DMA_QListTypeDef List_GPDMA1_Channel1;
8 B9 v4 r8 B8 Z' _ - DMA_HandleTypeDef handle_GPDMA1_Channel0;$ U# N& N, a( O" x% J, b
- /* USER CODE BEGIN PV */, }& }7 R/ {% U3 H4 H; @) q5 t# @
- ! F0 P' |# R% S: B
- /* USER CODE BEGIN 2 */
8 C. ]3 S: f, W. a+ {3 w
" e' ?% L4 q# C$ d \7 l) J# n/ t- HAL_PWREx_EnableVddA(); //add it manually with lower cubeMx version
$ H( e+ b$ `3 l3 C" E7 i
7 y4 t& v# h- E% N) m- MX_ADC4Queue_Config();% \0 {% d, K' p- p4 {( _
8 ~+ D9 a( u2 c- __HAL_LINKDMA(&hadc4, DMA_Handle, handle_GPDMA1_Channel0);9 t, x, `5 G4 c
M4 |! b0 {1 K R- HAL_DMAEx_List_SetCircularMode(&ADC4Queue);
) M9 I+ |9 ^! c# R+ z- H -
; }& j t1 x+ R% h9 S9 ] - if (HAL_DMAEx_List_LinkQ(&handle_GPDMA1_Channel0, &ADC4Queue) != HAL_OK)3 n+ Z! I1 T0 L+ y
- {$ f5 J" |" ~9 m) E2 `" k
- Error_Handler();
g& w- I1 }2 T& i. p8 v - }4 F6 \' G1 F$ @7 e! w" \
1 ]3 S& W/ J) j: B1 { G6 f- if (HAL_ADC_Start_DMA(&hadc4,( `- i& _7 w4 b8 N( d& c( w! |2 H
- (uint32_t *)ADC4_Result,
3 l0 T0 I6 V7 ~8 ?$ Q Z7 D$ M - (ADC_BUFFRER_SIZE)
1 \$ T: O' O, o f - ) != HAL_OK) }4 A8 G, c. M1 ~0 I5 B
- {1 M& @( L2 ^) c: b- I7 Q
- Error_Handler();' M/ Z: M! W9 G m5 ~
- }: T5 U. @7 }( G4 h
- /* USER CODE BEGIN WHILE */
复制代码
- D' U/ H' C9 B d结果验证【显示了2组数据】:
, ~6 r: U) d- p0 [, | Z# f: s
% z/ q+ d8 ?" f7 J
! N0 x g9 x+ a" Y( h2 r! C6 j4 p3 M# K
; Y9 |% R5 z9 D* K
$ h4 S2 I+ Z$ x0 T: a
: i- T& H$ o8 ~$ |$ O4 r0 r最后还提醒下,如果CubeMx版本比较低时,HAL_PWREx_EnableVddA()函数需要自己手动添加。我目前CubeMx 6.9.0版本已经不用手动添加了,创建工程时会将其自动生成于相应位置。
! P6 Z! K, k2 P$ Z! J; f- \/ O8 A" U, v" g
6 ^, R" x. ^5 a! ]; @( J
7 [3 Z5 ~, r& M+ I3 P! f; S9 l如有侵权请联系删除, z' _' F P8 r/ B
; W# \# i! {4 A* X" @转载自: 茶话MCU
2 j& Z: |3 z" \7 d
! R8 ]9 \/ O4 p+ M* ]: y
" I1 h4 y, n3 R2 t; e |
学习一下