有人使用STM32U5系列MCU开发产品,在用到ADC结合DMA传输时遇到点障碍,这里针对片内ADC1和ADC4基于DMA标准请求模式和链表模式演示下实现过程,以供参考。
7 e, _; _3 i' u6 q" r/ k/ L4 f; q/ A- V! k
( a% r9 h$ {5 J/ M先对ADC1基于DMA标准请求模式做演示。9 `! \1 |3 {5 T7 x0 w
+ O0 o0 @' w" i
! s8 B: D7 U: z; m随意选择ADC1的4个通道,扫描模式,连续转换,DMA传输转换结果并令DMA工作在外设字到内存字的循环传输模式。使用CubeMx进行配置。其中DMA通道使用Channel 1。8 S- }$ [7 X0 R9 a8 B3 l
% `% S8 J5 H. E- ^ \1 T; H! o4 |0 |
# G7 U" v4 M2 W# r9 B
5 u0 b2 C) {3 S. c' E$ `+ X! P+ u Q4 `7 V3 h
. n. M0 I+ H# R8 e% E3 _: A
( r$ L0 a7 e5 ]2 `! e
4 m* X! i& t$ R( l/ X i/ G/ \9 `# I. }6 E
# M. H2 ]8 l/ b$ h" Q2 x
相关代码:- ?+ l0 @5 N8 _' M3 L
- #define ADC_BUFFRER_SIZE ((uint32_t) 8)
8 c3 u0 m3 F6 h, v1 v - uint32_t ADC1_Result[ADC_BUFFRER_SIZE];
" P4 g: T' d/ M, N( D! l* c - , V% L# l2 J" E, U9 G
- ADC_HandleTypeDef hadc1;
5 f: Q" a2 n) ?6 p5 U - DMA_HandleTypeDef handle_GPDMA1_Channel1; //For ADC1" X1 {9 }+ R# ^+ u8 q4 n: K7 S
- ( [0 l- T5 T1 _* @
- /* USER CODE BEGIN 2 */# x3 V1 z- j& _1 m0 b U
- " d' V) H- N1 y3 w m- Y
4 M. ^1 p; F+ Y' d1 M- HAL_PWREx_EnableVddA(); //add it manually with lower cubeMx version
' F* P# N& Z9 n5 W, @ -
: ]! M2 T0 |: ^6 g2 e - __HAL_LINKDMA(&hadc1, DMA_Handle, handle_GPDMA1_Channel1);
) ?! X3 O0 y3 M0 @; R, ]; S - ' O' c# j4 q8 [5 i$ a5 l
- if (HAL_ADC_Start_DMA(&hadc1, (uint32_t *)ADC1_Result,8 R8 D) x2 }2 `3 q
- (ADC_BUFFRER_SIZE)) k' U& [) D+ m; M$ x2 e9 x, _- F
- ) != HAL_OK): {0 @/ p$ J8 s9 K) q
- {4 D/ n1 L! ^4 U! c: d
- Error_Handler();( \, y" h" K3 O, J
- } % b8 K; v0 V. n3 v! J* J$ x6 ?
- # u5 E4 n3 x0 t
- /* USER CODE END 2 */
复制代码 " x! p( O7 v9 R Y7 a' B5 n
运行结果如下图所示:【目前4个通道我是悬空的】; ~" G" b* m% s/ x' s
% C7 A' s% U4 [7 B8 Q9 A$ W# p# q# b4 p6 I
: g; p9 J% {+ X6 h7 J5 b/ c& U
, V# b) z2 O( k9 |) q1 F6 u! \* s, F5 t
现在对ADC4基于DMA链表模式做演示,其实就一个节点。
) M5 V! O/ w3 h8 A, Y( a* [5 V- x3 o, L+ {/ I* {
3 s' i# ]% r; y0 b k( v! E: _
选择ADC4的4个内部信号通道,扫描模式,连续转换,DMA传输转换结果,并令DMA工作在外设字到内存字的循环模式。使用CubeMx进行配置。其中DMA通道使用Channel 0。对于内部信号的采样,往往有最小采样时间要求,我这里的演示随便选了个参数,具体应用时请参考数据手册及当时ADC时钟具体拟定。特此提醒!
' ~) x- s# z' J) j3 }5 O( u- _6 ~! R" I8 w$ M2 t, i- ~) H' O
4 P! e/ G: W+ O$ ?2 P, @5 t
/ r- k( z2 T5 b- V- ~8 p) j' H& `8 m- c7 u1 n+ Y
5 l4 w9 k7 f" M: Y, F: W
关于DMA链表模式的配置在CubeMx界面里的Utility菜单下。& i3 \6 [" O# t: @. n
$ }9 z0 v: B: {; B; w/ i+ a' v) i9 b/ f w7 m
9 h- i0 m( _' x B( @* A) @) p* p
7 L# o. D$ o+ H, k2 w H
3 @4 E8 \6 i( a2 U% d/ M
2 [2 x& v0 D9 e
/ n7 y5 B1 c" M, L8 ^" ]* Q( k# V+ `
5 ^6 F* R$ G, {# m. D8 u$ [ n+ J
' }$ T n" I# b5 a" b5 b相关用户代码:
7 C4 }4 h" B& L' X& y2 D- /* Private variables ---------------------------------------------------------*/
& z, K0 h. W X7 Z" f; D4 W9 K - ADC_HandleTypeDef hadc4;
8 z: m1 T8 l7 g4 M - DMA_NodeTypeDef Node_GPDMA1_Channel1;( P/ w5 B* j9 I& t1 Q8 K
- DMA_QListTypeDef List_GPDMA1_Channel1;- V, O& O% c: }2 e2 h
- DMA_HandleTypeDef handle_GPDMA1_Channel0;9 _2 K6 n5 V. N; H
- /* USER CODE BEGIN PV */9 o- N; T5 [% C( z0 d4 f- O9 n; k" ?
5 O0 h" \ b% A- /* USER CODE BEGIN 2 */
9 u! z1 Z& L5 I( C" z- R
7 v( c) D* v9 V; e+ G& Y0 K: R& s- HAL_PWREx_EnableVddA(); //add it manually with lower cubeMx version& | s" e# d! h7 I" i
8 \' ~9 C: X' w- MX_ADC4Queue_Config();
3 p+ y7 w7 b# N* t X! k
2 M/ p$ U' ?# Z% m- __HAL_LINKDMA(&hadc4, DMA_Handle, handle_GPDMA1_Channel0);
5 T7 J0 f: n z' s6 ~ - . D, W, \7 b- E/ J& ]5 Q
- HAL_DMAEx_List_SetCircularMode(&ADC4Queue);- g3 q2 f* k- N6 I! g4 H
-
+ Y: O/ Y6 d' y1 z, c - if (HAL_DMAEx_List_LinkQ(&handle_GPDMA1_Channel0, &ADC4Queue) != HAL_OK)
2 E- c* D- R3 \" T) K# o" ^) U8 K - {
2 Z1 }8 S6 F. L( W! V. O* m$ B - Error_Handler();
: ]! ?+ t7 P5 }: q. k# V0 Q* s - }# o0 R0 {) ^7 s3 ~# U- B. P
- ' E* \# c: n/ y e2 p% Z
- if (HAL_ADC_Start_DMA(&hadc4,
. {6 b* c' g" ^ D% B- C - (uint32_t *)ADC4_Result,
8 ~& h& S) f* l S - (ADC_BUFFRER_SIZE)1 C. Z& X9 z+ P8 m$ ]) Q* O5 {
- ) != HAL_OK)1 U. \5 i- f+ e& r8 k- O6 F3 c: s
- {4 {) a8 `3 f6 S4 M$ S% T- }0 y9 I
- Error_Handler();
1 q8 D" s6 y& Y* u* K4 F, N - }2 I$ {" B1 S0 p
- /* USER CODE BEGIN WHILE */
复制代码
1 m: q) n' l j) x结果验证【显示了2组数据】:- \2 u; l; P, c G0 M0 e2 o: z
2 D3 w$ W) g; A' y
7 p# L* @& Z9 V
/ ]; n; }0 r6 J) C) t
# x0 o) \$ M! D0 m8 w* k: ]
) r! w2 I9 V" d* r0 T8 ?. J最后还提醒下,如果CubeMx版本比较低时,HAL_PWREx_EnableVddA()函数需要自己手动添加。我目前CubeMx 6.9.0版本已经不用手动添加了,创建工程时会将其自动生成于相应位置。% ~3 C' q, z! T
: N% Z+ a( m4 j5 ]- K
3 n- n, p6 T6 e
! b, T$ v# B: a# [+ d如有侵权请联系删除
; D, D" y z' z9 j* Z, F, T8 t0 S P" U0 j5 x; `3 r+ `
转载自: 茶话MCU) r1 k, w# o6 @
9 M: l; n4 g& N+ I. F- P. J
; t( s1 |8 }' |4 l" E( Z' D |
学习一下