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

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

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

# t, d/ d8 D$ r% a! i. u- g
- R, l- d5 Z- \4 o: [, H9 u! H! O$ |" Z
结合STM32G4芯片的特性,这里可以有两种实现方式。. v& Z5 s' Y" K3 a6 \1 `9 o9 Z3 G0 D
2 {" \/ i6 q( z
第一种,DMA的请求来自于DAC1的转换事件。第二种,DMA的请求来自于定时器事件,下面用到的是定时器的更新事件。这里就两种实现方式的配置及相关用户代码简单介绍下,以供参考。& Q8 X& @! i2 J# x0 G

$ @5 J7 B9 t1 h2 E. W8 C& E' T* l我们先看第一种方式,即DMA请求来自DAC转换事件,定时器3触发DAC的转换。
0 S2 G8 A% c+ s) B$ \! j
# D% v% C5 z: [" U6 v9 t1 l2 A' \使用CubeMx进行配置,主要配置如下:
# c# x: Q6 \3 H$ p' V
d1020b7d0f8f4894eb7b709ab4cbed6d.png

; e1 w/ N" g$ M9 @5 U  `: q
( f5 |; w* v1 ~$ H+ P9 I# o* E' C4 D1 _1 r  j9 A
ddd67d8a4616146cdf0ec6419da513ec.png

6 Q) y7 s. [2 d7 q+ Q# z( Y* {$ s* T9 G7 j5 H
0f1f5180cdc185196607e3ef27b9e215.png

( w4 q7 T2 l: `, ?0 b! B/ _) n8 v  o% Y3 T2 n' A! F, H
完成配置后生成初始代码,再添加下面代码即可验证测试:  t! q( d- i2 k$ v0 z
: I7 X! B) M/ x2 M
  1. #define   Tpai     (2*3.14159)9 \% O; @/ `( C$ p* N
  2. ' [4 x! S. e( T
  3. uint32_t  PData[200],Dac_data;3 p. x7 ^" f, s& |5 ~

  4. / U/ L& Q+ E% H% N
  5. uint16_t     i;. m. s6 L& }2 ^# F
  6. 9 f7 [9 R% z" i2 h( ?/ L8 u
  7. for (i=0;i<200;i++)1 e  t2 n) S/ T
  8. 8 G5 h: T# c/ S3 C; k7 m0 O$ n# ~) u
  9. {undefined
    : i! C; S5 k+ |7 e. ^

  10. , x4 f7 t6 G1 W% z: Y- ?- V
  11. PData<i>=</i>
    1 O, f& P# P2 D# Y! b
  12. $ d0 h' ?& p7 h* D
  13. (uint32_t ) (2000*(sin((Tpai/200)*i))+2000);6 A( M6 l" y! f( y# d

  14. : B- i9 s) N0 E1 Q- m# C! ~
  15. } //prepare data for DAC, _% ?9 W, J' _0 a. e# W$ H
  16. 4 u! a1 ]: W( H6 l% Q5 K) I- h
  17. HAL_DAC_Start_DMA(&hdac1,DAC_CHANNEL_1,(uint32_t*)&PData[0],  200,DAC_ALIGN_12B_R);
    . Q4 c4 W+ |# I+ a: D
  18. 6 n% |, H2 `$ L5 B" u9 T
  19. __HAL_TIM_ENABLE(&htim3);
复制代码
0 z  L+ Q; Y; L$ @; U  {2 h2 |

; C0 G; |( ], X& v  b6 h$ _9 R" f: }
上面配置的DMA传输方向是从内存到外设,目的和源的访问宽度都是32位WORD. 当然也可以是内存访问宽度为16位的半字,外设访问宽度为32位字。即DMA的配置像下面这样也是可以的。
% u% q3 @0 N% N3 a, T
3 L. N/ k6 p* M( `5 c3 }- c6 \
d1a3b9537ab66535982e8b0cb86d3bbc.png

) D0 k2 {. B" Q% u1 B+ t* Y
' r: f: O1 x; e% E$ ]5 R其它配置不动,代码稍微改动和整理下即可。参见下面代码:
4 V1 N4 G- {5 K0 M/ o# O6 f6 \9 ]" x2 I  F) @
  1. Uint16_t  PData[200],Dac_data;: l& s# g9 R0 H/ o+ B) K% m, C
  2. ; m1 g* A% d' W+ E/ ]
  3. #define   Tpai (2*3.14159)
    0 t0 {. |( E- ^' ^. D' L0 }

  4. " k" o) e9 I: \# F, l
  5. uint16_t     i;
    " j/ P: o4 v8 M

  6. ) j- }0 p  o) K
  7. for (i=0;i<200;i++)0 \4 c9 r# o% k; ]1 a/ ?+ O

  8. ( ^6 O% r6 h- F# z. M; @; y
  9. {undefined
    $ J+ ?! q% L' j9 e5 |( s
  10. " q3 Z9 f( [# @7 W
  11. PData=6 [3 ^2 Z8 l" F2 I
  12. ; u9 \+ `2 O. m. m3 _
  13. (uint16_t )(2000*(sin((Tpai/200)*i))+2000);
    # T, z/ k9 _$ ?" w

  14. # C7 @% {' F( D' h  x7 m, X
  15. } //prepare data for DAC  r2 G( s! I& m

  16. + o" E+ b4 K( P  J' y2 [9 h
  17. SET_BIT(hdac1.Instance->CR,DAC_CR_DMAEN1);
    4 b8 [/ ]" D0 I7 N) [  g
  18. ! f1 B- |1 B) a4 }% X- m$ @
  19. 2 x( d# h, _' y8 h  f

  20. 1 l( w# t. F  U, p3 T
  21. HAL_DAC_Start(&hdac1,DAC_CHANNEL_1 );
    9 S) B- N$ b2 b6 m
  22. 9 C+ f0 E+ S8 ?# H8 L# f" `/ P% F: R- Y
  23. HAL_Delay(2);
    6 @4 w# A5 W5 e; U

  24. 2 @- b* J/ X. K2 r8 x6 R( g& q5 W

  25. # z0 {5 E/ U9 y* b- M

  26. 6 O5 k/ G) j! b( T
  27. HAL_DMA_Start_IT(&hdma_dac1_ch1,(uint32_t)&PData[0],(uint32_t)&DAC1->DHR12R1, 200);1 U/ X. n5 s! ]5 ?$ H- p
  28. + J: e# S. }2 I7 v. B* Y
  29. + z) J+ V0 t, P" u$ z1 ^
  30. % l$ `4 C1 `1 o$ U) P; C
  31. __HAL_TIM_ENABLE(&htim3);
复制代码
- R! Y/ j4 H5 S. e& z1 Y
- h. H" W8 c$ f

  E9 c, D2 P/ O$ I" P6 b& C5 F# e* X
第一种方式就介绍到这里,再来看看第二种实现方式,即TIMER更新事件作为DMA请求源,同时作为DAC转换触发源。
/ E1 g1 `7 q, u7 ]+ O) w+ e- P' c' y/ {! S2 r; j
基于CubeMx配置,主要调整下DMA配置,其它配置基本不动。. }1 Q8 A; k: [" j% E  @' T' }
) x- x, S7 F2 U: N
* U' q. k0 ^4 n7 \

1 p0 i. ~' g/ G$ m- g) e6 L! @9 W* q6 m1 P6 n  J" }
主要是DMA请求事件变了,其它配置跟第一种模式基本一样。2 v" E3 u; G0 S0 L
; Q3 ?" k1 ^( J2 r
配置完成后生成初始化代码,再添加下面用户代码:9 |2 @3 Y2 U9 |  z3 J! Z
3 n* Q3 g) I" l! x
  1. #define   Tpai     (2*3.14159)
    9 h; {  O5 o7 H) ?

  2. 5 S4 {  ?! L( n
  3. uint16_t PData[200], Dac_data;
    : ^, N6 i$ z+ A' o6 K4 l7 c7 ]

  4. " C" r  \0 T; U9 v; n- q" R
  5. uint16_t     i;- w9 {6 l0 a9 N/ w; ?( d

  6. ' j' o& V: H7 j
  7. for (i=0;i<200;i++)7 S2 P/ |# H7 N

  8. " R$ s+ z- m  }- E  |
  9. {undefined
    # `2 h" n. C" U, _1 f9 W

  10. / d6 q5 m- W9 ~" ]8 e( ?: V; D
  11. PData=. {2 g8 k6 h% f* |5 ~

  12. . f1 N' H2 l$ [& I0 v5 _6 X; C- B
  13. (uint16_t )(2000*(sin((Tpai/200)*i))+2000);& O  P$ o( r4 r, l- i1 a  f
  14. : A' n% Y: ]9 i  w! f' x) e: S
  15. }3 P8 {$ ~" D, P8 ~: [. L
  16.   e6 c  s" \" T& }* K# d' ^
  17. HAL_DAC_Start(&hdac1,DAC_CHANNEL_1 );
    8 i  i* g. f: A2 X4 h" W" s/ T& J
  18. $ c% X' `. u( J  y, W
  19. HAL_Delay(3);
    " ^2 z1 L8 H$ Y+ M1 X, n

  20. 3 Y- ^; m  E, h7 g: F2 e4 E
  21. * y- g/ k0 f9 B9 a
  22. / S9 O7 g  V! C  e# m/ Q8 Q
  23. HAL_DMA_Start(&hdma_tim3_up,(uint32_t)&PData[0],(uint32_t)&DAC1->DHR12R1, 200);
    1 D4 _6 C( P2 g  S

  24. ( D6 ]4 {% S. V  S& \$ P  ^' F
  25. ! s+ t; N. j! F) j/ j/ ?0 z
  26. # m0 ]" u5 a6 b: \3 k" v* G1 Q- i6 p
  27. __HAL_TIM_ENABLE_DMA(&htim3, TIM_DMA_UPDATE);9 E4 D2 q* N8 m; a4 X

  28. 9 Y8 a. b- T/ |8 C; |* F. D
  29. __HAL_TIM_ENABLE(&htim3);
复制代码

; H, h" q1 l8 H# t/ y% ^" T$ O5 n- x4 S( K& R$ k; {" L" x
这里要提醒一点,G4系列的DAC1的数据保持寄存器可以一次放2个通道的数据,在使用DMA传输时,即使只用到1个通道,DMA对它的访问也要遵循WORD对齐,不然你可能会遇到麻烦。
0 e6 v1 Z' m- C; u; V* T' f. u: l( q$ [  K
如果说,我们不使用DMA做数据传输,只是手动给DAC喂数据,那如何实现上述效果呢?这时我们可以使用软件触发DAC的传输,手动给DAC的数据保持寄存器赋值,参考配置及实现代码如下:
; ]# m0 m  q0 U; {- f: t: b) O. h3 U& v- p
81958bbf0c7325cd86a0ecbf4dc138ef.png
& u5 o5 y- T& S* p  f( u
" B1 A  |) E& B( R

' I$ o8 E1 d! C5 a$ t' G相关用户代码如下:
# R6 T5 O+ ]: t6 P* q+ C; T, `5 \  G4 Y9 ?3 f& J
  1. #define   Tpai (2*3.14159)
    % N1 p9 p4 S- K3 I0 b- C3 ?* {
  2. ( e" G0 L, g6 ~: }
  3. uint16_t PData[200],Dac_data;* s* A# F( J% m3 |- c# O
  4. ; A) x, y  _0 F
  5. uint16_t     i;  X/ ^% u5 |# \3 w" h' z
  6. 8 R( M( W; l7 S. |4 _* o
  7. for (i=0;i<200;i++)
    - W- M6 M7 r0 B) ?% ^% c
  8. 2 o7 G: g$ m, A& l
  9. {undefined
    8 P" U& K1 [; e
  10. ( m5 O# i! ~- c0 `# H
  11. PData<span style="font-style: italic;"><span style="font-style: normal;">=6 @" h" B! U7 Z! Z

  12. - d; X  t8 r8 T* T: o& ~4 L
  13. (uint16_t)(2000*(sin((Tpai/200)*i))+2000);0 D8 ^$ _# S* \

  14.   E8 {: F1 A  t% z% C; X5 m6 W" X
  15. }
    ' f* D4 s- z1 b

  16. # |8 X& e$ r' P% e/ d3 \3 U
  17. HAL_DAC_Start(&hdac1,DAC_CHANNEL_1 );
      V- {7 k6 E# q

  18. : |( D  ?  E3 v
  19.    HAL_Delay(3);
    5 b/ Z* @+ Y% E6 Z

  20. ! a5 _+ _# K) L) o8 Z

  21. 6 V4 E9 q+ k! C. R

  22. ) d0 F1 H" N& z+ e
  23. while(1)4 N! ]* v' e* G# o$ A2 S4 W

  24. $ M& h( i0 {# n# c% _5 ?" B
  25. {undefined' P1 V! l8 j3 @5 f
  26. 7 s+ F3 M2 c' A
  27. for(i=0;i<200;i++)7 c5 E- J4 \3 ?" {' E
  28. % s) }  B  n3 c% c; t
  29. {undefined& ^! c% X9 D* [- q6 i' X- W5 E1 u  @
  30. & ^  @6 x" T) n5 U4 Y( W, E
  31. DAC1->DHR12R1= PData</span><span style="font-style: normal;">; ' s: @% \0 z. L  t
  32. ! C: y2 Z3 O2 a" J. x
  33. SET_BIT(hdac1.Instance->SWTRIGR,DAC_SWTRIGR_SWTRIG1);
    * I4 N6 P' f# \9 u: z5 \0 V7 y4 G

  34. + @: [' l4 |* ~
  35.       HAL_Delay(5);
    ) \; C5 x. d) Z5 t: y

  36. 7 [5 m* p. H" X. T9 t

  37. : |, j+ t( S. ^9 `( K
  38. . j6 |9 z) C1 k4 y; Y4 O7 M+ q) `
  39. Dac_data = DAC1->DOR1;//for debug8 k" U$ R/ y( G1 K4 n8 E8 m4 X

  40. ) U, V! u- |2 F
  41. ! ?9 Y" p1 g% J6 H
  42.   E/ O. a; @3 T7 W' [+ r, k
  43. } + J  y( Z' `, e- w3 k
  44. % @6 O, I2 F- n" h) y2 f
  45. }
    # M1 ^) b* R8 b; [* n
  46. </span></span>
复制代码
0 ]! ^' I7 w  K0 T" e3 e
总之,不论使用哪种方式,都可以实现我们所期望的结果,即输出如下正弦波。. h; Q7 z2 t! N( r: D; H' H

& l* T% r1 q" d  ^
692bd68b1c31d5aa2a4b73541244f56e.png

  r( R6 B& c9 L; p
8 h& `/ [  |- s3 z% ]好,关于STM32G4的DAC应用就简单介绍到这里,STM32G4系列的模拟外设丰富而强大,此处算是抛砖引玉。这里做些分享也是为了让其他有需要的人少走弯路,加速开发进程。【文中代码都很简短、直观,就没做注释说明了。还有个客观原因就是在微信公众号里排版也很费劲,字符不太好对齐。若有需要交流的可以后台留言。】$ X* C8 a" y2 k( ^

# C$ _4 c: D$ A# z7 W
+ \1 Q6 K9 M, ~" y2 [
79bba335bff508c4f57300f0f57049de.png
赞 收藏 评论0 发布时间:2021-12-8 22:00

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版