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

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

[复制链接]
STMCU小助手 发布时间:2021-12-8 22:00
有人使用STM32G431芯片做DAC应用,具体来说就是通过DMA将数据从指定内存传送给DAC数据寄存器,并由定时器触发DAC转换。他发现总是没法实现该功能。这里简单介绍下相关实现过程,并做些提醒。这里要演示的基本功能就是让DAM将内存数据周期性传输给DAC数据寄存器,最后输出一路正弦波。
" A" \! z+ s2 p/ B+ [2 e+ l3 l  p5 Z% ~
8c8aec0947a9e081baa317138ac945de.png
  a5 s2 \9 y  r2 j6 W3 W  W  ^' k

5 V. _4 L" _( Y, @# q6 l1 e5 J0 d" l1 D
结合STM32G4芯片的特性,这里可以有两种实现方式。5 E8 e: A8 v8 [, p5 m/ T

; E; u" i+ p" c$ n/ L5 W1 x第一种,DMA的请求来自于DAC1的转换事件。第二种,DMA的请求来自于定时器事件,下面用到的是定时器的更新事件。这里就两种实现方式的配置及相关用户代码简单介绍下,以供参考。7 F- H8 V; B  q6 m1 N/ A
3 g' r; [" J! E! s3 d6 [3 Z3 p
我们先看第一种方式,即DMA请求来自DAC转换事件,定时器3触发DAC的转换。" k7 t1 D( r# f1 Z6 L2 q
$ O  o: r. U2 A3 d. g
使用CubeMx进行配置,主要配置如下:
8 s" X* A: ~- s# N5 v/ ^+ R5 A
d1020b7d0f8f4894eb7b709ab4cbed6d.png
6 s0 h7 X8 Z& f( h1 `1 y: Y1 R& w

: L1 u& b9 a  t
9 C, i. `8 B0 ]9 Z6 L# U) x7 j3 Y4 p
ddd67d8a4616146cdf0ec6419da513ec.png
) i$ }9 v" I$ r& T

9 K" y, U6 c+ h! X8 _. ^
0f1f5180cdc185196607e3ef27b9e215.png
/ l& W; H. K" _9 z; J! ]
4 r& u% d5 G. E3 f
完成配置后生成初始代码,再添加下面代码即可验证测试:( D* I: k9 u' L, w& {9 C
/ W  D5 }) L% |
  1. #define   Tpai     (2*3.14159)$ e3 Z3 S" C" x% q
  2. * E& f; z7 ~8 }& R4 W7 t9 D
  3. uint32_t  PData[200],Dac_data;4 E9 `$ m6 i# j+ G5 v
  4. . i& [$ \' c! d3 t$ v4 g6 @  l
  5. uint16_t     i;! m& k$ H% }3 Q$ k# X

  6. " m0 {% i) i. J$ h
  7. for (i=0;i<200;i++)
    9 k. a* q8 ~9 p0 v- G
  8. . B) U! @: q9 L6 G5 X
  9. {undefined2 i# h/ V% R# o7 A$ b  p: b9 A

  10. / Y3 z# m! E! ~" q8 M% X
  11. PData<i>=</i>
      o8 G# c! [4 p, y+ s0 Q& W& c4 n

  12. * A5 ^0 J3 X+ O* P
  13. (uint32_t ) (2000*(sin((Tpai/200)*i))+2000);* l$ @! B3 ^  `. _- Z) c, Y
  14. , l! I: {9 w# ^4 |8 Q( X
  15. } //prepare data for DAC
    + {6 F& E* h4 m+ Z1 g5 H

  16. * n; y) N8 b( W; f8 I0 O
  17. HAL_DAC_Start_DMA(&hdac1,DAC_CHANNEL_1,(uint32_t*)&PData[0],  200,DAC_ALIGN_12B_R);2 }: j5 M9 s& P0 r; e
  18. : m3 O4 \4 J$ r. `* Z: |% V, S! I
  19. __HAL_TIM_ENABLE(&htim3);
复制代码

, M( k2 H% k3 G- o% T( L" s% b" I  H. ^$ D% x$ N6 k
2 _. h4 O4 o0 @- S4 r$ n
上面配置的DMA传输方向是从内存到外设,目的和源的访问宽度都是32位WORD. 当然也可以是内存访问宽度为16位的半字,外设访问宽度为32位字。即DMA的配置像下面这样也是可以的。
7 n7 X4 @* i/ L4 F) A2 `9 N1 h# o! G, e4 ^# p+ a3 @# F/ P$ {
d1a3b9537ab66535982e8b0cb86d3bbc.png

! a& {9 G" G$ a# s+ D0 L& N9 E, I8 _' s" S
其它配置不动,代码稍微改动和整理下即可。参见下面代码:# z, Z) _+ E. o% }# ], R

  J8 Y& q* y9 r1 h1 f
  1. Uint16_t  PData[200],Dac_data;: s8 {1 {- S. Y
  2. 8 U3 [& V9 T1 F6 e. N; b  V8 w& a
  3. #define   Tpai (2*3.14159)- `. e- o# x& d  T) t# ?  x  |8 W
  4. 9 l7 D% F/ d' m9 K+ f
  5. uint16_t     i;/ |* `1 j+ z" G. U0 N& k
  6. 0 C+ g: |6 z9 u8 r; B
  7. for (i=0;i<200;i++)! }/ P) N6 D% B- u  N

  8. 1 g# U2 A5 l' l! K0 O
  9. {undefined. n, e& y; c7 X; t, O
  10. - ?/ m& F7 N; x2 N' e. C
  11. PData=0 M' O; s/ q( y2 W7 |0 q

  12. " }2 `+ ^& k" A: y5 X! J: [
  13. (uint16_t )(2000*(sin((Tpai/200)*i))+2000);
    1 H0 F) \& B/ e. W
  14.   [5 l7 n4 A7 f
  15. } //prepare data for DAC
    7 s" m1 b; q9 u: z" |& `
  16. " m& |* V& ^2 K
  17. SET_BIT(hdac1.Instance->CR,DAC_CR_DMAEN1);+ f3 A. l' |) }/ M4 g
  18. % V) u+ H1 ~: \7 e, Q% K# K! c
  19. 8 f) O1 G0 v) W/ a1 J% x( ]
  20. & P6 F2 B( i. W" A; t# e
  21. HAL_DAC_Start(&hdac1,DAC_CHANNEL_1 );
    : u% v; _3 S- O' T6 Q
  22. 6 F# T* c: I6 A! j
  23. HAL_Delay(2);% \8 c- Z+ P( d9 h) ]6 U. `' ^
  24. * X5 b$ K5 H. l6 p! w
  25. ) m) R$ m# x  G

  26. . Y# X4 a4 q8 W! Z$ O
  27. HAL_DMA_Start_IT(&hdma_dac1_ch1,(uint32_t)&PData[0],(uint32_t)&DAC1->DHR12R1, 200);0 K8 `0 @8 j- r9 L, ]
  28. ' X( e. S+ ]5 x! M) q$ j

  29. ) @4 A3 b% s# Z2 F

  30. % D& u8 F- I" W+ X  A
  31. __HAL_TIM_ENABLE(&htim3);
复制代码
/ L: W% s+ c( h/ y" g- f) z

. J7 b0 W/ q; s* S& Y
  v, y- l  }9 A8 i, x5 |7 W) g
' ^5 Z. ]: \, J. _第一种方式就介绍到这里,再来看看第二种实现方式,即TIMER更新事件作为DMA请求源,同时作为DAC转换触发源。+ C: l$ U) @# Y2 N& h, o: q
3 W# Y* |/ z1 x9 C; ?
基于CubeMx配置,主要调整下DMA配置,其它配置基本不动。/ x! V8 X2 e; b  A
  g- K: J& t3 B

6 D* `- L# s: p4 B
$ ?$ D0 G" G5 L% E' B, E5 E) p  h  E" p( I% m3 ]$ V6 J1 W6 ~2 e
主要是DMA请求事件变了,其它配置跟第一种模式基本一样。
1 G# q" M- D) T3 C
3 \0 t' J$ P; B" D# m9 k9 C9 s: C配置完成后生成初始化代码,再添加下面用户代码:# e: \5 W6 ^3 I" q1 T
3 \' O+ q! B4 A1 Q# K! F; F
  1. #define   Tpai     (2*3.14159)  C7 m# ^  {' k# C1 \3 P1 a
  2. 2 P* \4 [2 |7 I3 K& U: Q: t/ v
  3. uint16_t PData[200], Dac_data;; h2 e# e1 \7 v% t& }; Q

  4. + _* q) A7 L5 ^
  5. uint16_t     i;
    ! f. C: Q% k( c+ q% ~4 a" i
  6. " ~( w& N. m, e/ Q
  7. for (i=0;i<200;i++)
    2 N# D5 {& H% ^6 E; O2 J1 I
  8.   L) O. o* q7 a
  9. {undefined  J6 R* |9 h/ b( P; Q8 D+ z

  10. / P6 v$ K9 j$ W0 S
  11. PData=: I1 G+ R4 F& G( u0 |

  12. ; _4 P4 p+ s- T7 t
  13. (uint16_t )(2000*(sin((Tpai/200)*i))+2000);
    - g2 L# R* u4 {. Z. P4 {4 V
  14. ( D3 A3 y5 o! _2 J9 x7 z
  15. }
    ! |& ]- p! N$ W
  16. 5 j- z" M4 F) `! V
  17. HAL_DAC_Start(&hdac1,DAC_CHANNEL_1 );
    6 l+ e# l( f; [& ?5 c: W
  18. . a0 a6 p4 D+ \) r; L" o
  19. HAL_Delay(3);
    ' B3 E$ v5 I* G8 i" d

  20. $ ], T) r& H; ?; v+ k/ A

  21. ( i" j- f3 m* ^1 A# [* t9 u
  22. . ^! r6 B2 L# o' C" }
  23. HAL_DMA_Start(&hdma_tim3_up,(uint32_t)&PData[0],(uint32_t)&DAC1->DHR12R1, 200);  [# f+ B2 N3 I' N4 J( [$ \

  24. , w8 w: ]$ I; e' B* ?

  25. 7 \5 r" M5 ?3 w4 S. e+ E* i+ P

  26. 4 |$ O- S2 C! t5 U3 j
  27. __HAL_TIM_ENABLE_DMA(&htim3, TIM_DMA_UPDATE);
    9 Y  k* Q* v7 ~9 ?+ V# n
  28. " T1 K0 {! b7 |7 `* t4 m
  29. __HAL_TIM_ENABLE(&htim3);
复制代码

0 i. K9 Y9 M" I' y4 c* a0 h5 K/ k/ }8 T6 K5 e5 |/ k/ m
这里要提醒一点,G4系列的DAC1的数据保持寄存器可以一次放2个通道的数据,在使用DMA传输时,即使只用到1个通道,DMA对它的访问也要遵循WORD对齐,不然你可能会遇到麻烦。
2 X# t' n" h) I% ~# c6 |
0 ~' o, G+ M) B) p4 a如果说,我们不使用DMA做数据传输,只是手动给DAC喂数据,那如何实现上述效果呢?这时我们可以使用软件触发DAC的传输,手动给DAC的数据保持寄存器赋值,参考配置及实现代码如下:! V& K8 m  c5 B7 y$ H2 n# J

; l9 r% B+ ]! E
81958bbf0c7325cd86a0ecbf4dc138ef.png

9 r/ P( C8 ]8 \0 E% [1 F5 V9 S" a/ a
: n  t$ d  E9 e7 g! [; {
相关用户代码如下: ' B7 B% S2 K; E0 |/ a7 C  \0 J1 ]
3 j% d3 |9 E5 w8 F5 O, p
  1. #define   Tpai (2*3.14159)9 C! P. A. G. [- j% I/ B$ {

  2. $ Q* j8 {! }! w  s
  3. uint16_t PData[200],Dac_data;
    0 Y+ Z/ A: z2 v
  4. ! e6 ~/ K) ]' p3 S
  5. uint16_t     i;. S1 v' p; ?9 q, B
  6. , \% L. S# q, ^7 T' ?. A9 n5 q
  7. for (i=0;i<200;i++)- }8 R* I0 J7 d  X9 W# e

  8. % O8 ~' `" J$ u
  9. {undefined% y+ ^+ B! z# }3 u" t

  10. * O6 z% f* q  w6 y
  11. PData<span style="font-style: italic;"><span style="font-style: normal;">=
    : w* O% n7 h* m( V: a; Y

  12. 1 v3 R  u6 V6 B- a" D( c
  13. (uint16_t)(2000*(sin((Tpai/200)*i))+2000);0 p; Q+ E; w" o; f- I3 K

  14. 8 t# y  Y! M' n* p9 v- |# a
  15. }3 M/ Q, m, P3 H  }4 P
  16. % [: \* ~& Z# ?  J$ E
  17. HAL_DAC_Start(&hdac1,DAC_CHANNEL_1 );2 b$ E3 B  ]1 x

  18. . e0 w+ _* u4 G) p2 T9 J
  19.    HAL_Delay(3);0 }) `( V1 S; U
  20. ) o  X. j5 l! I8 a9 [  A0 p# F! f

  21. % {9 y! p6 {- m! }
  22. ( i4 r! ]. |5 V) Y$ M9 @
  23. while(1)
    9 W3 k8 e3 x6 z& ~

  24.   _- B! Z2 i. d( W
  25. {undefined5 h' Q1 [0 D7 e3 @' A5 j

  26. $ ^9 Y1 c6 G3 M1 ]# {0 ~- j: ~
  27. for(i=0;i<200;i++)% g) L6 W, X6 [% B
  28. / D9 O3 s7 B3 \( u# N* E
  29. {undefined7 H. B* G( E8 ]* c. f: G' g3 V8 }
  30. # {$ l" f6 Q) a6 g( R  P  ]& W
  31. DAC1->DHR12R1= PData</span><span style="font-style: normal;">; : }8 ^9 f5 E9 u

  32. 2 A6 G8 M) Z# O( _. g- X: O
  33. SET_BIT(hdac1.Instance->SWTRIGR,DAC_SWTRIGR_SWTRIG1);
    ' r2 M1 {& E( [5 l: O

  34. ( l( }/ I/ b" M- d  C# T* R: ?) o4 S
  35.       HAL_Delay(5);
    0 j, y0 q  _  i5 t- l, j5 A0 u
  36. . d* F4 d& e6 a

  37. 7 ?9 p/ P! S7 b3 ~" g4 A0 Q9 |

  38. % [/ I: K$ w0 S- q  I. J5 @* L6 F
  39. Dac_data = DAC1->DOR1;//for debug
    5 l' F) G# q. v* f1 ?* \
  40. " U7 h3 {2 |* r+ z

  41. # Q! ^; K! E0 {" {$ a% [- a$ [8 _4 S" I
  42. * W  n7 W# X$ {6 h1 U/ o$ ]/ s0 A
  43. }
    % ]( ~& K& k4 _1 J

  44. $ h2 [. u' K" U# T6 @
  45. }
    . c: @# d* s) ^7 \1 {: @
  46. </span></span>
复制代码
: u* ]$ d% a" m: a- p, m
总之,不论使用哪种方式,都可以实现我们所期望的结果,即输出如下正弦波。7 ^- n- S4 C2 X' j

9 \' H# j- }4 }, y
692bd68b1c31d5aa2a4b73541244f56e.png

: i& w+ R# C1 I) G. O' [8 i; y7 {) {4 ~! i! \% ^
好,关于STM32G4的DAC应用就简单介绍到这里,STM32G4系列的模拟外设丰富而强大,此处算是抛砖引玉。这里做些分享也是为了让其他有需要的人少走弯路,加速开发进程。【文中代码都很简短、直观,就没做注释说明了。还有个客观原因就是在微信公众号里排版也很费劲,字符不太好对齐。若有需要交流的可以后台留言。】
' X4 `* c: j# J- v# g
; v& t+ ?! a5 P7 E, p
+ f7 ^( D( I7 B
79bba335bff508c4f57300f0f57049de.png
收藏 评论0 发布时间:2021-12-8 22:00

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版