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

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

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

8 K' S- ~! i' C
; f. O. t0 k: b2 E# T1 u. W, R2 N* x& |8 K  {) w
结合STM32G4芯片的特性,这里可以有两种实现方式。
  O6 J. ]) }& \$ B; t" h
( F' l( M5 ]' m" p第一种,DMA的请求来自于DAC1的转换事件。第二种,DMA的请求来自于定时器事件,下面用到的是定时器的更新事件。这里就两种实现方式的配置及相关用户代码简单介绍下,以供参考。
1 R& T# y3 @  O! g. l4 R
' L! L* U! h6 [, w( j* Z% b我们先看第一种方式,即DMA请求来自DAC转换事件,定时器3触发DAC的转换。
$ P  G0 M7 K3 ^" \; X5 D
, m  G% G( m4 M/ V- ~" j使用CubeMx进行配置,主要配置如下:) m! U, p0 J; k9 ^2 r- F1 {2 d& z8 B
d1020b7d0f8f4894eb7b709ab4cbed6d.png

6 Q: d5 W9 d: p2 w8 H$ M! ^8 V5 P# G- p4 F( ?4 H- Y0 N! W

3 B2 K4 S) o3 F8 `: Z
ddd67d8a4616146cdf0ec6419da513ec.png
: S  j1 P: Y& @; l; j  a

" l/ L; L3 f7 }
0f1f5180cdc185196607e3ef27b9e215.png

$ M- V# h2 x5 H* U  w' v; p' q" Z& B# v# z. w3 b1 U' P2 `& S" c
完成配置后生成初始代码,再添加下面代码即可验证测试:$ O. s% _( ?( ?! {: K/ j5 E  w
& \# t% O$ r3 D' w4 T# X; U2 Y
  1. #define   Tpai     (2*3.14159)+ [, X" z, g# }" c" w
  2. 6 m4 n; v1 i4 C+ C, E
  3. uint32_t  PData[200],Dac_data;
    ) t4 c6 S, N) ~  L; r6 D, [
  4. % X# @' W9 T6 T' `+ c
  5. uint16_t     i;
    8 {+ ]2 ?6 c( C  h- u9 y( F1 F: N
  6. 9 y- e' f+ o+ d
  7. for (i=0;i<200;i++)
    0 D/ y6 [, |% Y! O
  8. ( @4 p( Q: z/ E3 o  Q
  9. {undefined
    2 h2 c- }, R1 Q+ o8 P  I' K* m7 U: v

  10. ( C7 c8 p' |  T6 O* c! }
  11. PData<i>=</i>
      D: G* m* x9 r$ e" V% w
  12. 2 X% _8 B- f8 `7 l5 G' g9 @; v
  13. (uint32_t ) (2000*(sin((Tpai/200)*i))+2000);
    9 f" j5 y! h* J$ L
  14. * P! V3 n& [( B2 i1 x
  15. } //prepare data for DAC5 U9 ]: W. Q. u2 a, J

  16. ) x( A4 r2 M- N5 x
  17. HAL_DAC_Start_DMA(&hdac1,DAC_CHANNEL_1,(uint32_t*)&PData[0],  200,DAC_ALIGN_12B_R);
    5 {5 A+ o) Q- L7 @% N
  18. ' H6 J6 Q* r7 ?; i' }1 t6 g
  19. __HAL_TIM_ENABLE(&htim3);
复制代码

3 S0 O  r& [  {& K* _9 Q7 B* c2 R) _7 f2 _

* l( b1 _. h6 x  S1 W上面配置的DMA传输方向是从内存到外设,目的和源的访问宽度都是32位WORD. 当然也可以是内存访问宽度为16位的半字,外设访问宽度为32位字。即DMA的配置像下面这样也是可以的。
0 U$ U( L4 [2 X5 |
! M6 A1 h+ U: o' b
d1a3b9537ab66535982e8b0cb86d3bbc.png
  M4 w: K  K+ ^$ q9 u5 }" j$ l2 f
  X! P7 `6 F# i# y' T: r
其它配置不动,代码稍微改动和整理下即可。参见下面代码:) z0 x9 g4 h* q1 U3 [+ S+ O
. d9 @& {, n0 E1 y) o
  1. Uint16_t  PData[200],Dac_data;& W7 e8 D+ Q6 @
  2. ! B4 ^2 d5 B2 I' o3 l5 T
  3. #define   Tpai (2*3.14159)7 D3 h% G$ g$ A0 V
  4. " B8 K) W) A, c: V& b  a( y
  5. uint16_t     i;
    4 {7 T' a( X) S& @

  6. ( W1 T4 J0 C2 Y* s( n$ Z+ c) z5 h( U
  7. for (i=0;i<200;i++)9 V0 x* H5 r& f6 [# ^0 P  _  \
  8. 5 Y6 Y3 g$ P8 e  }
  9. {undefined
    1 u2 _! w! t6 ]. u  h. Y# B8 Q

  10. 5 ^& H# ^3 L2 \. s
  11. PData=
    4 @: m! y, p. U' ^

  12.   q1 }- H+ d% s9 d% I
  13. (uint16_t )(2000*(sin((Tpai/200)*i))+2000);; ~* h; G( q* f$ [$ o0 v) g$ M) ^
  14. # u8 n$ X1 D% k1 H8 E
  15. } //prepare data for DAC: x: x( F6 c* u# E

  16. : J! `( M7 d2 k, A
  17. SET_BIT(hdac1.Instance->CR,DAC_CR_DMAEN1);
    - p3 N& j' d! O; ?" h' S* S6 E: E/ B0 j1 L
  18. 1 U3 p7 L( U2 U8 _0 M- v0 n; V

  19. 8 g% ^/ \3 O2 L) `' {9 K3 N

  20. ( N# q  D" c7 j* y4 s' q3 s
  21. HAL_DAC_Start(&hdac1,DAC_CHANNEL_1 );4 I5 ]. ?' R; ]! s
  22. ! a+ h8 ]; D* X. ^, w9 `# y
  23. HAL_Delay(2);1 ], c0 X4 Y* t% K
  24. ) W& Z; }. Q: o  R+ @  @& j
  25. ' k1 y3 V5 w! P9 x' M# Q

  26.   o" {% S: J( N/ n% s% y6 \6 a
  27. HAL_DMA_Start_IT(&hdma_dac1_ch1,(uint32_t)&PData[0],(uint32_t)&DAC1->DHR12R1, 200);# G8 c% Z9 u" I% @1 u! ]- ]/ [* U3 j
  28. 8 ~) _# s  u; F: e) P
  29. . D0 V" _- j, [$ Q, V

  30. 3 U, e  ?* O- W7 u, l" X9 u
  31. __HAL_TIM_ENABLE(&htim3);
复制代码

  w- {! k+ k1 a9 M9 M
& k  f  o0 b3 }0 m% |9 u, g% B- I% j* h. e3 ]6 L. L: Y

: F: F9 D' b. N4 f9 y+ K* f第一种方式就介绍到这里,再来看看第二种实现方式,即TIMER更新事件作为DMA请求源,同时作为DAC转换触发源。
, q6 p1 X( L& G9 ]
6 k9 M/ |, K) j& T* y1 `$ O基于CubeMx配置,主要调整下DMA配置,其它配置基本不动。* W$ V$ A6 J+ P- F% S% N  i, [
7 l# m1 P; T6 f6 H2 _" Q7 l+ I
# x! n; t1 {7 ?  J, I' F' u& A1 M
5 L; l6 r6 Z) a& q- {
" S. y5 v1 z( H+ K
主要是DMA请求事件变了,其它配置跟第一种模式基本一样。# X2 N% N) z' N- O

4 w/ l% u5 {* l4 c+ p3 w配置完成后生成初始化代码,再添加下面用户代码:9 x1 q2 h% w6 v/ K. B" k" L0 _( p

7 `/ Y3 ?* x, r" d# w
  1. #define   Tpai     (2*3.14159)" Q# [, z* s. i4 K

  2. ( M" J: C8 c& Y% Y
  3. uint16_t PData[200], Dac_data;. ^- S& v/ Y  ]% h5 H$ z5 z/ [

  4. ' I* Q' u+ I/ U2 E7 T
  5. uint16_t     i;8 S3 w2 H  d4 N. k9 |" y8 N
  6. , o5 A  E% M: ^9 ~. X4 D2 L. r
  7. for (i=0;i<200;i++)
    1 |* }( c0 H5 j4 t9 h. |
  8. + _8 _1 p2 k; _7 M& j
  9. {undefined
    ; X9 |$ P3 e( |# Z' x9 Y% m( R

  10. 8 {# v6 `! u7 [9 a% Z% I$ Q/ W
  11. PData=
    2 k- j! h3 H( W2 |5 {
  12. 4 q) E( O7 S( ]6 k* o
  13. (uint16_t )(2000*(sin((Tpai/200)*i))+2000);& r1 ?$ n) z8 X9 Q; j+ L
  14. . K+ ^! |8 ^# i. E& o* s
  15. }
    8 |4 O3 B' `$ T6 V
  16. 5 [$ X* w8 |7 w' M, A& P
  17. HAL_DAC_Start(&hdac1,DAC_CHANNEL_1 );8 _  q% S  J9 [* H9 h7 C; J
  18. , n; a3 |- J: Q+ ]. U, ]5 T* _* M
  19. HAL_Delay(3);
    + H. W" ?* k. a( L7 m

  20. - Y7 z: J: A/ @8 i5 G

  21. 8 V) t% ~( _0 Y/ J8 J4 E! K

  22. " j9 ]  V" w6 T9 ]3 ~
  23. HAL_DMA_Start(&hdma_tim3_up,(uint32_t)&PData[0],(uint32_t)&DAC1->DHR12R1, 200);- k+ G1 P( n6 a5 m1 F% Q5 o

  24. 1 g6 Y6 _8 k( ^* k! H2 A8 e& T0 {/ L
  25. 3 r  u; L1 T/ A: }8 S
  26. + J3 q4 N$ o  t+ a
  27. __HAL_TIM_ENABLE_DMA(&htim3, TIM_DMA_UPDATE);
    8 m9 j: F, a# f$ \2 V+ ?) i( C

  28. * l& F5 _5 C+ y/ [- g! z4 X
  29. __HAL_TIM_ENABLE(&htim3);
复制代码

5 L% B3 i3 K' X2 T8 z2 p' p# G. _0 p
这里要提醒一点,G4系列的DAC1的数据保持寄存器可以一次放2个通道的数据,在使用DMA传输时,即使只用到1个通道,DMA对它的访问也要遵循WORD对齐,不然你可能会遇到麻烦。- x0 r1 t  \  J& `/ ^" S
+ q' k" N. D/ D9 w& T% _
如果说,我们不使用DMA做数据传输,只是手动给DAC喂数据,那如何实现上述效果呢?这时我们可以使用软件触发DAC的传输,手动给DAC的数据保持寄存器赋值,参考配置及实现代码如下:0 [5 I% S  g/ J

6 U1 [1 b1 D7 O; o* D0 s3 }8 T( a
81958bbf0c7325cd86a0ecbf4dc138ef.png
# a- |. H& J, N; n7 L8 c3 A

9 ?* r8 |" d) T
/ o( ]7 \& }. a/ W! I相关用户代码如下: 9 C/ I; W0 _5 ~  F% ^9 G8 G

2 W, E  p/ e& u3 B+ a. k6 s
  1. #define   Tpai (2*3.14159)8 k$ t* W0 c1 e8 a* x4 ^

  2. , w8 Z# P# O- i0 R9 L
  3. uint16_t PData[200],Dac_data;6 z3 t# \8 ?/ m7 I

  4. ! {0 Y2 b8 k6 D
  5. uint16_t     i;: z4 D) `( g# l  y
  6. 3 U1 y- P3 R. U# t: K
  7. for (i=0;i<200;i++)& B( `+ x( G8 a) t) m5 l

  8. 6 [6 k4 Z) o" Z9 k+ L( e* K) Z
  9. {undefined% F3 |& q5 j7 |4 E( l
  10. * W/ n8 s; y8 J: p& T8 j! X  o
  11. PData<span style="font-style: italic;"><span style="font-style: normal;">=
    ( ?' k+ w$ z5 D! c- Y$ k$ l* c

  12. 8 r% Q! S/ f! _
  13. (uint16_t)(2000*(sin((Tpai/200)*i))+2000);2 i" U: F5 L# U6 L

  14. + O( ?3 N4 e4 C. B
  15. }$ A4 r* y) K1 j; a" O! E

  16. . Y; y4 B8 ?8 Z) e1 r
  17. HAL_DAC_Start(&hdac1,DAC_CHANNEL_1 );% w- c. D0 \0 D" ~  f0 a6 L# C6 Y

  18. 3 L6 h: R$ C# z
  19.    HAL_Delay(3);
    ; ^$ ?1 S  h" p+ T' p

  20. % e+ F1 T$ i" [. ~. o- w0 Q3 A

  21. ) `& I0 a4 b! A% g- a, Q

  22. 6 |3 f9 `( V+ a1 o% g* V
  23. while(1)
    ) X0 Q- Z: g! C9 N4 j/ |% D% a

  24. * y% M5 S2 ^4 _2 r3 e2 g5 t
  25. {undefined
    $ T: y! |- l. z5 U2 B
  26. - N' b1 E! H& y
  27. for(i=0;i<200;i++)# {0 g" M0 ?2 [2 [3 e: \3 e
  28. ; d3 P. C) L  H* G, Y6 K( c6 p1 r: U
  29. {undefined! D$ k/ }. D8 g, j

  30. 2 Z* W- j% G7 u
  31. DAC1->DHR12R1= PData</span><span style="font-style: normal;">;
    & F. i) ~3 D: w: Y) c
  32. ' H$ G6 Y2 _& E: U4 t
  33. SET_BIT(hdac1.Instance->SWTRIGR,DAC_SWTRIGR_SWTRIG1);4 y* w# C$ K. |8 N( [

  34. ; l% t, ?/ q. T6 c
  35.       HAL_Delay(5);+ h6 r, F0 @- M  k; [9 u% ^4 s
  36. 3 f/ V$ B& E* d# f
  37. 9 Y6 |' u6 n/ T; z/ H" n( R
  38. 5 h' d; V* v* S$ j9 k3 Q9 o
  39. Dac_data = DAC1->DOR1;//for debug9 x3 a5 L; t1 M; g3 p. S

  40. $ V$ ~8 b# y, ?9 M3 {6 N

  41. 4 B( Y9 I/ z9 A% f' z5 A
  42. ; P8 A4 M* s4 D- F
  43. } , Q+ }8 t: R  O3 f/ t0 p9 K, Z4 h3 C
  44. 9 m& r% V2 G6 t1 G9 l" I; c
  45. }
    / V* J# u% w# v% \% |5 X$ ^
  46. </span></span>
复制代码

; ~$ [% d7 \$ \0 P总之,不论使用哪种方式,都可以实现我们所期望的结果,即输出如下正弦波。" t9 W1 _2 F( H! c0 i3 r. j
; c3 F+ p% o6 n
692bd68b1c31d5aa2a4b73541244f56e.png
* c. q2 P% ]  X

1 r' [  j% p+ ]4 Z& @  f4 b* u, @好,关于STM32G4的DAC应用就简单介绍到这里,STM32G4系列的模拟外设丰富而强大,此处算是抛砖引玉。这里做些分享也是为了让其他有需要的人少走弯路,加速开发进程。【文中代码都很简短、直观,就没做注释说明了。还有个客观原因就是在微信公众号里排版也很费劲,字符不太好对齐。若有需要交流的可以后台留言。】
5 r2 i  y7 g  J2 i5 `0 N0 S. R- f0 n6 w: t, x9 X' @6 b
, p% L2 V3 T% H% F  u. y2 m" u
79bba335bff508c4f57300f0f57049de.png
收藏 评论0 发布时间:2021-12-8 22:00

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版