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

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

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

9 |3 y, y/ u; t+ C/ O
8c8aec0947a9e081baa317138ac945de.png
+ h8 n4 f) z! @

+ @) w: f$ V9 e) |% `2 S6 e+ t
- i: A7 [& J/ b# [9 `结合STM32G4芯片的特性,这里可以有两种实现方式。" p8 j0 X7 I* o' O* S  X$ U
$ Y* f/ I+ W1 k+ i) Z4 q) g7 d  R% O
第一种,DMA的请求来自于DAC1的转换事件。第二种,DMA的请求来自于定时器事件,下面用到的是定时器的更新事件。这里就两种实现方式的配置及相关用户代码简单介绍下,以供参考。% m$ o! C  Q0 [$ x3 B, C

3 M# E: f0 v6 M% z+ Q我们先看第一种方式,即DMA请求来自DAC转换事件,定时器3触发DAC的转换。9 p9 X3 x$ [# E$ h/ N5 r2 B  ?
9 i% r, e8 c" ?7 d
使用CubeMx进行配置,主要配置如下:
; U' K- ]) a# y, R, p
d1020b7d0f8f4894eb7b709ab4cbed6d.png
( }% v6 l  k/ R/ |0 k

6 w' d) z+ j! r
6 |7 U! a# E1 X9 m
ddd67d8a4616146cdf0ec6419da513ec.png

# A' J/ o' |6 l- m2 h
  J% Y9 j- e  J" L7 A1 k6 `+ u- o# R
0f1f5180cdc185196607e3ef27b9e215.png
' x5 G, C7 D: k$ j* ^' }4 o; N8 x
" R' B" d# e* Z( _- g
完成配置后生成初始代码,再添加下面代码即可验证测试:
2 i/ f  N, J! G/ t  N  V
9 Q& G5 W+ W* @2 p1 @. ~6 P
  1. #define   Tpai     (2*3.14159)4 p- ?1 Y2 X6 d# V5 r! n+ N
  2. 1 E4 I' ?7 B1 P5 e; D
  3. uint32_t  PData[200],Dac_data;% s  ^1 r! ~' |! T" R! K. {
  4. % V) N0 X4 B( [% Z% ^
  5. uint16_t     i;3 E: G( _: ?( [9 u* q& d8 S2 u. x! c
  6. ! Y5 b; c+ H; \- c; Y4 ^, q$ i' V
  7. for (i=0;i<200;i++)0 i# `4 Z. |0 l" D; l% b3 d* _
  8. # e0 r% c. N) ~& z: ~: W
  9. {undefined+ O0 {" J4 O; [" K2 h
  10. # ?0 U9 I" W+ [, M+ n5 s+ g
  11. PData<i>=</i>
    ! G& u0 B( F# v1 u0 r7 V
  12. 8 H- j9 N# |7 |  Y1 x
  13. (uint32_t ) (2000*(sin((Tpai/200)*i))+2000);1 e: g1 _. Y) c) k& d! E

  14. # q4 {3 p+ D' L. W. W
  15. } //prepare data for DAC
    7 ~* y5 M$ Q3 ]7 Q! o9 d4 f
  16. % k* R& l* Z, S, D' C
  17. HAL_DAC_Start_DMA(&hdac1,DAC_CHANNEL_1,(uint32_t*)&PData[0],  200,DAC_ALIGN_12B_R);
    / w$ o) X1 Z# E6 `
  18. 1 R: s8 z/ F; W
  19. __HAL_TIM_ENABLE(&htim3);
复制代码

. a$ x8 l, k$ X& }& h9 g- ~1 h2 V- ~
2 F& J# H  Z. f) e; F: ^
上面配置的DMA传输方向是从内存到外设,目的和源的访问宽度都是32位WORD. 当然也可以是内存访问宽度为16位的半字,外设访问宽度为32位字。即DMA的配置像下面这样也是可以的。/ J; d+ n3 G6 ?) N/ @1 o
* u& ~" E( }8 @1 A
d1a3b9537ab66535982e8b0cb86d3bbc.png

  Z# S- a& {3 F! B2 C8 _  X5 l# \' G, F
其它配置不动,代码稍微改动和整理下即可。参见下面代码:
* ]1 h* w1 h8 R1 {/ t. n
+ `* j& q# i# Z
  1. Uint16_t  PData[200],Dac_data;( g5 f+ V. L* ~- T# k# y. M2 `3 i
  2. + u* V3 [0 f. U7 z9 h" ]( n
  3. #define   Tpai (2*3.14159)0 M2 a2 \  i+ e8 O( O

  4. ) e9 ~1 v. U2 q5 Y8 T
  5. uint16_t     i;
    , l2 u  q, \; a8 [; U+ X

  6. 5 _% E) N5 B- ~) I$ T+ ]
  7. for (i=0;i<200;i++)
    2 B4 E2 i7 W# W0 V( F8 ~3 m
  8. * \# z6 t9 g6 E5 f
  9. {undefined
    # b6 c, q) H. o/ B; [: {5 ^
  10. " r  k4 R$ B" q  d/ E
  11. PData=3 q+ |! i& k7 j3 `

  12. 3 B( r& a/ Y, x, a2 {
  13. (uint16_t )(2000*(sin((Tpai/200)*i))+2000);- v$ G; A/ g4 n" O* R5 _5 T7 f4 ~0 ]
  14. $ Q& Z( i, v% k
  15. } //prepare data for DAC" D  C( m$ d+ l# O9 H6 g
  16. 2 X2 s4 }5 \: t2 p& _( [; ]
  17. SET_BIT(hdac1.Instance->CR,DAC_CR_DMAEN1);
    # a$ V3 [8 `7 @: L9 G
  18. 8 \4 k4 r$ W# e' T  d9 Z% F

  19. 8 A# c1 F+ E1 h9 k' G  T
  20. % j/ W/ W; ^+ w9 [* S/ Y
  21. HAL_DAC_Start(&hdac1,DAC_CHANNEL_1 );
    8 \/ y3 V+ O5 ]9 n; O

  22. 6 Q7 I( y) I8 \! @- Z0 z
  23. HAL_Delay(2);5 X$ p/ h6 H. C  R- ]
  24. 6 Z/ B$ H, r4 a
  25. % m8 S  h4 \0 r' G4 i) u* V" H7 a
  26. 0 B7 z0 ?( E: H
  27. HAL_DMA_Start_IT(&hdma_dac1_ch1,(uint32_t)&PData[0],(uint32_t)&DAC1->DHR12R1, 200);
    ; a! }5 a* p7 k/ r
  28. 7 ~; W3 o  w2 f- S6 L! R

  29. 7 M% e# m, Y6 B# x1 f/ ?
  30. + N# W& D4 J" n+ z, h8 Y
  31. __HAL_TIM_ENABLE(&htim3);
复制代码
; N# D7 E2 B% o/ |, d" r, r

4 {/ u5 f0 W4 ]+ e
6 t" o: {+ E* g  U3 s3 R1 U2 T4 v* s" @$ |
第一种方式就介绍到这里,再来看看第二种实现方式,即TIMER更新事件作为DMA请求源,同时作为DAC转换触发源。
% C# a, O: f8 |& X
6 U: i$ ^; d5 R. ]3 m% y基于CubeMx配置,主要调整下DMA配置,其它配置基本不动。9 B8 U+ l) S; Q* J& g% u) y* m

# P* u) m0 a) t9 n4 L
$ a/ U7 L8 T- T7 _

1 U) ~* p, F5 `  d1 Y
* D- ~& I/ ]( S9 g6 @主要是DMA请求事件变了,其它配置跟第一种模式基本一样。3 x( u* m: b  {7 B  E

5 Q' ]6 V5 {/ c0 j- x配置完成后生成初始化代码,再添加下面用户代码:
+ j3 Q8 Y9 a4 p$ ?9 d: N
0 q% L% t5 R( X  ], \( t- g
  1. #define   Tpai     (2*3.14159)% ~# O0 r% M( Y! d0 x7 C2 f3 e

  2. 2 }5 q3 u( v7 n0 G$ h1 f
  3. uint16_t PData[200], Dac_data;2 E& ^$ C% C( h  c1 l
  4. & w7 d/ j8 ?  T0 n
  5. uint16_t     i;
    $ A. @9 b. i! W  t* [5 n+ Q4 Y

  6. 6 R9 ]/ t- r; M7 q; W  H
  7. for (i=0;i<200;i++)
    / C3 O2 z: Y  [" O. N8 X- Z# O

  8. ' C# r: q% u0 M- v
  9. {undefined
    # b( G+ f& G9 q# e5 N! Q
  10. , y9 S7 ~  g& R5 G, W
  11. PData=
    7 k( n0 E2 M; U2 C8 K
  12. ' V9 f) r, P6 G$ d, K# y$ s
  13. (uint16_t )(2000*(sin((Tpai/200)*i))+2000);
    - b2 L# j6 Q5 r3 W; g
  14. " L5 l1 F& y' S& k+ b+ r$ v
  15. }
    . T& i' X4 d  U' L3 T, B

  16. 3 F6 Y8 N7 ~! e: r# r
  17. HAL_DAC_Start(&hdac1,DAC_CHANNEL_1 );; Q8 F8 A# t& z0 ?# `% r7 G

  18. 0 c  o( P; }7 @+ a
  19. HAL_Delay(3);% ]6 l5 F4 }# \6 t

  20. : g0 ^) g! @+ I" o0 [- r
  21. % J/ @  K- i3 E0 @, E
  22. 1 F* u4 Z- e6 i: C/ E5 y8 z( p
  23. HAL_DMA_Start(&hdma_tim3_up,(uint32_t)&PData[0],(uint32_t)&DAC1->DHR12R1, 200);
    $ b7 t$ O* S7 f* U9 s; X: S6 A
  24. . O- o3 w, R# e6 @. d
  25. 8 K# A  H* H: j; t1 i

  26. % L; i' Y) |" }' ]
  27. __HAL_TIM_ENABLE_DMA(&htim3, TIM_DMA_UPDATE);
    $ n. \8 L- c+ `6 G  A1 T" E
  28. 2 g3 C: H/ z, ]$ {
  29. __HAL_TIM_ENABLE(&htim3);
复制代码
/ d$ ^) ?, ]+ r7 @* M. Y
: f% E# D9 M# V" v8 D2 L* D
这里要提醒一点,G4系列的DAC1的数据保持寄存器可以一次放2个通道的数据,在使用DMA传输时,即使只用到1个通道,DMA对它的访问也要遵循WORD对齐,不然你可能会遇到麻烦。
" [' r6 m1 r' X! L2 {
" i% v$ x: e$ \& G3 Y如果说,我们不使用DMA做数据传输,只是手动给DAC喂数据,那如何实现上述效果呢?这时我们可以使用软件触发DAC的传输,手动给DAC的数据保持寄存器赋值,参考配置及实现代码如下:: i  ]) b6 P8 d2 V3 m2 V. c

9 H0 R* j0 ^- [6 t6 O, I
81958bbf0c7325cd86a0ecbf4dc138ef.png

. i$ H& _8 v  Q/ F# z4 O8 S  D( [6 b! ^

( Y: @+ `$ P( k6 y, s5 n相关用户代码如下: ! ]( z: T0 P# P# Y2 t
6 ]' J, q6 q$ j
  1. #define   Tpai (2*3.14159)  w1 X& Q6 m8 H0 e! ?6 j

  2. . J* O" A2 V0 o. \) Z% a
  3. uint16_t PData[200],Dac_data;) l$ ^& {! X& @2 R! R( ]. b
  4.   _) F: U: V1 r
  5. uint16_t     i;
    1 i- W: |/ Q. [# @8 [" ^

  6. * s: b1 O5 v) w7 V; w" }
  7. for (i=0;i<200;i++)# `# Z8 S& l* v# z

  8.   k  f7 m5 v- d$ X0 c9 J" R
  9. {undefined/ |8 S0 g% W! L$ K, g

  10. 7 Y" E% F; V( |- z$ p" o0 G2 }. n
  11. PData<span style="font-style: italic;"><span style="font-style: normal;">=
    - Q) O# K' S( \- g" V" ^" Y9 m
  12. / n) X+ ?( I8 m
  13. (uint16_t)(2000*(sin((Tpai/200)*i))+2000);
    6 ~8 t/ i  z1 k, B% r

  14. ' j% W0 }& D9 n1 Y
  15. }
    7 c7 I# y/ B% V: H
  16. " K% y7 `7 T2 n5 ^
  17. HAL_DAC_Start(&hdac1,DAC_CHANNEL_1 );9 b* E3 l3 `+ A1 G- t# i! P
  18. 8 D) O+ m, |$ g$ o4 I
  19.    HAL_Delay(3);5 S# P( ~* F' ~! c' g4 g
  20. : u7 _& D) r# [: [$ z
  21. 0 P  n6 @* Q: G" |0 i! V3 x

  22. . L7 r/ K3 Y7 M+ D. s1 D
  23. while(1), w& D: Z% c/ j
  24. + D# H" o+ L* I, t- ~3 S& I
  25. {undefined& N" S, ?/ N4 u; L$ X/ j' C& O6 [
  26. . a+ N3 u8 t! t( D7 z6 q
  27. for(i=0;i<200;i++)5 y7 l5 I/ |( H- t! ^

  28. - D5 _1 _( S$ C' o- ^" G( a7 K
  29. {undefined5 p) i- w! L3 R2 Q; O! Y5 ~# S

  30. ( D5 f9 w  e+ n  D# C4 D
  31. DAC1->DHR12R1= PData</span><span style="font-style: normal;">; 9 }) o  V+ q8 F' v) ^- t
  32. + O2 x5 l7 \' V
  33. SET_BIT(hdac1.Instance->SWTRIGR,DAC_SWTRIGR_SWTRIG1);/ d* S( V+ F; r

  34. % c" u9 F+ ]& n1 t& A! m6 f' I$ r0 t/ Y
  35.       HAL_Delay(5);/ v, j6 e" P( \
  36. : d1 X* i4 O+ \* k# ]

  37. 3 W+ _) n5 B) \- j' x
  38. ; @7 }( N3 m' Y# M" _
  39. Dac_data = DAC1->DOR1;//for debug$ {, b* K( f& }

  40. ( B5 X: `: u; S' s
  41. , b4 s( M, E! S& b5 Y
  42. # z1 X+ Q: K5 _8 ?: g9 j+ C
  43. } 0 u+ H( f7 N/ ?& V
  44. 5 p& {* _8 o0 l; r, d# Q6 L# {
  45. }' V, H% H1 x# ]4 _8 b% ]4 q+ y, a
  46. </span></span>
复制代码

: j; ~- t; s" C" f& h总之,不论使用哪种方式,都可以实现我们所期望的结果,即输出如下正弦波。' u- R: g+ a% X' b( @$ W! Q- a
( |3 n  I- r" |  B8 @3 m) h
692bd68b1c31d5aa2a4b73541244f56e.png

! e: n  G$ z- L+ Z) t
7 S1 ?; Y; Z' P9 s9 Y好,关于STM32G4的DAC应用就简单介绍到这里,STM32G4系列的模拟外设丰富而强大,此处算是抛砖引玉。这里做些分享也是为了让其他有需要的人少走弯路,加速开发进程。【文中代码都很简短、直观,就没做注释说明了。还有个客观原因就是在微信公众号里排版也很费劲,字符不太好对齐。若有需要交流的可以后台留言。】
* v3 [. D4 ~3 q1 X6 r. x2 a# w8 K6 x- P. Y

- i! N" b* V9 c9 R1 h
79bba335bff508c4f57300f0f57049de.png
收藏 评论0 发布时间:2021-12-8 22:00

举报

0个回答

所属标签

相似分享

官网相关资源

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