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

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

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

3 t5 ^. }8 ^! C- O& {, f
8c8aec0947a9e081baa317138ac945de.png

4 r* {( L; [- ^0 I$ ^7 a) ?; b9 L+ |# ~8 K# P, g4 P7 F# l

  ~& {( K# {  g结合STM32G4芯片的特性,这里可以有两种实现方式。& K4 w/ b+ ^' g3 J# X/ G) p, Z! D- ~6 `- y

  [& t& |+ b; B第一种,DMA的请求来自于DAC1的转换事件。第二种,DMA的请求来自于定时器事件,下面用到的是定时器的更新事件。这里就两种实现方式的配置及相关用户代码简单介绍下,以供参考。
& ^4 M6 x+ i1 Q# o- E, |5 V" P: V- _1 n
我们先看第一种方式,即DMA请求来自DAC转换事件,定时器3触发DAC的转换。% ]6 S& S2 J) j
: q/ [: {. ?6 B$ P9 B; Y) F, D
使用CubeMx进行配置,主要配置如下:
3 j, ?- z* c( q
d1020b7d0f8f4894eb7b709ab4cbed6d.png

9 C- T4 b5 S: p  ~2 c- a$ {0 R" o4 Z2 A6 v$ X# d* j
* H7 ?2 J& G; y6 X/ }% H+ z5 U
ddd67d8a4616146cdf0ec6419da513ec.png
8 L5 ]3 x, {! e
1 |4 a+ N: O# _) ?9 x2 O) L( j$ k
0f1f5180cdc185196607e3ef27b9e215.png

# C$ B* E$ {; n  e- s% n$ X4 q0 q" t# |% M+ M% v* t4 {+ O
完成配置后生成初始代码,再添加下面代码即可验证测试:4 \7 E4 A: N, s3 X5 P
1 D  @8 W5 P: D1 i$ }7 R' m
  1. #define   Tpai     (2*3.14159)
    5 Z1 L9 O- E# t* T1 ~
  2. + p) t6 K* g/ C
  3. uint32_t  PData[200],Dac_data;
    ) ]( [; \4 O/ M% p7 m4 `0 W
  4. 9 q# j$ `3 ^' l! o
  5. uint16_t     i;  Q; X9 [, \/ w9 e% E0 H

  6. ( X) U( G! x1 |, v/ F2 J
  7. for (i=0;i<200;i++)
    " J3 ?5 w% S' W* p% N: P

  8. # |# }9 B7 B! L3 e# r( V
  9. {undefined+ S- N* T( ~/ c% B8 g) M
  10. 0 k" \, ]% W  c5 j3 [
  11. PData<i>=</i>
    ' t! R, s- ~2 k
  12. & |% v; w2 H+ n, r) V
  13. (uint32_t ) (2000*(sin((Tpai/200)*i))+2000);
    - e  \2 Q  Q- L! l
  14. " i6 `( V- x" \! H9 L. E
  15. } //prepare data for DAC
    6 B9 \# Q/ n, h7 |
  16. % C; L4 D) t* c
  17. HAL_DAC_Start_DMA(&hdac1,DAC_CHANNEL_1,(uint32_t*)&PData[0],  200,DAC_ALIGN_12B_R);6 M; G1 g, Q2 [3 v1 r

  18. & ]! B7 ]5 k2 ~2 ?
  19. __HAL_TIM_ENABLE(&htim3);
复制代码
) g8 T: }4 @  O3 H+ n
2 K; ~+ D) p" X, M+ N2 j2 f; r
: V2 C5 A5 m. r9 Z9 m$ S
上面配置的DMA传输方向是从内存到外设,目的和源的访问宽度都是32位WORD. 当然也可以是内存访问宽度为16位的半字,外设访问宽度为32位字。即DMA的配置像下面这样也是可以的。# c5 ^. P5 `  h# Y8 Z1 t

2 q+ C* L6 I) g' M
d1a3b9537ab66535982e8b0cb86d3bbc.png
/ s( ~" }! ]; P
; \0 g( a3 U4 p
其它配置不动,代码稍微改动和整理下即可。参见下面代码:0 A' }5 H8 r- {! W2 M8 c, J
; k, D& U# M$ ~8 k% D) }
  1. Uint16_t  PData[200],Dac_data;
    ) i; p$ e6 G! T  A" }8 A

  2. $ ~6 D1 i; i) H
  3. #define   Tpai (2*3.14159)" i, H; B2 {+ h; m3 N
  4. ) ?, g) x- X7 s0 o' h' G
  5. uint16_t     i;% y) U, g' z9 i8 F% k+ @9 y

  6. . Y' v, v/ x3 U6 _
  7. for (i=0;i<200;i++)
    ; `: W( m9 d1 A3 j0 W
  8. 2 T6 |" K& p* |+ w  _
  9. {undefined% p0 P" [- K/ F1 v3 A# [* V

  10. 4 S) e* P3 z+ I& K
  11. PData=
    0 e  t! L* f/ _- n0 t
  12. 0 A8 G- W6 W1 M0 v
  13. (uint16_t )(2000*(sin((Tpai/200)*i))+2000);
    ' G) w# `* |  b" d2 W' \
  14. * P- m& T" v. o2 c; x+ M' N
  15. } //prepare data for DAC" n1 ?( o( V0 V4 Z3 |% E5 `

  16. % V' X. \0 d/ b1 @5 D# s
  17. SET_BIT(hdac1.Instance->CR,DAC_CR_DMAEN1);
    ( S( q% h8 S5 J. l$ J! g

  18. . _5 r3 U2 ^9 [; L2 w

  19. " K3 J% y* Z4 i7 V8 d6 p
  20. # ~3 S+ |/ H' E" `3 x
  21. HAL_DAC_Start(&hdac1,DAC_CHANNEL_1 );8 L0 K9 G! H& J; M7 V

  22. ( Y  B5 T% \# m8 c
  23. HAL_Delay(2);
    1 Q: }! G+ b) b' w' ]
  24. / D* T4 y8 l4 h! b
  25. ! l  E3 a" l* H! [
  26. 7 R( o6 W0 {/ V7 Q! S6 ~6 w
  27. HAL_DMA_Start_IT(&hdma_dac1_ch1,(uint32_t)&PData[0],(uint32_t)&DAC1->DHR12R1, 200);
    3 O, }' p+ k* E0 ~. q; f

  28. ( P. i/ T, v# P2 i9 f
  29. 8 E- z2 a, k# |/ L/ `/ ^
  30. # F' v0 q$ R1 g. D3 z) D3 a8 o
  31. __HAL_TIM_ENABLE(&htim3);
复制代码
9 m; r' M8 C: S6 Q4 M4 u) U. h
8 B: ]% m+ }7 O+ y) m" Q, X

/ u' }6 `8 w* v, |: l0 i' P( L$ }8 [8 N
第一种方式就介绍到这里,再来看看第二种实现方式,即TIMER更新事件作为DMA请求源,同时作为DAC转换触发源。; ]' s8 w  I* M

% x" o) g& J1 d% b) Z7 g. ~基于CubeMx配置,主要调整下DMA配置,其它配置基本不动。
- p* z2 Z5 Y5 b1 A: |* r$ v  G( s/ \+ v9 A3 V! [$ B. Q# V
3 n6 ~- W7 L/ g% Y2 I+ Y

$ Z$ j* q& b% ?+ K* G
& R0 k1 @, m  E) v2 ~主要是DMA请求事件变了,其它配置跟第一种模式基本一样。
* \0 A$ S) B1 S, F& N; e# F( H5 D
, d; H( ~5 j- Q5 r& Q  p; r$ V配置完成后生成初始化代码,再添加下面用户代码:6 r' U  Y3 u/ k7 ?

" U4 b- t( @* A+ R( O
  1. #define   Tpai     (2*3.14159)4 y5 l' D- A% W5 A$ `

  2. / U) F* d3 X& Y  E3 |
  3. uint16_t PData[200], Dac_data;6 \5 A3 e) U1 i, E& _+ \3 t! ~) o1 ]- Y
  4. ! B/ b# q# t! E0 W$ o) w/ @
  5. uint16_t     i;
    * y) ^# v) \+ [7 V1 b
  6. 3 g9 R8 n+ \  Z0 y
  7. for (i=0;i<200;i++)
    + i! q1 x* Z0 i6 R1 u9 a6 u% c. U

  8. # @- t. Z$ m: I& E: Y% ~' ]
  9. {undefined* a: i$ w+ E* H& o0 n
  10. 6 G3 o' k' v% ^1 \, _
  11. PData=
    , b4 ~, i+ I$ n
  12.   `( h. h) H* Z1 |/ ?+ ~; v! X
  13. (uint16_t )(2000*(sin((Tpai/200)*i))+2000);2 D% n+ e- m% F9 x9 }

  14. $ I: A8 z& k3 V: }1 J1 G8 R
  15. }1 R/ P' n) M! F% d! y
  16. 1 k# g3 t. u1 `. e+ q  `  v
  17. HAL_DAC_Start(&hdac1,DAC_CHANNEL_1 );/ q7 n9 E+ W* Q$ Z
  18. 4 I7 `* x# l/ \: z% P5 B
  19. HAL_Delay(3);
    5 z% c: R# R: j3 l3 \+ K: B2 K

  20. $ d4 B. J* i& j7 [

  21. 8 }/ w: O) E) R7 n: ^& V7 H( X$ J
  22. 5 r) V) p9 h- a* B5 P
  23. HAL_DMA_Start(&hdma_tim3_up,(uint32_t)&PData[0],(uint32_t)&DAC1->DHR12R1, 200);+ g% y  X( ]. s: j$ p
  24. , H# t& u: H% d1 N# C2 p

  25. 7 B0 V& v; N2 B& o5 u. c& L6 j. n3 l
  26. 9 b+ @* j; J: Z, e/ Z& \9 u
  27. __HAL_TIM_ENABLE_DMA(&htim3, TIM_DMA_UPDATE);( b$ g% O7 `) M3 v# s& z( o, s
  28. - o' v) V2 B+ [" P
  29. __HAL_TIM_ENABLE(&htim3);
复制代码

9 L% y* |) l; H! i
) D" y  w: j" q这里要提醒一点,G4系列的DAC1的数据保持寄存器可以一次放2个通道的数据,在使用DMA传输时,即使只用到1个通道,DMA对它的访问也要遵循WORD对齐,不然你可能会遇到麻烦。
* z% o) c2 d6 c& G; ^, O) e$ |0 Y2 P
% Y9 T  ~& x2 P3 G, P如果说,我们不使用DMA做数据传输,只是手动给DAC喂数据,那如何实现上述效果呢?这时我们可以使用软件触发DAC的传输,手动给DAC的数据保持寄存器赋值,参考配置及实现代码如下:7 s2 h, C+ |& z' i* e9 M7 J+ |
# V& B5 z! _9 ]" n9 U5 v8 U
81958bbf0c7325cd86a0ecbf4dc138ef.png
' ~6 Y) Q& v  A5 Z- p# e" U
3 k) H/ \! W4 w

: {" f& n# w; ]; K. ]相关用户代码如下:
: b( d# H- {6 p1 F/ B# C3 x4 M
0 O/ ~4 P, }: h; [/ m$ O
  1. #define   Tpai (2*3.14159)  m* @: S2 U5 ~& `- f' Q( {; M

  2. 1 p# e7 R2 F* ~
  3. uint16_t PData[200],Dac_data;; \6 g* o0 L3 M) ]' |, c

  4. ' z$ k( W( ~4 M4 a
  5. uint16_t     i;
    / h) D1 |, N$ P% o
  6. 7 p4 a1 x* u. @* Q8 B
  7. for (i=0;i<200;i++)
    " {! I/ P% b, |% p( g
  8. 3 A% j/ o6 a6 @* x% z) s& ~
  9. {undefined) [7 {* a4 @- |+ D5 _7 j

  10. * I+ A- ]: W0 \5 K5 q
  11. PData<span style="font-style: italic;"><span style="font-style: normal;">=- e' H+ I0 a. o! t/ F' K. k

  12. 9 W4 U! t6 A) o4 x* W
  13. (uint16_t)(2000*(sin((Tpai/200)*i))+2000);
    - t# w8 v9 f) \3 @: t) ]

  14. + A; J7 u) S& d
  15. }
      ?4 k( Y& p  x4 o# z; |
  16. $ M. p$ d) L6 p
  17. HAL_DAC_Start(&hdac1,DAC_CHANNEL_1 );
    " E  B. ~# h8 R% O6 ~, `5 c) {
  18. + W! |3 V. t3 `- l7 f- `, @( z( }" `
  19.    HAL_Delay(3);
    $ `; A( ~5 ]$ Q9 X; ~# D
  20. ! e5 i) D6 ]0 ]" u1 `
  21. 9 l/ K8 h" x& @+ F; N
  22. ( p2 Z/ Z4 g2 {) V2 A
  23. while(1)
    , b1 ~$ m8 n) x* `3 O, ^  [- Q6 E

  24. 9 `. x6 e% a' r( ^) B$ b- p% v( p( E7 d0 t
  25. {undefined
    3 @2 S8 s0 ^' Y  H( r1 W
  26. 1 U1 I" Y0 u) O* K' g
  27. for(i=0;i<200;i++): |0 \7 a  _4 h3 j9 \. P
  28. 2 u) `0 v) R) ?" F' d) u
  29. {undefined
    9 s( w4 q' k% T5 s9 K

  30. 1 K& ~5 s% }; Q; Q. J
  31. DAC1->DHR12R1= PData</span><span style="font-style: normal;">; ' H, a9 M3 S' d8 G, n2 l9 _: i

  32. 9 R5 J" }4 Z9 i8 p' u* J
  33. SET_BIT(hdac1.Instance->SWTRIGR,DAC_SWTRIGR_SWTRIG1);* P6 B7 n+ u7 `
  34. - D; `: C4 g5 W7 u
  35.       HAL_Delay(5);* y1 z/ R; }' s' V

  36. * t8 h2 R8 K! w  X* C
  37. * }$ m# A6 l% @5 j; r" i

  38. 6 z0 d, f! C6 @; W% }
  39. Dac_data = DAC1->DOR1;//for debug
    ! L! ]6 F6 n0 M

  40. 5 z" N5 l& W' `* N8 Y) b# R
  41. : s, ], @8 ]0 ^2 i/ |
  42. 6 E! S4 J# o. ]% R
  43. } # o  B( H0 r8 S# y- T
  44. - c( z$ a. f( h2 L$ y
  45. }) \+ j/ C; F' d; `
  46. </span></span>
复制代码
+ [# }5 M) @9 [( |( }2 n
总之,不论使用哪种方式,都可以实现我们所期望的结果,即输出如下正弦波。
& i) y, q& t5 ^' G  m( I7 q
9 e) Q& {5 c0 a% B! A* @& Q* p
692bd68b1c31d5aa2a4b73541244f56e.png
3 K4 k) Q8 h  Y+ `' p, u- V

0 I% h7 W: y& v好,关于STM32G4的DAC应用就简单介绍到这里,STM32G4系列的模拟外设丰富而强大,此处算是抛砖引玉。这里做些分享也是为了让其他有需要的人少走弯路,加速开发进程。【文中代码都很简短、直观,就没做注释说明了。还有个客观原因就是在微信公众号里排版也很费劲,字符不太好对齐。若有需要交流的可以后台留言。】! g2 G% l; o. P& V

! `0 ]' W+ P, r$ l+ x( A! ?% j
' O% z+ y, \" E. R3 f- G% }
79bba335bff508c4f57300f0f57049de.png
收藏 评论0 发布时间:2021-12-8 22:00

举报

0个回答

所属标签

相似分享

官网相关资源

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