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

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

[复制链接]
STMCU小助手 发布时间:2021-12-8 22:00
有人使用STM32G431芯片做DAC应用,具体来说就是通过DMA将数据从指定内存传送给DAC数据寄存器,并由定时器触发DAC转换。他发现总是没法实现该功能。这里简单介绍下相关实现过程,并做些提醒。这里要演示的基本功能就是让DAM将内存数据周期性传输给DAC数据寄存器,最后输出一路正弦波。
! Y" X3 W  \9 k, j0 J- ?; z1 o
9 H6 s. d" P, k2 W7 q' s
8c8aec0947a9e081baa317138ac945de.png

3 J/ F% _9 u, W. ^; N/ o- |' n5 m" [' b% V: i% V+ r/ o

" V. @# M2 h6 @% U6 A5 G结合STM32G4芯片的特性,这里可以有两种实现方式。
3 V/ F/ ]0 e% j/ x: Y( k$ h2 K
8 u" a0 [4 U* ]/ E# M第一种,DMA的请求来自于DAC1的转换事件。第二种,DMA的请求来自于定时器事件,下面用到的是定时器的更新事件。这里就两种实现方式的配置及相关用户代码简单介绍下,以供参考。
2 P; d6 y* `, Z/ S. q7 T1 X
$ k$ [* f6 M8 `( z我们先看第一种方式,即DMA请求来自DAC转换事件,定时器3触发DAC的转换。
" Q0 ^1 W7 \. D: ^* H. V! K( Y( Z% k  H: F" O) U- Y
使用CubeMx进行配置,主要配置如下:3 f3 \# E9 F4 ~" f5 x0 u) Q9 [
d1020b7d0f8f4894eb7b709ab4cbed6d.png
7 k* i0 h/ I3 C8 a. e

- l9 G- N5 F/ y' _- H" U
8 J& t2 H( B- S# w2 m1 V4 I1 M
ddd67d8a4616146cdf0ec6419da513ec.png
. Z4 J* t1 Y  y+ x8 f% x- C

4 k2 ]1 f5 K* V6 R
0f1f5180cdc185196607e3ef27b9e215.png

: M1 F. Y8 E9 S. B' W
4 D  T# s# X  `5 s, J完成配置后生成初始代码,再添加下面代码即可验证测试:% m! g# a1 S, n7 M

2 d# r( u8 S& ~. t/ a2 G
  1. #define   Tpai     (2*3.14159)1 v8 M% N* _% {

  2. * h# K* \6 n8 {3 x/ m7 T6 z, q
  3. uint32_t  PData[200],Dac_data;4 c: z- L8 f3 |& I, V! I& d

  4. # p( g7 k  G0 g9 k; K
  5. uint16_t     i;- j" D: k( Z/ ]4 X3 u3 w
  6. 9 S+ N. e  M; s$ P
  7. for (i=0;i<200;i++)
    + }% ]4 h3 Z$ O9 m# b- e. u! c: J4 J
  8. ' }1 E# e& H4 @, V! g' s
  9. {undefined5 B( O& n9 z: X: a6 w( P8 ^8 u
  10. : R) ^, ^' G6 p
  11. PData<i>=</i>2 U/ e7 k& k. O3 o& O! c, W; ^# n

  12. ; W3 T: h* I4 v5 t2 w  j
  13. (uint32_t ) (2000*(sin((Tpai/200)*i))+2000);: [4 d' I- c5 ^9 ?/ Q+ n4 Q

  14.   i0 u% e$ ^# q5 O( ^# s- D, n
  15. } //prepare data for DAC* S9 }" P% e3 O
  16. 7 B0 [4 O% ~; ]: {3 n5 r
  17. HAL_DAC_Start_DMA(&hdac1,DAC_CHANNEL_1,(uint32_t*)&PData[0],  200,DAC_ALIGN_12B_R);
    8 m% ~0 U$ r% H  Z, w2 J
  18. + D4 _) d/ w& g5 o
  19. __HAL_TIM_ENABLE(&htim3);
复制代码
# y  o1 M9 p; m
! ], o+ g& v' f8 C

8 w  g, b6 @7 U) y6 M2 [上面配置的DMA传输方向是从内存到外设,目的和源的访问宽度都是32位WORD. 当然也可以是内存访问宽度为16位的半字,外设访问宽度为32位字。即DMA的配置像下面这样也是可以的。& C5 o% }4 t- s8 b; d# q
! h% G5 a# ]: x' W* J; |' I' a/ U. _
d1a3b9537ab66535982e8b0cb86d3bbc.png

! f( X4 w0 i7 e2 f' I, N5 ]7 S$ t* U8 _0 e5 u) m8 v- j; U
其它配置不动,代码稍微改动和整理下即可。参见下面代码:& r' `# p  G6 q6 P  q/ X: D

" U- w3 `! l, J7 s# O  W" |7 U$ ?
  1. Uint16_t  PData[200],Dac_data;6 ?# s! e- D7 l) _' u

  2. 0 n( a4 t$ q+ X8 u+ r- A8 W* z
  3. #define   Tpai (2*3.14159)
    : c4 s7 a/ x) z- T1 ~

  4. & F, v4 ?2 V7 Z: f
  5. uint16_t     i;
    6 e8 U) f" f, [
  6. # h. T0 m# x" W8 T5 |" {7 H9 n
  7. for (i=0;i<200;i++)
    1 f: d8 J; O+ w
  8. : L9 N! [0 a  @% D1 L9 [2 z
  9. {undefined
    " |* T: N- i8 q& U' D2 ^4 z

  10. 1 v# A8 s% T* T5 @6 M
  11. PData=. x) R8 ?7 G" t3 S: @
  12. 4 `) r  i6 f/ S7 |  O& N
  13. (uint16_t )(2000*(sin((Tpai/200)*i))+2000);
    / C) X2 @& g/ C2 ~) u, a
  14. % b# e. x8 \: U9 V8 N5 h, S1 c- F
  15. } //prepare data for DAC
    6 N  }; t( I( [+ o- a& o

  16. : @& A" C" T) z2 i
  17. SET_BIT(hdac1.Instance->CR,DAC_CR_DMAEN1);" i2 O0 r' a: v* d
  18. 2 P) X6 K+ R# K

  19. 2 z, `4 o1 v+ v  q4 ~

  20. ! Q) H( o+ \' Z/ e' i5 {7 N9 h
  21. HAL_DAC_Start(&hdac1,DAC_CHANNEL_1 );
    ; z$ b( H  W% o; O

  22. $ m) r; ?/ q9 M; a5 u
  23. HAL_Delay(2);% i3 Q: ?: c! \; i: k# n1 _" I0 k

  24. - g, X' l& t* q0 J5 m' F" K3 f  s6 Q

  25. 5 v) ~. Q4 y. p# P/ t% e5 J: x

  26. 6 v4 B/ i; y1 i2 t% H* m
  27. HAL_DMA_Start_IT(&hdma_dac1_ch1,(uint32_t)&PData[0],(uint32_t)&DAC1->DHR12R1, 200);! K2 _, P' F! J2 @! @9 l! K

  28. : }3 M; v% L& m' f5 B) ~& U

  29. 3 [$ b% {5 T, R! J' p% a
  30. . A: r6 c2 ~) D) o1 k3 D  Z
  31. __HAL_TIM_ENABLE(&htim3);
复制代码

: n, s' \0 x- r$ A& y7 |2 x/ j% n7 Q# t- ]5 N9 c
& ^; D+ d+ e( i" t' r
% s1 M8 m& p* g& O! w) h
第一种方式就介绍到这里,再来看看第二种实现方式,即TIMER更新事件作为DMA请求源,同时作为DAC转换触发源。3 H% \# y0 M0 [' `
7 ?) t' c5 A! d9 b7 [
基于CubeMx配置,主要调整下DMA配置,其它配置基本不动。; X6 A. d2 x) |1 s
: J. c' A, j" c% N

* L- n+ z# a/ R3 }) G! q* ~0 \) h, {" c" G# q: U1 k/ `; ]
- F: Y* [- K7 T$ V" D& I6 g
主要是DMA请求事件变了,其它配置跟第一种模式基本一样。
$ I! L' h' s, f( ]
' m9 a7 p) m# H7 o) Z配置完成后生成初始化代码,再添加下面用户代码:6 t9 w& x3 j0 K$ K

$ ]: c8 Z' C2 _- p. N3 q
  1. #define   Tpai     (2*3.14159)& Z( p1 {4 ~* Q4 q. R7 q

  2. 8 `: v( ]- q6 g( C# ]' T, w
  3. uint16_t PData[200], Dac_data;
    , g+ u& w" M7 c, e, e' V

  4. ) O/ V# K& f8 W1 R
  5. uint16_t     i;" F9 V* w1 Q  [2 M5 n

  6. * L" b" v$ ^6 A5 G2 W
  7. for (i=0;i<200;i++)6 Q& w. V3 B3 y, A

  8. 9 ?$ T6 P! X4 D* d5 t
  9. {undefined
    $ k1 E# y. n/ T# j

  10. 6 o) @/ w- ?) L+ ^7 m, r; U+ w
  11. PData=
    # G. q3 ?0 |) d& x( V' ~

  12. ' I7 _( \  _/ D3 D* ^( Y& s$ g9 L5 [% ^
  13. (uint16_t )(2000*(sin((Tpai/200)*i))+2000);, i1 y  D% G& O, B* ~8 b1 ^

  14. ' `/ Y' T2 b9 U0 V- ~/ h
  15. }
    ; d! A; F: K& C' o4 n) d3 c% q

  16. ' R% b. e" X+ j' I
  17. HAL_DAC_Start(&hdac1,DAC_CHANNEL_1 );, o6 k- ]& a) }1 T, v
  18. 9 I' a7 S) s. Q' m" q
  19. HAL_Delay(3);
    7 d* m' ]3 \6 _: E8 d  g
  20. 7 g$ q' u( T+ l1 F+ \8 X
  21. 3 A1 A' z7 Z6 |$ T5 m" b

  22. # q8 w; T: D  s; i  V1 ?9 `
  23. HAL_DMA_Start(&hdma_tim3_up,(uint32_t)&PData[0],(uint32_t)&DAC1->DHR12R1, 200);
    2 ]  a! r- c5 t! R# }# \; e' G
  24.   ]4 z' T/ ?  L/ C5 `. a

  25. 0 O& z% E, e- k5 q

  26. # ]# h- W  m; a
  27. __HAL_TIM_ENABLE_DMA(&htim3, TIM_DMA_UPDATE);7 C2 h! R, I+ \+ g

  28. ! t3 e$ K, i4 c% [/ \) A3 L. k
  29. __HAL_TIM_ENABLE(&htim3);
复制代码
1 q6 ^* e; s5 Y) `! @* D! W

, b7 e* W8 L5 l8 m: h这里要提醒一点,G4系列的DAC1的数据保持寄存器可以一次放2个通道的数据,在使用DMA传输时,即使只用到1个通道,DMA对它的访问也要遵循WORD对齐,不然你可能会遇到麻烦。
1 n5 b+ n* d; C- `) Q0 ?/ j
, U5 l, z5 x: t& U& P4 V/ g0 N9 w如果说,我们不使用DMA做数据传输,只是手动给DAC喂数据,那如何实现上述效果呢?这时我们可以使用软件触发DAC的传输,手动给DAC的数据保持寄存器赋值,参考配置及实现代码如下:
, m# i: H& \9 Z: d1 O5 ^3 @
7 P1 s0 z. R2 z$ H
81958bbf0c7325cd86a0ecbf4dc138ef.png
4 p: J4 b/ k6 {8 l8 B$ o7 x

3 |) u1 j% Q- |/ f& Q2 q3 }. y) ^! G: T7 Z+ g
相关用户代码如下:
, f( E# k0 E$ M" q$ \! W, {; {* j3 k+ ~$ H& [5 w
  1. #define   Tpai (2*3.14159)3 J5 a1 V# I( T

  2. - k  h& z9 z2 N; R' ]
  3. uint16_t PData[200],Dac_data;1 X+ y6 {) S. {+ }& n
  4. 7 g$ P5 a& `( K2 I6 A
  5. uint16_t     i;
    # V+ G+ a( A' R7 P- i/ [& i3 E5 m$ u

  6. 1 V' P# n5 J" e- u1 o! l; w
  7. for (i=0;i<200;i++)2 }( F5 k' }. I3 E( k3 t1 ]

  8. " e0 u- L8 q5 X" c& O$ f
  9. {undefined
    5 @  E  ]3 T0 I/ j+ l8 L2 u
  10. & n+ F# a2 J  X* y
  11. PData<span style="font-style: italic;"><span style="font-style: normal;">=1 R+ V9 W+ t  E9 o2 u

  12. ( f- D/ b$ p' @# ?
  13. (uint16_t)(2000*(sin((Tpai/200)*i))+2000);
    : V& E. q1 F3 e. i

  14. ) U8 g$ F* t4 X6 ~
  15. }
    1 H& e- Q$ L' W6 X5 }
  16. ; L7 x& ^; G& B7 E7 A1 }1 T/ l7 ]
  17. HAL_DAC_Start(&hdac1,DAC_CHANNEL_1 );& l1 [- N/ S9 v( Y* ~' e

  18. 4 s8 e, d7 n+ Z4 P$ a
  19.    HAL_Delay(3);
    / i7 |  R& a% W& x% [

  20. # Z" W% |& n( U  o* [

  21. ) c" U% Y8 k* J4 A5 x% o* R

  22. - K: K& Q- f# ^  X+ Y  b
  23. while(1)+ F% S+ t# |% q, J5 k1 i) z* a

  24. 4 l3 p, u% A4 u/ _7 T3 e
  25. {undefined: }2 v# t' j! @

  26. 4 C& a' Q1 r% r: Y
  27. for(i=0;i<200;i++)3 f# \. N& {# c5 x* y' v+ M

  28. 3 W9 I; F' k# y0 M/ I  n( L+ U
  29. {undefined, T9 m$ S( C% f

  30. : ^* \: D6 _& U  x9 O+ L0 A
  31. DAC1->DHR12R1= PData</span><span style="font-style: normal;">;
    7 G3 c$ o. F# Z- H; a. q% j  d7 V$ W
  32. ) U' j$ R, V$ l7 R3 u
  33. SET_BIT(hdac1.Instance->SWTRIGR,DAC_SWTRIGR_SWTRIG1);
    7 y3 Q1 V9 @& z) p9 g
  34. : W' n- F: ?. M( P
  35.       HAL_Delay(5);5 O( J9 i4 L% r+ w- n
  36. ' t1 b# D" f8 `- q' h2 y# J  C
  37. 2 E9 }4 D1 i0 ^$ U

  38. . b+ |/ K! f9 h
  39. Dac_data = DAC1->DOR1;//for debug5 g6 o' p; j/ M' |
  40. 9 r4 q& B+ V6 ]5 U% K5 m1 W! S
  41. + I" Q# \7 ]! C; l9 R/ A- N+ n1 Q

  42. " _" v' J- c3 t" t* a
  43. }   g! |8 C! `0 @3 q- V- {

  44. 6 e5 C" C) K/ y0 j1 a6 d
  45. }! b4 s2 u2 J  g, Z
  46. </span></span>
复制代码
' w# j( e+ Y" I5 L& P' n: _
总之,不论使用哪种方式,都可以实现我们所期望的结果,即输出如下正弦波。
7 b+ W1 E6 S1 H  X: b& c  r3 S4 r: p/ \% V. D  F9 K+ t
692bd68b1c31d5aa2a4b73541244f56e.png
6 M" Q2 {! F, [3 a+ v% X6 S

8 _9 v0 i) `. `+ h% o好,关于STM32G4的DAC应用就简单介绍到这里,STM32G4系列的模拟外设丰富而强大,此处算是抛砖引玉。这里做些分享也是为了让其他有需要的人少走弯路,加速开发进程。【文中代码都很简短、直观,就没做注释说明了。还有个客观原因就是在微信公众号里排版也很费劲,字符不太好对齐。若有需要交流的可以后台留言。】* s2 D* Y* p7 g
3 k8 a5 B$ I1 Y

* C, p4 f  t4 n1 @- R- f  A
79bba335bff508c4f57300f0f57049de.png
收藏 评论0 发布时间:2021-12-8 22:00

举报

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