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

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

[复制链接]
STMCU小助手 发布时间:2021-12-8 22:00
有人使用STM32G431芯片做DAC应用,具体来说就是通过DMA将数据从指定内存传送给DAC数据寄存器,并由定时器触发DAC转换。他发现总是没法实现该功能。这里简单介绍下相关实现过程,并做些提醒。这里要演示的基本功能就是让DAM将内存数据周期性传输给DAC数据寄存器,最后输出一路正弦波。
% _3 f$ c) ~; K# P9 @: {. _4 u5 `9 i* }; g4 k
8c8aec0947a9e081baa317138ac945de.png

6 q$ f1 a: |* a' n
* x; [" n: b) F# L9 C; w" s, e
3 t* p. \1 _' J' ]  g7 F2 a结合STM32G4芯片的特性,这里可以有两种实现方式。9 f" Z( l4 a, f- g8 I6 K2 R
1 h3 ]# W/ j4 g; y& n
第一种,DMA的请求来自于DAC1的转换事件。第二种,DMA的请求来自于定时器事件,下面用到的是定时器的更新事件。这里就两种实现方式的配置及相关用户代码简单介绍下,以供参考。+ H# O9 f7 x9 j. L- b6 g+ ~: l. p8 i
# Y4 [- t7 D# {4 q
我们先看第一种方式,即DMA请求来自DAC转换事件,定时器3触发DAC的转换。
) |) s0 w( z4 f& f- @' Q
, g8 ^. Z9 i* E1 {+ H+ H1 |使用CubeMx进行配置,主要配置如下:
; }3 G) x% U2 ]8 R( b
d1020b7d0f8f4894eb7b709ab4cbed6d.png
2 R# S; P# k# D; H3 g; ?  o

7 L# R8 n( E( a4 k3 G
! J2 Y1 Y( ?2 C% y! v+ B
ddd67d8a4616146cdf0ec6419da513ec.png

# p6 _; i9 L) C/ N5 \
; l" X( j- Z6 f. d, {& R0 N
0f1f5180cdc185196607e3ef27b9e215.png

# ?/ v0 @* b7 a) v# w5 J
& T- j& N) k% K完成配置后生成初始代码,再添加下面代码即可验证测试:/ i4 ^6 H3 o( B5 w3 v0 ]
/ j2 L) Z' \# ]
  1. #define   Tpai     (2*3.14159)
    ; h/ E; b: {5 ^5 ~. Z+ o8 }* G/ W. o
  2. / j% o; @/ ~( u# X
  3. uint32_t  PData[200],Dac_data;2 ^- @4 f3 T) P# b/ L
  4. ) K) K* ?6 o8 u9 t
  5. uint16_t     i;
    ! @3 K4 h& n# U  M# @( {6 k
  6. 5 g! b3 J- C+ I/ e. @. H& E$ i; q
  7. for (i=0;i<200;i++)
      a% W6 B% C& E; Z4 k
  8.   ^( Z5 c8 t) M  W0 q; g7 K
  9. {undefined, K& [& V4 o: X( c( ~) |

  10. / ^' f: K2 c' x! D8 N
  11. PData<i>=</i>
    # W; d% J2 d- I$ T& \

  12. ! [: O3 ?  }/ w
  13. (uint32_t ) (2000*(sin((Tpai/200)*i))+2000);. [7 m1 R3 b& Z  a4 `( Q8 j

  14. " |3 p5 F& U, u  A# V* Z
  15. } //prepare data for DAC, Z2 [+ z% O5 J; T4 K# e

  16. ) m# u: O0 s7 a" ^7 u- M8 F
  17. HAL_DAC_Start_DMA(&hdac1,DAC_CHANNEL_1,(uint32_t*)&PData[0],  200,DAC_ALIGN_12B_R);& j9 w9 ]* K' W2 q

  18. % v6 O3 B; v7 k5 g1 c: S
  19. __HAL_TIM_ENABLE(&htim3);
复制代码

; z. U! ?4 h& q/ k  ^3 U! `
% ^# a8 }, L5 U8 Y1 d9 y- @4 |) p5 Q# l
上面配置的DMA传输方向是从内存到外设,目的和源的访问宽度都是32位WORD. 当然也可以是内存访问宽度为16位的半字,外设访问宽度为32位字。即DMA的配置像下面这样也是可以的。
8 y, Y) e+ H; [# @% c' L- m; [2 ]* e. _& g; n7 L$ t8 N
d1a3b9537ab66535982e8b0cb86d3bbc.png

) j# \2 ?  R# O- D
' ?1 Z! C" d* p" J* j& N其它配置不动,代码稍微改动和整理下即可。参见下面代码:
5 P! ~5 z, a# ?( C* w8 V6 T& r5 z  I1 Z3 z, }* p
  1. Uint16_t  PData[200],Dac_data;
    . A+ i! @; X" ~$ z
  2. - z( a6 S% n' E0 r4 p
  3. #define   Tpai (2*3.14159)
    ' j# {4 |& k/ {: M/ P! W7 B
  4. " A* G/ @, t  `; C9 I
  5. uint16_t     i;' G# P! A5 q7 I* j  B% C+ L6 T
  6. 1 O9 ?. K' X3 f- K
  7. for (i=0;i<200;i++)
    & N& ]# P6 V, h8 R# P* ^7 L
  8. , C0 P# G/ {4 k5 e' }) z- B: i
  9. {undefined
    7 u( O2 R- f$ u4 I( o7 K
  10. % e; V  X- m* i  \8 g& W+ A
  11. PData=# D) R  ]: @# v$ [7 L$ e8 R
  12. ) T* K9 x4 K: L5 U  f
  13. (uint16_t )(2000*(sin((Tpai/200)*i))+2000);# D+ s' ]1 p% ?+ o

  14. $ w. z. K. Z2 ]5 J. p8 G7 E
  15. } //prepare data for DAC; w- Q; f/ |) L, z9 \4 l
  16. ! ~: ]% O( _; N# x
  17. SET_BIT(hdac1.Instance->CR,DAC_CR_DMAEN1);
    9 T5 |: f7 V  m7 M
  18. 6 Y' b+ x- L( B* ?2 ~

  19. 5 l* X4 L* N7 @* I& _, K8 [8 j

  20. ( ?: ?/ e9 `" m4 @  }
  21. HAL_DAC_Start(&hdac1,DAC_CHANNEL_1 );/ h) f; C9 O: p$ y% e! k

  22. ( A( T7 h! y; _
  23. HAL_Delay(2);
    " x! k+ E5 a8 Q2 B- i

  24. & f4 _: ~& X2 f5 E  A+ Y
  25. ; [4 V- l3 F' A) C6 i
  26. % D  c3 T$ o4 s
  27. HAL_DMA_Start_IT(&hdma_dac1_ch1,(uint32_t)&PData[0],(uint32_t)&DAC1->DHR12R1, 200);4 {, s# d- F) ]+ Q8 B

  28. . K5 s, G# y! \, m
  29. / O& y0 B1 K. s) V9 C; g7 |3 a& c

  30.   P* t9 e6 v  l( }9 K. F' ^: i
  31. __HAL_TIM_ENABLE(&htim3);
复制代码

1 R7 g4 n+ \" P4 i1 p) T1 a  k' t1 O! `1 `6 q3 l8 B' M

) _% [, {3 O/ b: m5 B3 n! V9 Q, t. t& ~. t, }
第一种方式就介绍到这里,再来看看第二种实现方式,即TIMER更新事件作为DMA请求源,同时作为DAC转换触发源。2 a3 `9 Q; g+ d& b8 r1 j0 E& J# [9 L- Q/ J

$ y2 n! t0 d5 L  a7 Y% A基于CubeMx配置,主要调整下DMA配置,其它配置基本不动。
3 O- i" y6 z, w9 M' T0 x5 x1 b. R" p: [2 ]( \+ `

8 X* @) |5 F5 o2 v4 B: X" d% x. K( e( h* B5 `6 z( ~( R9 r

# w7 |5 V+ n: C% F4 B主要是DMA请求事件变了,其它配置跟第一种模式基本一样。
# R& o* J8 j- U" q& {; I: O4 k9 c
5 b; W2 v1 N( w. D# |/ D配置完成后生成初始化代码,再添加下面用户代码:  `/ b$ |- d' R$ c* X7 s8 k( f
  u! i' z& c4 ~
  1. #define   Tpai     (2*3.14159); }' B# }* e* d' {/ @6 M* Y# `* L( O
  2. ' }; y( j, q1 c$ E$ e7 ~7 X! u
  3. uint16_t PData[200], Dac_data;
    . B% U5 `7 d; Q2 \, ^& A2 A; D* k
  4. 0 Q) q3 \. w. E7 p& d
  5. uint16_t     i;6 F% K  Q* O. P/ r

  6. ( o% T# }4 Q3 J- v8 d- L$ \  T
  7. for (i=0;i<200;i++)
    5 f7 r' J$ }, ^! S" o3 q
  8. ' D- b# x6 `3 U( `/ @: |# ]
  9. {undefined
    - L1 g$ a3 X; M8 \

  10. * V  r% ]+ _" E8 g
  11. PData=3 m6 c+ }2 L1 \

  12. ) g' E& p1 m+ [; E
  13. (uint16_t )(2000*(sin((Tpai/200)*i))+2000);0 \2 V8 `# F1 ^3 m

  14. , V& Z: R# @6 v' o
  15. }7 q3 z' C- i* K. s& W8 B' ]* E9 a

  16. $ s; w6 p( ?9 w- E. m
  17. HAL_DAC_Start(&hdac1,DAC_CHANNEL_1 );
    2 K4 c( F; V; `( R3 @. m
  18. " ?: `  [2 p3 @
  19. HAL_Delay(3);
    4 _2 M9 s; A5 k4 n5 [

  20. 1 A! r7 ]8 V8 d

  21. / `- Y5 j0 K0 ^/ O% X6 s8 ]
  22.   U/ t# Q" f* Y; |5 w* q# Q6 Y
  23. HAL_DMA_Start(&hdma_tim3_up,(uint32_t)&PData[0],(uint32_t)&DAC1->DHR12R1, 200);
    9 ^( t2 y+ x9 J* V
  24. " b& o! N/ z* D6 j+ e9 x1 ?
  25. - s1 K7 @+ Z% Y0 T/ e: Y* m5 P
  26. 7 O6 w! ]- n/ B6 n1 k4 D
  27. __HAL_TIM_ENABLE_DMA(&htim3, TIM_DMA_UPDATE);
    ; x3 x) p* M. j$ F* P- |

  28. 0 I& x8 q/ i9 A3 V! R
  29. __HAL_TIM_ENABLE(&htim3);
复制代码

( B* N- {2 C. Y# ^$ p" ?! f% n1 G/ k/ k8 Q. J: e: m
这里要提醒一点,G4系列的DAC1的数据保持寄存器可以一次放2个通道的数据,在使用DMA传输时,即使只用到1个通道,DMA对它的访问也要遵循WORD对齐,不然你可能会遇到麻烦。  v4 |0 i1 x5 t7 m
9 s4 h% C" {' Q, r4 }) o1 h
如果说,我们不使用DMA做数据传输,只是手动给DAC喂数据,那如何实现上述效果呢?这时我们可以使用软件触发DAC的传输,手动给DAC的数据保持寄存器赋值,参考配置及实现代码如下:3 W- q3 M6 i5 a! h% }2 G/ {/ [

; ^1 R# f% |% `, R# o- K  `( y
81958bbf0c7325cd86a0ecbf4dc138ef.png

0 E0 ?1 n) H5 q1 @/ I' Q, |( |! A/ e8 q. U" j
& ]4 ]# {! l7 r/ ?
相关用户代码如下:
  O1 ]+ d( D9 _3 ]  R6 i3 F4 X5 [/ Q4 h4 P) x
  1. #define   Tpai (2*3.14159)- M  V: t" e/ h' T7 B# c( h& \! \
  2. 2 T2 I2 o0 A# r; ^( s' v, N; Y
  3. uint16_t PData[200],Dac_data;
    4 M0 I" _+ t; j' p$ X

  4. 5 ~+ n% ^( N$ ~& T2 `/ ~
  5. uint16_t     i;' O1 C' J3 e5 S, |0 }

  6. 3 h  D& M, I6 `9 S% ?/ l: G7 x
  7. for (i=0;i<200;i++)# b, f- t! [1 |( E4 ?0 h0 R

  8. ) p% N$ v2 V3 ~! y2 B. ]
  9. {undefined; ~" z) `  D) S5 V# U9 c( ~
  10. # q' Q( q+ V7 P  V1 Y1 p8 R
  11. PData<span style="font-style: italic;"><span style="font-style: normal;">=4 T1 D+ ]; z, e1 r# w) A8 D
  12. ; a3 K8 q  i5 e7 \9 ~# G* h1 W
  13. (uint16_t)(2000*(sin((Tpai/200)*i))+2000);: p7 a( t8 |1 T% H0 g7 P
  14. 9 S5 u' p9 Z& Y7 ?
  15. }* [$ _6 f- e; L" a. E7 j0 h
  16. 7 j3 _) I3 @9 s  V" N- R3 S3 l7 x
  17. HAL_DAC_Start(&hdac1,DAC_CHANNEL_1 );
    * G* s% d& Q1 k. L$ s

  18. 1 @; r) H. B8 e+ z7 R
  19.    HAL_Delay(3);$ |! n1 H0 L6 \% v  h2 i- i5 B# Z

  20. 6 _5 L! D; g/ m, o2 k$ ^  J

  21. 8 v+ i3 |3 C  }9 u7 O( m

  22. - d9 J  {) @# f. r- M( }8 y9 m
  23. while(1)  F; p% P. S+ {& J( j0 }

  24. 5 J6 B) N& ]6 \% R. C5 w3 D$ Z! \# w
  25. {undefined) x. m& X0 \9 Z! c: N8 q; [: J

  26. , A2 v& K8 R1 L) P6 l
  27. for(i=0;i<200;i++)
    + o" R6 b* P! e! Z

  28. 4 }. ]! h0 A7 L8 K' g! k6 _$ ^5 E
  29. {undefined
    5 J4 B: @& w& j( g" N' x
  30. $ F, a( W. U) q- X4 ?: o
  31. DAC1->DHR12R1= PData</span><span style="font-style: normal;">;
      K3 k! f. p! Q

  32. ' D: c1 P2 Y: X5 O- R* M
  33. SET_BIT(hdac1.Instance->SWTRIGR,DAC_SWTRIGR_SWTRIG1);
    : R. f& C: c( a7 a. u

  34. - E# l) L/ W& ?  ~6 |( i9 ~' [
  35.       HAL_Delay(5);, u5 J4 J1 F: j' m: K5 K! X

  36. ! E% T9 q+ r1 o+ I) l% i8 ~
  37. 7 f5 |/ I" C! x: c$ a

  38. * L! G7 E& X6 u: C
  39. Dac_data = DAC1->DOR1;//for debug7 s- c$ C2 ]3 o0 x( k
  40. . S$ t3 ~5 p) H4 y

  41. + u5 [9 f3 K  q* [, S, Z- G
  42. 2 u/ |5 |; C8 B( _0 u
  43. } : V! u0 C, r" h
  44. 1 ]( T* J' H3 ]5 k( v+ @2 A' M
  45. }3 ]8 H! N' T! N- A' w
  46. </span></span>
复制代码
8 \. L4 Z+ @- r- K( Q8 d
总之,不论使用哪种方式,都可以实现我们所期望的结果,即输出如下正弦波。6 P% i/ |# O5 {! L, s
# Z5 m  j8 L$ L
692bd68b1c31d5aa2a4b73541244f56e.png
5 y# j* P3 a( B' g0 v8 u, n, z" o2 y4 Q
) @8 M! e9 `% f, k" P
好,关于STM32G4的DAC应用就简单介绍到这里,STM32G4系列的模拟外设丰富而强大,此处算是抛砖引玉。这里做些分享也是为了让其他有需要的人少走弯路,加速开发进程。【文中代码都很简短、直观,就没做注释说明了。还有个客观原因就是在微信公众号里排版也很费劲,字符不太好对齐。若有需要交流的可以后台留言。】
9 Y+ B! M. r$ J; g( {0 `: O3 G) W5 U5 D3 w2 t: j
% B" L  P/ O- r3 A; p5 B7 e  D0 b
79bba335bff508c4f57300f0f57049de.png
收藏 评论0 发布时间:2021-12-8 22:00

举报

0个回答

所属标签

相似技术帖

官网相关资源

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