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

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

[复制链接]
STMCU小助手 发布时间:2021-12-8 22:00
有人使用STM32G431芯片做DAC应用,具体来说就是通过DMA将数据从指定内存传送给DAC数据寄存器,并由定时器触发DAC转换。他发现总是没法实现该功能。这里简单介绍下相关实现过程,并做些提醒。这里要演示的基本功能就是让DAM将内存数据周期性传输给DAC数据寄存器,最后输出一路正弦波。
) I' U% a& E: l4 o& b; D% b/ k4 G3 x( w. k
8c8aec0947a9e081baa317138ac945de.png

6 `: s3 {6 U' z& F0 r* b& r
' E0 p6 N5 g7 ?, g, M6 [5 x8 `7 t  A' l5 m) l
结合STM32G4芯片的特性,这里可以有两种实现方式。5 Z! p) t5 K, ~7 F1 N6 z" E
/ c3 ~- @7 c2 h6 v' O1 u' h& l" L5 k
第一种,DMA的请求来自于DAC1的转换事件。第二种,DMA的请求来自于定时器事件,下面用到的是定时器的更新事件。这里就两种实现方式的配置及相关用户代码简单介绍下,以供参考。
# Z. f& Y9 g; O% {; i
. C. R) E) I! x, e3 z4 B8 X我们先看第一种方式,即DMA请求来自DAC转换事件,定时器3触发DAC的转换。
) A' M7 u1 X4 h" S3 D
% V+ y( R: P# `" b7 `  t使用CubeMx进行配置,主要配置如下:
' e1 U& x: E+ }5 C6 K0 N0 \
d1020b7d0f8f4894eb7b709ab4cbed6d.png
2 {; x! u* H2 P3 [* U
( X; ]( U9 M4 L
. @) S8 K6 G# `" j4 Y/ H
ddd67d8a4616146cdf0ec6419da513ec.png
7 ?- t8 u- F) w: t# G* G6 X1 k: i

5 N) c, ^" K0 A7 k$ y; r" f7 k
0f1f5180cdc185196607e3ef27b9e215.png

- }0 f7 I1 n5 Z2 D% \
% O0 H; B" d& c* M完成配置后生成初始代码,再添加下面代码即可验证测试:: {0 F( f$ j" ~
, ?$ p6 ~6 s/ a  t# \" u5 g+ S
  1. #define   Tpai     (2*3.14159)
    4 ~# l8 ~* c$ K- Q: I: Z7 L8 l  M( \
  2. & p  j! P$ \% L1 P5 X3 K) x! s
  3. uint32_t  PData[200],Dac_data;
    * M$ ~/ [$ o+ O' w3 y, a- ^" _

  4. " }4 i- S* A- _& s
  5. uint16_t     i;
    ! }" j& v- K$ A6 K& ^) p9 W
  6. 7 ]/ A" ]5 Q! E
  7. for (i=0;i<200;i++)3 X, s, |5 m! [& X

  8. 1 H9 k7 a/ c9 x9 H2 B4 E, d
  9. {undefined
    6 h+ E4 f4 {* |/ B
  10. 9 ~+ s5 x- j1 h* |3 O
  11. PData<i>=</i>  A: M; Z7 s  o+ W8 p9 A8 ]* z

  12. $ O& d- C* X% Y, C
  13. (uint32_t ) (2000*(sin((Tpai/200)*i))+2000);
    ) r$ }' C1 v' {% }* c5 Q
  14. " d8 b& i& ]8 _1 X  w
  15. } //prepare data for DAC
    - }. i% ~; |8 v! w* p& B

  16. 0 _! O- O! @6 h( Y# |
  17. HAL_DAC_Start_DMA(&hdac1,DAC_CHANNEL_1,(uint32_t*)&PData[0],  200,DAC_ALIGN_12B_R);1 {& t- ^% y. c3 O+ Q4 x
  18. 9 O3 b) W! Y% n
  19. __HAL_TIM_ENABLE(&htim3);
复制代码

) V7 j' p- c/ ]2 Z6 [5 L5 I- e) R- @8 I

: q( H$ ]; j. H. @上面配置的DMA传输方向是从内存到外设,目的和源的访问宽度都是32位WORD. 当然也可以是内存访问宽度为16位的半字,外设访问宽度为32位字。即DMA的配置像下面这样也是可以的。
+ o% n8 S2 n5 C& y- N; g" n, @" B% V( Y5 n: J8 O) d8 a" \; x, Q
d1a3b9537ab66535982e8b0cb86d3bbc.png
" V9 |5 G  t  A/ a8 K9 h

& n2 y% y" F6 R, B( v  r8 O7 c1 P其它配置不动,代码稍微改动和整理下即可。参见下面代码:
" e9 Z: W, u& m
: |6 e6 p8 C; L  Q8 z% Z
  1. Uint16_t  PData[200],Dac_data;2 W3 @8 E& f7 ~2 [4 `

  2. - h) R- |; u/ [% J1 Z* J
  3. #define   Tpai (2*3.14159)
    3 J* V* c9 d! v
  4. ( @! q) t8 o" m0 g6 t
  5. uint16_t     i;
    $ `; W+ b7 |6 L( h3 M5 `* g/ |

  6. 1 M- a: s* B# L' _- k
  7. for (i=0;i<200;i++): p6 w- v: t4 |: |$ I5 I) ?' D; d

  8. / ~+ \8 ~3 }! M* |! Q6 t& k
  9. {undefined
    1 X3 \9 g0 e1 ]7 D1 O
  10. / J+ a5 D- H, r/ J$ }6 Y. S" k
  11. PData=  w& W6 O3 a7 h6 g

  12. & d* G5 V& e2 x$ q+ ~  Z
  13. (uint16_t )(2000*(sin((Tpai/200)*i))+2000);
    & _4 A1 a% L; p3 i
  14. 6 A9 m9 M" i+ c- v* j% H" [5 {
  15. } //prepare data for DAC
    / ~! S$ _5 d/ w3 A, l. l

  16.   M4 K' r) h2 u
  17. SET_BIT(hdac1.Instance->CR,DAC_CR_DMAEN1);: B& N. `0 C% V! `5 z) A0 w2 y

  18.   g) ^, h& Y/ f2 V" y

  19. 4 Q- Q" {8 d; f+ \7 I4 M
  20. : t: x3 ^9 p. q# ?6 V
  21. HAL_DAC_Start(&hdac1,DAC_CHANNEL_1 );
    + ?* I- ^. i( A

  22.   e$ |/ ^) g. r* r! O% K  ?. U, j
  23. HAL_Delay(2);
    - p1 O+ l9 J$ Y: I; y" C1 ^0 L' D' O
  24. 1 p. {( I9 [$ E. h1 M8 A5 p! Z

  25. # ^  u( G' _0 |! D8 t+ B$ z
  26. % v8 d8 M, L6 ~* }% X! }
  27. HAL_DMA_Start_IT(&hdma_dac1_ch1,(uint32_t)&PData[0],(uint32_t)&DAC1->DHR12R1, 200);% \6 G- `  @+ V' I* Q! [0 q

  28. / i* O, ^# B4 F& B4 W
  29. 0 L: @; F4 ?/ E. ?$ o

  30. 5 G4 c# o9 N8 p4 A
  31. __HAL_TIM_ENABLE(&htim3);
复制代码
, u: c- Q: P+ B0 h$ h# R8 T
8 G  ]! Y9 R; K/ v( L/ C  c' q
8 _; W, ?; b  W5 ~, e6 T, ^
1 N7 A0 g4 p& o7 @& S! E* {
第一种方式就介绍到这里,再来看看第二种实现方式,即TIMER更新事件作为DMA请求源,同时作为DAC转换触发源。9 d9 y' K1 n5 W# C* L
( @4 l; ]; C0 a* L* X# P, K
基于CubeMx配置,主要调整下DMA配置,其它配置基本不动。
0 u) W2 z* Y, I# F8 C! e
. l$ V4 G' s3 Y2 f% j

0 p5 w- a6 q, H5 p) ?9 K- }, U7 i5 L; g8 m" m
; G- h9 @6 {# m* Z2 A
主要是DMA请求事件变了,其它配置跟第一种模式基本一样。2 K0 l: a) p! a8 o  n# s0 p( K

  [2 g$ H, m  w配置完成后生成初始化代码,再添加下面用户代码:
* n% @% q& w  n# _$ H9 C3 |" c3 G  N7 S! G8 _0 w
  1. #define   Tpai     (2*3.14159)1 X7 [, j) A# Z. w# q& N

  2. ' B1 i+ T8 {! Q4 Y3 E
  3. uint16_t PData[200], Dac_data;6 P. G( P- V+ Y2 N( |5 ^/ x

  4. , w3 C. N1 c  `0 f( s$ \7 c
  5. uint16_t     i;
    ! C2 ?& T$ Z; D2 e; z0 e( r7 D
  6. 8 M' ?/ F0 }! m1 y
  7. for (i=0;i<200;i++)8 f% `3 U0 D6 q, B4 p
  8. $ K9 }8 M: g+ q* Q
  9. {undefined
    7 {) ?: O2 }- n, B8 \' u8 b
  10. ! R) B* l8 P/ j  Z8 p
  11. PData=
    $ R( N! s( @. n6 L- j2 R
  12. : u. s$ W* U% @! w5 l& H2 k) b
  13. (uint16_t )(2000*(sin((Tpai/200)*i))+2000);
    ' V0 L* m* y+ B& p* x1 n# @

  14. 8 X" z& c& M4 g6 n$ X
  15. }1 A) F5 |% _! ]2 T2 p4 p9 K) M
  16. " @3 m. ~% ?; Z! w  q& L6 I
  17. HAL_DAC_Start(&hdac1,DAC_CHANNEL_1 );% b0 |) e4 Y! ^: \) A0 k; I
  18. + w9 N) K; I( X' L, P
  19. HAL_Delay(3);
    2 U( T. h) L* q- S+ G
  20. % a) ?# A6 N; T% {4 t

  21. . F( J5 Y7 M9 J4 A
  22.   Y( f# W6 P( N- a' E/ B
  23. HAL_DMA_Start(&hdma_tim3_up,(uint32_t)&PData[0],(uint32_t)&DAC1->DHR12R1, 200);, a" ?/ u6 n. _

  24. , w& u" W% k8 J- {" ]

  25. ' H/ l6 t1 b& [9 s, f% d5 t

  26. - W9 d8 s* w# ~( d# }- u8 r, ?
  27. __HAL_TIM_ENABLE_DMA(&htim3, TIM_DMA_UPDATE);: T; w: ~3 p6 c, B* v9 G
  28. 7 F  o3 ]: _8 m8 g1 c4 \  L) U
  29. __HAL_TIM_ENABLE(&htim3);
复制代码
$ I* X" d  G  r
6 g- S1 g2 f' L; O, ^
这里要提醒一点,G4系列的DAC1的数据保持寄存器可以一次放2个通道的数据,在使用DMA传输时,即使只用到1个通道,DMA对它的访问也要遵循WORD对齐,不然你可能会遇到麻烦。
' z2 s) K3 D' {8 I: d+ W0 Q7 c% X9 `! @
如果说,我们不使用DMA做数据传输,只是手动给DAC喂数据,那如何实现上述效果呢?这时我们可以使用软件触发DAC的传输,手动给DAC的数据保持寄存器赋值,参考配置及实现代码如下:
! w6 W- {* F; S8 ^3 z
/ O+ I6 b# S+ [2 o' f
81958bbf0c7325cd86a0ecbf4dc138ef.png

7 Q: V9 n2 z8 `+ a* r% `& y* u% b& u# E- e
/ u1 r3 \, H' L0 S/ h* R# j; V& n
相关用户代码如下:   c* b! @3 ^& o* b1 r' O% O

: E4 m1 y8 j, m% E' Z
  1. #define   Tpai (2*3.14159)
    # V' W( u; O$ I7 d& K# D( X% n# Z

  2. * h$ ]  @# \: V  h' z; x
  3. uint16_t PData[200],Dac_data;
    ! c- h7 r. j( U0 E9 r
  4.   L9 V4 i# j3 l
  5. uint16_t     i;
    0 h- S8 ~3 t( _8 o: M6 L
  6. ( ~0 I/ M' t- W
  7. for (i=0;i<200;i++)- w7 |  x" K& a* m

  8. $ T- W2 [' K2 h
  9. {undefined: g. j; H+ N5 b, x9 @
  10. 5 a& w3 \' P2 M; j$ W
  11. PData<span style="font-style: italic;"><span style="font-style: normal;">=& R+ J' l3 z: ]; D

  12. / z; m' m5 U: [# _) s9 {  ?& t
  13. (uint16_t)(2000*(sin((Tpai/200)*i))+2000);
    . W$ Q& y" [- F; B4 t
  14. # }  I& u: B: w) |7 e$ ~7 }9 A, w7 Q
  15. }0 f9 i5 H: a$ p) y( f) G& e/ b, v

  16. # U. H7 V" n8 Z4 W% i; K! x; i
  17. HAL_DAC_Start(&hdac1,DAC_CHANNEL_1 );7 K# ~. I/ i5 Y. v3 }
  18. ! w3 M# @: {  l% L/ g9 h* N0 \
  19.    HAL_Delay(3);1 |# Q/ r8 }. P, b  \; l$ Z7 H

  20. 4 O& \  V' ]( ~

  21. 9 q" Y( [: C' i

  22. 3 |% w' N+ _9 y2 m% b6 g  M
  23. while(1)
    ; w; \  e* }" ?* w8 {

  24. 6 A; F' L' e9 y" y
  25. {undefined
    # N3 r  G: ]9 t# h1 i! T
  26. 0 P, W# ^9 ^; ?5 v
  27. for(i=0;i<200;i++)/ `3 v) g% r- a" X

  28. 6 s% o6 @8 p0 `
  29. {undefined! q, z8 |' X6 m6 f; j/ _) z' u

  30. 4 d' c0 h/ v- n  N* ]8 w! k+ B
  31. DAC1->DHR12R1= PData</span><span style="font-style: normal;">;
    - ]6 |; [% V( e$ ^* A7 K
  32. 6 r+ W5 r. ^: t; I7 p+ M+ y
  33. SET_BIT(hdac1.Instance->SWTRIGR,DAC_SWTRIGR_SWTRIG1);
    8 ~$ l1 @, V3 m/ `5 I
  34.   D) G# |- }: Y7 s6 p- h
  35.       HAL_Delay(5);/ \  h: Y0 p5 j- R) U, F& l

  36. ! ]8 |3 G% n. ?8 L! Q/ _  S

  37. ' \- V5 ^" r% `* c+ e+ [5 M

  38. & M+ N( t2 F, |6 h) N7 p
  39. Dac_data = DAC1->DOR1;//for debug
    7 m, |1 Z4 q! |0 y' z. e5 t+ w

  40. + d) y7 I- G  o) W2 ?6 P
  41. & E; \" s( A, L
  42. # P" P( h! Y. b0 w+ F' S* T
  43. } 1 X8 _" L3 x: Q

  44. 3 s$ G, P3 g. M7 N0 K& ?$ T
  45. }( f$ g, Q9 o, d& R/ p
  46. </span></span>
复制代码
$ i3 G( k8 _8 G8 v, @) N' c
总之,不论使用哪种方式,都可以实现我们所期望的结果,即输出如下正弦波。0 @5 ^+ ]) A! g

" M+ ?& `6 M& W% M6 Q- y
692bd68b1c31d5aa2a4b73541244f56e.png

4 n0 T6 H* w, h. o! S" V4 S' r$ h" R* a
好,关于STM32G4的DAC应用就简单介绍到这里,STM32G4系列的模拟外设丰富而强大,此处算是抛砖引玉。这里做些分享也是为了让其他有需要的人少走弯路,加速开发进程。【文中代码都很简短、直观,就没做注释说明了。还有个客观原因就是在微信公众号里排版也很费劲,字符不太好对齐。若有需要交流的可以后台留言。】0 N) G$ ], [* E

! [1 m8 @3 s+ n' @& r- j# _4 O5 a' n
2 ~1 X% g) J5 L( S/ F2 V
79bba335bff508c4f57300f0f57049de.png
收藏 评论0 发布时间:2021-12-8 22:00

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版