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

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

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

0 ?% G! L1 @7 P, h$ a
8c8aec0947a9e081baa317138ac945de.png
$ m7 t& x& U' L
9 Q4 |; e$ B/ a8 u, c1 ^

* y1 h2 k$ N. L% v! l& N结合STM32G4芯片的特性,这里可以有两种实现方式。8 I2 v# @* v- A
, p/ I; u4 }0 X; P4 D" ]- d: F9 h1 l
第一种,DMA的请求来自于DAC1的转换事件。第二种,DMA的请求来自于定时器事件,下面用到的是定时器的更新事件。这里就两种实现方式的配置及相关用户代码简单介绍下,以供参考。+ {! y# L" W9 b- P
$ ~: Z& d2 l. a6 L2 i7 R, t
我们先看第一种方式,即DMA请求来自DAC转换事件,定时器3触发DAC的转换。$ ?) R* T, |5 Y1 V) ^9 @! x
$ ?- H: y; k! d$ ^+ _
使用CubeMx进行配置,主要配置如下:
/ a5 F+ L) b' {8 j! j
d1020b7d0f8f4894eb7b709ab4cbed6d.png

, {! R+ p" n: s# p. s3 \9 ?
% _* k* j; j2 y& F2 ^( q4 a3 D+ B" e- [5 F2 N7 ]% y
ddd67d8a4616146cdf0ec6419da513ec.png

& r4 t$ H% ?$ d/ s* ^" ]! y0 v. S2 W+ b! m* H. D; m' i! P& J
0f1f5180cdc185196607e3ef27b9e215.png

; U6 k# |# F' z0 z) \
( }2 k( R3 a) P6 L0 X7 f$ o1 R( S完成配置后生成初始代码,再添加下面代码即可验证测试:: A# z# l: Q, l

4 J+ ?! I2 _) H+ z( ]$ R( ]' W% f
  1. #define   Tpai     (2*3.14159)( Q- f1 E* t6 n4 Y& u

  2.   B2 b3 `& l" U+ n5 I% @
  3. uint32_t  PData[200],Dac_data;
    ) g. f' X* U' _

  4. 6 G% V' n$ J. q. }5 x. S/ K
  5. uint16_t     i;
      ^# k' K8 Q( G- Z2 ^3 O9 Q8 r, {  e

  6. 6 |+ i3 A) a* Z$ S
  7. for (i=0;i<200;i++)
    ; B- `; `. y  P( }
  8. ' h4 m  O; V, r- |
  9. {undefined9 X4 @+ a1 A! e+ F! \

  10. 9 T" d3 c" v, D; q
  11. PData<i>=</i>& S  ]/ {, h2 g2 T. _

  12. 4 z8 \9 g4 ^0 ]
  13. (uint32_t ) (2000*(sin((Tpai/200)*i))+2000);; K* T2 {: [6 u! ?, ~
  14. * Q4 M$ u" s" a3 L- i# n
  15. } //prepare data for DAC
    * G& \- c0 I- Y/ x. v

  16. ; u9 {* i% B2 i$ h
  17. HAL_DAC_Start_DMA(&hdac1,DAC_CHANNEL_1,(uint32_t*)&PData[0],  200,DAC_ALIGN_12B_R);
      J. \1 N, t/ w% F1 F
  18. $ M9 S# n) q  y, H
  19. __HAL_TIM_ENABLE(&htim3);
复制代码

5 ]' N' P6 J  i- r& I  D. ]' ?% s+ Y8 ]# Z9 b

. p3 m9 `1 f7 r% Y上面配置的DMA传输方向是从内存到外设,目的和源的访问宽度都是32位WORD. 当然也可以是内存访问宽度为16位的半字,外设访问宽度为32位字。即DMA的配置像下面这样也是可以的。
+ H& m6 l# Q7 l  Y/ H7 q- w$ h2 A! M/ m9 B
d1a3b9537ab66535982e8b0cb86d3bbc.png

3 ]8 J: |( j" w' f8 i1 t
$ ?4 V( e7 `( Z7 u( v7 n; S3 p3 D其它配置不动,代码稍微改动和整理下即可。参见下面代码:
: F# N- O% z8 Q! _. x: _
  s1 V  y) T1 V$ q
  1. Uint16_t  PData[200],Dac_data;
    ! e( Q8 D; F) O2 ^6 x" H
  2. * A% l$ r8 l" c, o! U8 {
  3. #define   Tpai (2*3.14159)" |3 g" E7 G( {1 L( L  _
  4. / a0 E* y/ X& F+ h7 ]
  5. uint16_t     i;0 Y# p0 c% a0 ]$ N- U1 e

  6. : S+ d7 f" a$ F7 @% z
  7. for (i=0;i<200;i++)4 o: J) v- e, F- p! x5 s

  8. 0 ^6 G. U9 V, A4 D7 p) N" _
  9. {undefined# q  Q- n( _& ]( S  q1 p( }  |+ O

  10. / J! n  h" z9 z7 J$ @+ p/ e
  11. PData=" q* L8 o9 `1 t3 _- O9 j

  12. : u8 F  e7 @9 A& v7 z
  13. (uint16_t )(2000*(sin((Tpai/200)*i))+2000);7 H" {& E$ y7 \: }. V. R
  14. * N6 C# X, C5 P
  15. } //prepare data for DAC
      h+ @* x: n0 |" T2 O% B

  16. 8 G0 J: S6 ^4 }( H  M( e5 N  J8 e" L
  17. SET_BIT(hdac1.Instance->CR,DAC_CR_DMAEN1);8 [3 @, K* j3 O9 f& o: _3 ^
  18. ; ~8 x2 z! ^+ u/ y4 Z! y1 ?' y4 X

  19. - }; |9 G/ [; H, `$ N/ P4 U6 |
  20. - i' B% r. g0 Y3 Z. B
  21. HAL_DAC_Start(&hdac1,DAC_CHANNEL_1 );
    ) Z& a7 W$ k& h' d. v. \1 _
  22. # P2 C1 Z1 U1 j- E7 b- X& {% z
  23. HAL_Delay(2);
    & P1 c& W* e. B
  24. ) u( q$ G0 V8 \9 [9 \# Z
  25. " t& T7 y6 c0 z# V5 j- R, Q

  26. * X# [  [3 B2 ~% m
  27. HAL_DMA_Start_IT(&hdma_dac1_ch1,(uint32_t)&PData[0],(uint32_t)&DAC1->DHR12R1, 200);2 Z5 g. d0 c6 a7 ]% q& y, B7 r

  28. 7 R' y  Z7 {1 n7 ^8 V, U, \

  29. 3 C; _. S1 r5 ?+ H' ?# L; G; V
  30. 1 s  J* u8 `, {4 d0 o* s
  31. __HAL_TIM_ENABLE(&htim3);
复制代码
( X: X& ]6 P0 f! _

* n' j& D1 E# g& Z6 x8 @; H( z& S9 O3 y5 N
" F! j; F* s" Z/ |' o. L" k
第一种方式就介绍到这里,再来看看第二种实现方式,即TIMER更新事件作为DMA请求源,同时作为DAC转换触发源。/ t* \: C; Y9 P( x7 v! ^
( H% o2 Q  t. [1 I- V
基于CubeMx配置,主要调整下DMA配置,其它配置基本不动。
8 G) G, O4 L& H) B) o
! i8 u  h% E/ E/ p, k
0 h: |4 w6 @/ |; j
, [, P, A6 s* l% |
( P- B( x+ P; G; J" ?0 E
主要是DMA请求事件变了,其它配置跟第一种模式基本一样。
/ f1 R9 w/ b' o( L
" M3 Q- B% t0 K# g0 Q  W; S: {配置完成后生成初始化代码,再添加下面用户代码:
7 M& j- N+ I- R# M% ~7 X1 v5 H7 g* F' L) k. m+ B
  1. #define   Tpai     (2*3.14159)) |& t. i! ?! s  [- P

  2. 2 ~/ X8 U" n$ Z# h
  3. uint16_t PData[200], Dac_data;
    9 O" d) Y" _% b5 _
  4. # f$ ?+ a# b3 V6 I" g
  5. uint16_t     i;
    . {6 s5 s2 F: k, z! W7 \) U+ D" k3 z
  6. + |' i- O8 O2 J! @
  7. for (i=0;i<200;i++)
    1 _8 p3 |7 q" A3 K) I9 |. h8 E! Q

  8. " ^, ^0 [5 f5 r) E
  9. {undefined
    4 |( O5 N* @) G% m7 X, x$ ?/ X
  10. ( M1 ^( r+ ~' b6 i( Z
  11. PData=9 Y1 }& ?6 n+ H  V. n
  12. $ r4 l# a5 E$ F8 k
  13. (uint16_t )(2000*(sin((Tpai/200)*i))+2000);5 c8 ~% D( S) P, p

  14. 0 N8 \, u6 n) Z$ f
  15. }
    ! e7 H. N. t# d& X% I
  16. - A& E5 h5 g8 `
  17. HAL_DAC_Start(&hdac1,DAC_CHANNEL_1 );  @8 u: q& T5 t3 u+ b4 {' _
  18. & K6 m& R% p4 R
  19. HAL_Delay(3);
    . H' ^0 V; k+ M' |8 b$ d! M/ c5 E

  20.   j* x9 z; b9 R8 N4 a9 z

  21. 2 a) E, x2 \' p7 L8 c! Z6 k
  22. ( l/ y, i" M2 x# H; S
  23. HAL_DMA_Start(&hdma_tim3_up,(uint32_t)&PData[0],(uint32_t)&DAC1->DHR12R1, 200);
    % J; I- w3 x; ~- ~

  24. 1 }; S- D5 C# S! m
  25. - d& O5 o& s" e& G) ^

  26. & |+ @8 Y$ i3 r& I1 e) g) m' J
  27. __HAL_TIM_ENABLE_DMA(&htim3, TIM_DMA_UPDATE);
    8 }6 Q: z/ ^4 e) @& l

  28. , }  \( x6 W3 n6 A3 e- e$ _3 u
  29. __HAL_TIM_ENABLE(&htim3);
复制代码

* y) D0 P& e5 x* G* S7 C4 @( I% o. A4 o3 o
这里要提醒一点,G4系列的DAC1的数据保持寄存器可以一次放2个通道的数据,在使用DMA传输时,即使只用到1个通道,DMA对它的访问也要遵循WORD对齐,不然你可能会遇到麻烦。# {5 X& |; W  n

& J8 Z4 D" p, I) q如果说,我们不使用DMA做数据传输,只是手动给DAC喂数据,那如何实现上述效果呢?这时我们可以使用软件触发DAC的传输,手动给DAC的数据保持寄存器赋值,参考配置及实现代码如下:
4 h' v9 o1 a+ l" G" [0 Q+ f% _4 `
1 [! ?  u3 _  s- Y* {
81958bbf0c7325cd86a0ecbf4dc138ef.png
: H: u' E6 E1 J

( y0 c% b" F  k5 w% a
, n; O$ B2 m# D相关用户代码如下:
' j2 A7 m* C" B7 B% n$ k' B5 T! a+ R7 ?, `
  1. #define   Tpai (2*3.14159)
    $ p* i0 J+ L; C: p7 J% _; C9 J
  2. ) s  z- W' K( Q9 a- V; |+ K0 C/ w
  3. uint16_t PData[200],Dac_data;  K+ A: A! d8 T% g! R. u  H
  4. , @8 H7 D! U& Z+ X2 c% q8 ]7 A
  5. uint16_t     i;
    ' ?) Y% V, i2 H9 u. J2 u  @

  6. + H3 e  a* Y- r4 {+ n( l& S
  7. for (i=0;i<200;i++)- w1 }2 T3 p3 l

  8. ( ?3 @1 l0 z( ^% o$ W
  9. {undefined0 q+ l. _1 h: G( D$ T

  10. , h' j1 }* q4 Z& c, J! `
  11. PData<span style="font-style: italic;"><span style="font-style: normal;">=
    8 J, l: c; N  i, l
  12. 1 S# R6 |6 ]/ h
  13. (uint16_t)(2000*(sin((Tpai/200)*i))+2000);( E6 o. S% j5 r( u! F: F
  14. / T/ Z6 m0 a3 H) C5 m
  15. }
    * n' e' O7 R' t

  16. , c( b/ k0 o) b& u' c7 o* ~
  17. HAL_DAC_Start(&hdac1,DAC_CHANNEL_1 );
    7 k; `# s( L6 e6 {* k1 w  ?
  18. - E7 `7 M; ]) R& s( `0 n
  19.    HAL_Delay(3);6 k! ]% ~- T5 I2 f0 Q

  20. 0 n1 }, u7 m. Q( \8 @
  21.   `* _$ f" l9 y3 r* e1 y

  22. * y/ Y* `7 g4 a
  23. while(1)
    ! S: w5 g" }& [7 N
  24. , e& F3 E4 V0 E9 o2 N4 k7 ^- T
  25. {undefined6 z+ p5 r; k' T$ ^  `

  26. 5 v/ f& R# |1 E0 W
  27. for(i=0;i<200;i++)
    2 |4 p& J* V" Z0 M" k6 N5 h7 c# |

  28. 8 j3 O2 J( N, P6 X; Z3 }5 F0 z
  29. {undefined
    5 I7 A1 T/ `& v$ n' I9 |; V  R4 `
  30. , T* Y- _' T/ v- b5 P
  31. DAC1->DHR12R1= PData</span><span style="font-style: normal;">;   ?; f$ S; _; C, L# x0 {3 Z; E0 I

  32. ; x) ^' Q/ I( U" w
  33. SET_BIT(hdac1.Instance->SWTRIGR,DAC_SWTRIGR_SWTRIG1);
    % t) I3 D9 m; {: P) h

  34. " ?+ M1 M5 ~& b- R
  35.       HAL_Delay(5);
    2 w$ p+ b2 ?' y* M2 g

  36. : {4 u4 C3 A' b: `4 \7 O0 t
  37. % b% R7 H& ^0 j2 M/ n

  38. 6 D5 [- B% ^$ [
  39. Dac_data = DAC1->DOR1;//for debug
    8 a! d8 `8 S( g+ h

  40. - w6 d( ^0 S/ [
  41. # `# n( T3 X- q% ]
  42. : t. J9 c1 t: h' U6 x  T
  43. }
    ! Q& Q5 A  l/ v2 s* B6 K
  44. . G& V4 R3 M- a* w
  45. }; }- w5 G# l4 N+ r: _5 m
  46. </span></span>
复制代码
& K. a. ~/ C% i' ^# M) S6 E$ F
总之,不论使用哪种方式,都可以实现我们所期望的结果,即输出如下正弦波。
' q5 S# C6 j4 z- @( O' K+ G/ T. \3 j, ^3 U. E) J% i8 |+ _
692bd68b1c31d5aa2a4b73541244f56e.png
' G; W2 E( o1 T1 O  z( T$ h
. I& N" v/ |/ O6 D: F. n4 G# c1 |1 _
好,关于STM32G4的DAC应用就简单介绍到这里,STM32G4系列的模拟外设丰富而强大,此处算是抛砖引玉。这里做些分享也是为了让其他有需要的人少走弯路,加速开发进程。【文中代码都很简短、直观,就没做注释说明了。还有个客观原因就是在微信公众号里排版也很费劲,字符不太好对齐。若有需要交流的可以后台留言。】
' a9 t3 q0 c& _% X% u
2 ~9 ~9 _" g6 e  {9 Z' L; w+ e/ Q; B& g9 v0 j
79bba335bff508c4f57300f0f57049de.png
赞 收藏 评论0 发布时间:2021-12-8 22:00

举报

0个回答

所属标签

相似技术帖

官网相关资源

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