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

【经验分享】基于STM32G4芯片的DAC应用示例

[复制链接]
STMCU小助手 发布时间:2021-12-8 22:00
有人使用STM32G431芯片做DAC应用,具体来说就是通过DMA将数据从指定内存传送给DAC数据寄存器,并由定时器触发DAC转换。他发现总是没法实现该功能。这里简单介绍下相关实现过程,并做些提醒。这里要演示的基本功能就是让DAM将内存数据周期性传输给DAC数据寄存器,最后输出一路正弦波。
7 y, o# q6 D  l3 |, A$ O+ _" N6 B! o* }
8c8aec0947a9e081baa317138ac945de.png

) q6 j7 t1 w9 G- x; y* ^  I2 d8 `
5 Y' M9 t5 u: _  Z9 n5 U! w; G6 T/ E
结合STM32G4芯片的特性,这里可以有两种实现方式。$ C4 l4 l  k; ^0 n2 A
9 p3 C! m0 f8 \* @; @' l" a
第一种,DMA的请求来自于DAC1的转换事件。第二种,DMA的请求来自于定时器事件,下面用到的是定时器的更新事件。这里就两种实现方式的配置及相关用户代码简单介绍下,以供参考。
% }$ I+ s2 c2 H6 q. `, k, x
7 O0 u! m: T- ~我们先看第一种方式,即DMA请求来自DAC转换事件,定时器3触发DAC的转换。
2 ]4 }' N' x0 W( V: Z+ W% \- x0 i% q
使用CubeMx进行配置,主要配置如下:/ b) |& L; P& V* M8 Z; Q! D. ^0 m# {
d1020b7d0f8f4894eb7b709ab4cbed6d.png
  e% n8 d, X) Y1 u4 [: m
5 O- M1 d5 h3 t/ b3 W% L) b
& h5 v1 V! [: q) H
ddd67d8a4616146cdf0ec6419da513ec.png
/ N: ?$ Y5 U5 z
2 ^; R! x! I  n* m" v; |: c8 w
0f1f5180cdc185196607e3ef27b9e215.png

! x9 k7 B9 S* I9 d8 S4 o
4 ~" O, F! O' P- ?9 ?; R完成配置后生成初始代码,再添加下面代码即可验证测试:
- R/ @$ a- D/ k1 `+ X9 s8 |/ u; O  N/ t$ g; f
  1. #define   Tpai     (2*3.14159)
    6 Y1 R1 w% I$ C9 v6 t
  2. 2 k2 R8 B: L" Z
  3. uint32_t  PData[200],Dac_data;
    : f4 w( U6 S+ O  e, H

  4. ) ?" \2 |4 `8 E, L2 i" T
  5. uint16_t     i;- L( ?& x4 a; B, j

  6. 2 V% g; c% N' ?2 F8 K
  7. for (i=0;i<200;i++)! n+ o% q/ b$ U6 V# W: f
  8. $ d# l3 M4 e* P
  9. {undefined
    5 _% l' v" t/ n8 a' U1 {. _

  10. ! ?7 @1 k4 f+ E; y4 ^+ M5 Z
  11. PData<i>=</i>) W$ ~7 \$ F0 }: C' g

  12. . b* [  K$ _- a& m; R/ Z: `
  13. (uint32_t ) (2000*(sin((Tpai/200)*i))+2000);, X& n9 f/ d/ i0 I& X

  14. * I! S; l  h6 E6 N5 U
  15. } //prepare data for DAC
    % J( D, K0 y# u. t, m9 t1 a
  16. 9 O" q5 p9 h* T* i$ x2 Z
  17. HAL_DAC_Start_DMA(&hdac1,DAC_CHANNEL_1,(uint32_t*)&PData[0],  200,DAC_ALIGN_12B_R);8 q9 a  O% F. R( ~* T: E$ e5 E+ I6 b
  18. ) R- Z9 k3 n/ X
  19. __HAL_TIM_ENABLE(&htim3);
复制代码

0 l: A2 {  f: W  ^
) ^% }3 k3 l, G3 [2 @6 ]- A5 ]( R# K- B+ |
上面配置的DMA传输方向是从内存到外设,目的和源的访问宽度都是32位WORD. 当然也可以是内存访问宽度为16位的半字,外设访问宽度为32位字。即DMA的配置像下面这样也是可以的。) b& K1 }: O9 ]: h9 i; J

; c1 [$ C/ C2 R! G  K) K) x
d1a3b9537ab66535982e8b0cb86d3bbc.png

2 r* R0 V( r; a& t8 t, ~) b, b. q" E, y5 K1 t
其它配置不动,代码稍微改动和整理下即可。参见下面代码:
5 s1 |( Q9 D8 r* b5 E! B
% N- v  i0 s) w5 _( y' J
  1. Uint16_t  PData[200],Dac_data;
    7 Q0 Y5 w% }5 G" d# j2 B" e1 z. @9 Q
  2. * ~1 Q- c( A( U, s
  3. #define   Tpai (2*3.14159)
    5 K, a; y+ ~. p  l

  4. % I+ d, K. D8 y$ g: z6 i
  5. uint16_t     i;
    * ~% r' z! ^9 T6 y2 m6 W$ @1 Q

  6. + e" T+ u4 a2 X& _. I
  7. for (i=0;i<200;i++)0 K8 v" ?' i8 S! q, _5 [2 R, }( s1 G

  8. $ |8 L, Q3 |- c8 z( f# n8 B
  9. {undefined
    : }  S  S% C4 A1 l

  10. 7 X2 L% E5 a- M
  11. PData=
    & c3 [/ j# \& D1 J5 u/ A" |2 y

  12. 9 [! t* |+ c" p4 E; O7 d4 a6 z
  13. (uint16_t )(2000*(sin((Tpai/200)*i))+2000);
    5 x. E2 U! ^" w- T0 a
  14. . y* `# E9 A+ C6 M( @
  15. } //prepare data for DAC8 H  N' c2 C* U3 ~$ Q
  16. " ^* M/ T: X- y0 V3 @8 J
  17. SET_BIT(hdac1.Instance->CR,DAC_CR_DMAEN1);
    2 I/ z5 D( S! d

  18. - w1 U' _2 [) |8 v4 U) }$ g

  19. . U& m, Y, C6 @/ m8 V
  20.   a9 ~, V9 s6 V: g) b: q* b
  21. HAL_DAC_Start(&hdac1,DAC_CHANNEL_1 );* Y7 p$ Z4 I+ r+ k- ?
  22. , t7 D6 W3 V5 ^* _% B: t7 t) H
  23. HAL_Delay(2);
    6 @! `- w0 L7 {: Z

  24. # T5 @3 m9 u9 q4 |2 x  q

  25. $ w- M) {" r4 ^3 ]; O
  26. ) h# }& d2 ]+ L/ h
  27. HAL_DMA_Start_IT(&hdma_dac1_ch1,(uint32_t)&PData[0],(uint32_t)&DAC1->DHR12R1, 200);
    4 F" {1 S3 ^; C' K( q7 I
  28. ) t0 Z" W( U4 \8 Q2 {4 i

  29. * X/ A" N( g( p2 E1 N

  30. * e! J0 p  c* M  C/ P0 ~; o; I
  31. __HAL_TIM_ENABLE(&htim3);
复制代码

$ _2 c3 y0 D- H$ C1 ^# D
4 \+ ^2 |+ [, y& g. j) K5 V$ I4 i* u) l
- w& G/ f  q0 H* ^, _1 B7 g0 ~' _
( J! G0 x2 Q5 ?第一种方式就介绍到这里,再来看看第二种实现方式,即TIMER更新事件作为DMA请求源,同时作为DAC转换触发源。/ {3 c1 Y2 K8 p) l4 L$ b3 `
4 U* e1 A/ F1 y6 e# j9 f
基于CubeMx配置,主要调整下DMA配置,其它配置基本不动。
2 \3 L" p" k0 v7 Z) t8 q* [
$ ]/ u* E  ]$ a4 u( h2 {, ]7 e

& z& W3 r* Q5 j1 `/ [  e! n
/ V+ u4 x4 z; s$ e7 }0 R
0 L0 g/ _4 |" T' H: P6 n& P) d主要是DMA请求事件变了,其它配置跟第一种模式基本一样。
, z& `6 @- p! F4 I- P+ j& Y, Q# }7 A% K! x  h
配置完成后生成初始化代码,再添加下面用户代码:
3 \: @, W& L, P9 p% [
0 M: i- x. K" A- y7 _, V
  1. #define   Tpai     (2*3.14159)6 k/ _/ p: n( {& L
  2. 0 k  c! q+ B3 o; O1 m
  3. uint16_t PData[200], Dac_data;* y! \' R7 x6 Q9 e' U+ D
  4. : E' V0 c# w+ B0 u( Y1 F
  5. uint16_t     i;4 U( k7 T$ F; m
  6. 1 V  z) h) K+ \1 Y' |" t! L
  7. for (i=0;i<200;i++)
    ( y5 Y: b* T; C3 v/ [9 ?1 j
  8. / ~6 z7 x5 f) W
  9. {undefined- z, |3 Y/ ?/ s' |+ {

  10. ( i3 z) I) t: e; J- B( i: N8 B' V# D
  11. PData=
    1 [- j& z' d2 ]9 _, a+ o

  12. ( M1 h+ J' ^/ q9 \& _7 ]
  13. (uint16_t )(2000*(sin((Tpai/200)*i))+2000);
    * j3 l6 @4 S8 U9 N7 o

  14. 7 K, U7 o. |( G% T8 ]& n
  15. }
    ! h2 I0 f# D7 @  J# h

  16. 2 w8 K: l( T- M& T: X" F) K8 O' t
  17. HAL_DAC_Start(&hdac1,DAC_CHANNEL_1 );5 Q( }, F' U' U
  18.   f7 y) @2 `% B: z- w7 x
  19. HAL_Delay(3);
    ; _  d  Z  W- a! ?
  20. , N5 v4 |. ?5 Q- l" ?8 J# u: o

  21. 2 h. c5 u% K) f: n; b: a

  22. . j* @" }2 A  E
  23. HAL_DMA_Start(&hdma_tim3_up,(uint32_t)&PData[0],(uint32_t)&DAC1->DHR12R1, 200);% e* q/ H) ^: r" _: S( m

  24. , w" Z$ h& ], Y- d" |5 U
  25. 3 }" r/ s5 B( l9 z5 E: Q) q/ ]# B
  26. + S( w- |  ]! u
  27. __HAL_TIM_ENABLE_DMA(&htim3, TIM_DMA_UPDATE);
    $ q9 P2 @* r! T

  28. 2 M! s: T8 E0 K6 \; _; ]
  29. __HAL_TIM_ENABLE(&htim3);
复制代码
3 \1 ^. ?: w" o

; J1 r6 b& o1 m& a3 [7 K. q% ~5 x; e这里要提醒一点,G4系列的DAC1的数据保持寄存器可以一次放2个通道的数据,在使用DMA传输时,即使只用到1个通道,DMA对它的访问也要遵循WORD对齐,不然你可能会遇到麻烦。
5 H2 R6 x& R. U: a% K; `' z& F9 \; u3 g7 E8 `
如果说,我们不使用DMA做数据传输,只是手动给DAC喂数据,那如何实现上述效果呢?这时我们可以使用软件触发DAC的传输,手动给DAC的数据保持寄存器赋值,参考配置及实现代码如下:
2 e' W- v- O# a# L5 j
  o6 O, a1 b% @, G2 G
81958bbf0c7325cd86a0ecbf4dc138ef.png

" h' A4 Q: I) {/ ]" K+ m! S7 g0 O9 P& i$ V- ]; ?7 w
% g( [0 P' [0 V
相关用户代码如下:
- N0 q* W# C1 Z/ Z& [4 b: U% u+ a/ _! f/ r$ C
  1. #define   Tpai (2*3.14159)
    & G7 _6 S! l, R* V! z
  2. 4 y3 h$ b# |! o. ]& ?7 _4 r6 {
  3. uint16_t PData[200],Dac_data;
    ) G  R/ f' i8 N
  4. ) j3 L, d$ V  H5 w# u0 B+ t7 \/ }
  5. uint16_t     i;6 S* F$ ~! {  w  p9 y1 f
  6. 9 v5 X5 G( x' W; G# I1 V% W: t. W
  7. for (i=0;i<200;i++)  [# j8 \" Z# M# X4 e
  8. 9 G2 U/ H2 D2 U+ J/ a. U" J9 c: f
  9. {undefined9 Z# J2 n( `3 n5 q5 z' b7 m/ P' S

  10. / t) q7 I3 s5 f9 Z2 U3 s- Q# K
  11. PData<span style="font-style: italic;"><span style="font-style: normal;">=" w8 `- T) T0 X

  12. ( o) n' Q  Y  R% i: Z. P
  13. (uint16_t)(2000*(sin((Tpai/200)*i))+2000);" A/ ?+ y; d% r
  14. " }* {4 Y: s' O1 S
  15. }
    ! w( e  A4 `2 x) Z7 h, L  G

  16. 0 z; }5 l* d' |6 S' v& F+ N% I
  17. HAL_DAC_Start(&hdac1,DAC_CHANNEL_1 );$ `2 B. B% G5 Z  A1 z. h
  18. 6 q+ z4 {7 B8 `% B3 H* N# M
  19.    HAL_Delay(3);0 b. A% Q) x0 m

  20. 3 F  p: c1 g  R; w$ O
  21. + C& z" Y' k* t! s2 |
  22. . {3 ~5 F7 v# r3 ?
  23. while(1)
    : \7 I- Y9 J; Q' r0 I4 y
  24. 6 [0 b: E) V  v
  25. {undefined, L8 i; |. J7 b& L- M

  26. 6 Y! l+ c( s0 Z" P$ ^0 A+ g2 q
  27. for(i=0;i<200;i++)
    0 A  J' M6 ^/ E

  28. , L( F, |6 O' ?
  29. {undefined4 ]0 N5 p6 P9 o) l! i! K& a$ X
  30. : ?8 D% w( d; _) X2 f
  31. DAC1->DHR12R1= PData</span><span style="font-style: normal;">; 4 B$ F" s+ ^3 [! l6 F! x# b
  32. % T% g- U3 l2 S' b+ h. W1 K, J
  33. SET_BIT(hdac1.Instance->SWTRIGR,DAC_SWTRIGR_SWTRIG1);6 E4 x3 g6 y: O) w+ A
  34. 3 @# x1 y5 ]/ Q$ a6 Q
  35.       HAL_Delay(5);
    ! O, m' g9 D: [2 q+ ?8 E

  36. 1 J3 m0 U5 E. h- `7 l# g; y

  37. , M' j3 u% a7 S1 ^8 L! V) S
  38. 2 S; m% {; [) k0 P
  39. Dac_data = DAC1->DOR1;//for debug. s1 S% f, ~4 \4 I
  40. . T/ H; M* j/ W/ a

  41. 7 z, C, D# r/ Z1 Y+ _

  42. * u- @5 A3 \" c# f4 A/ a8 q) u
  43. } 5 Q3 Y1 h) b) [: G: H/ p

  44. + ?* e- `/ ?* Z& G' _) b
  45. }
    ) ]5 F. Q+ W" _$ B, F; a1 o! e% h- g
  46. </span></span>
复制代码
0 m0 W1 \1 _: `* U
总之,不论使用哪种方式,都可以实现我们所期望的结果,即输出如下正弦波。
2 b$ \  {! j% i& i# n# x
; y; t) H8 n/ I! a* K  Q
692bd68b1c31d5aa2a4b73541244f56e.png

" h6 D7 i" Z& _& k( W3 ], h5 T2 j
+ b1 ^% L9 v9 {8 \# U8 a- k: r1 T好,关于STM32G4的DAC应用就简单介绍到这里,STM32G4系列的模拟外设丰富而强大,此处算是抛砖引玉。这里做些分享也是为了让其他有需要的人少走弯路,加速开发进程。【文中代码都很简短、直观,就没做注释说明了。还有个客观原因就是在微信公众号里排版也很费劲,字符不太好对齐。若有需要交流的可以后台留言。】
2 A; u- W; m  I8 C8 q
2 f0 d# p5 u  a7 \
5 L. p3 U6 J" f
79bba335bff508c4f57300f0f57049de.png
收藏 评论0 发布时间:2021-12-8 22:00

举报

0个回答

所属标签

相似技术帖

官网相关资源

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