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

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

[复制链接]
STMCU小助手 发布时间:2021-12-8 22:00
有人使用STM32G431芯片做DAC应用,具体来说就是通过DMA将数据从指定内存传送给DAC数据寄存器,并由定时器触发DAC转换。他发现总是没法实现该功能。这里简单介绍下相关实现过程,并做些提醒。这里要演示的基本功能就是让DAM将内存数据周期性传输给DAC数据寄存器,最后输出一路正弦波。
/ ^% X4 [+ A' G3 ]
2 r; A5 C* y& L9 Y) F, ~
8c8aec0947a9e081baa317138ac945de.png

, w4 A( a" M) L' z, h' ^9 c2 y5 u9 [4 \4 D: O& u; X

8 A# {' Z" E" V' F& R结合STM32G4芯片的特性,这里可以有两种实现方式。
* `! D" G$ [7 k8 z" _  W: E0 T) Z8 Y# f9 {, I, c
第一种,DMA的请求来自于DAC1的转换事件。第二种,DMA的请求来自于定时器事件,下面用到的是定时器的更新事件。这里就两种实现方式的配置及相关用户代码简单介绍下,以供参考。
& t8 n* u7 G6 R' F
, [, I5 y3 K( K我们先看第一种方式,即DMA请求来自DAC转换事件,定时器3触发DAC的转换。4 A6 G- n6 P, [

1 k+ ]  I( |- w) R3 f" z: _使用CubeMx进行配置,主要配置如下:5 s+ K5 ^" w9 U+ S/ w
d1020b7d0f8f4894eb7b709ab4cbed6d.png
8 w) M4 i5 Y: ~4 X# @; i2 Z

2 h& N1 L9 l. E% e' P
' r+ |+ A8 p! ^8 _5 p
ddd67d8a4616146cdf0ec6419da513ec.png

, x$ P4 D, B# w& c6 B8 O0 h
" k" {  F+ W7 {6 ?( E9 w
0f1f5180cdc185196607e3ef27b9e215.png
0 f/ k; p$ n6 |. h
  k9 A5 @- k2 a9 n9 c
完成配置后生成初始代码,再添加下面代码即可验证测试:
3 K( ]& p& g8 ~% e; V$ l7 ?; K. \; i6 w# f9 X$ e
  1. #define   Tpai     (2*3.14159). ^6 u$ ~' u" U& j( }  P! z

  2. ; d# `  A3 R' p5 q
  3. uint32_t  PData[200],Dac_data;
    - u3 t0 |! G. K1 h! W" m. [& t

  4. + b  s& |+ R. I+ b- j& R
  5. uint16_t     i;
    ; T8 P* i* G# d7 m0 z9 l
  6. 9 D  C# i: m% t$ n, v3 i3 Z+ u
  7. for (i=0;i<200;i++)
    & \( F5 S, C7 k+ ?6 H" ^
  8. 5 @9 T* \4 l' {* {/ x7 p
  9. {undefined( u5 T( K  H  D* R

  10. ) v# U3 J, \) n: n6 o3 x& e
  11. PData<i>=</i>
    , I) ?0 @% g3 G9 a' E5 x2 Q
  12. $ b3 Y) h& s) H1 O% H: v& f
  13. (uint32_t ) (2000*(sin((Tpai/200)*i))+2000);0 L% z! O8 O# Z" A% F8 |
  14. : {: c& J# P4 \% q
  15. } //prepare data for DAC, H$ g) O% t8 g& m8 l! L2 F6 p
  16. 5 W" q- Q" W2 K" B( j6 s1 e
  17. HAL_DAC_Start_DMA(&hdac1,DAC_CHANNEL_1,(uint32_t*)&PData[0],  200,DAC_ALIGN_12B_R);
    8 g5 S/ \4 \, A. x6 K4 `. i6 D

  18. ) p$ I2 w: @: e8 H2 `% q- `
  19. __HAL_TIM_ENABLE(&htim3);
复制代码

$ l4 i1 _: g7 z0 @. i  \3 x# W6 r7 X; Q

8 w8 d5 u! z, g5 o上面配置的DMA传输方向是从内存到外设,目的和源的访问宽度都是32位WORD. 当然也可以是内存访问宽度为16位的半字,外设访问宽度为32位字。即DMA的配置像下面这样也是可以的。
+ D! M! o- Q7 _8 E# ^& U# _& ~- _: V9 R7 Y9 Z3 l% y, L
d1a3b9537ab66535982e8b0cb86d3bbc.png

1 c3 |% }: l2 z) {) `
: k" T; ]- Q9 p! Y2 @9 z其它配置不动,代码稍微改动和整理下即可。参见下面代码:' E3 C8 ^3 L" h# W7 S

0 y& {, s% R+ F! \* A( A
  1. Uint16_t  PData[200],Dac_data;, e! d7 @5 H& y
  2. 3 y, X% t4 m7 V- N, ?. p1 W7 Y
  3. #define   Tpai (2*3.14159)+ Y+ v2 E' d/ q1 Q5 I; {7 k" `
  4. ; V3 d: N/ N( n& P4 u0 W) y
  5. uint16_t     i;
    9 c$ J0 I7 _  R4 i' ]# \3 y
  6. 2 T% j3 n$ w' J2 j6 p# \
  7. for (i=0;i<200;i++)1 h: a0 O9 ?6 q6 R* U
  8. 7 }$ H+ t3 R/ y6 J: C( @
  9. {undefined6 ]4 K# ]5 O0 k. {
  10. % u) I4 W( h$ \0 r! K7 U
  11. PData=6 U3 O) `" Q$ h* W- u3 K
  12. - m6 h6 l0 W, u) `* g! y3 u) B
  13. (uint16_t )(2000*(sin((Tpai/200)*i))+2000);* Y3 @. X' Q/ Z% m9 N
  14. ( M4 I, U* r6 a% X
  15. } //prepare data for DAC* F( ^2 \) l9 x; z

  16. ; T7 I$ _/ T; Q, V3 v
  17. SET_BIT(hdac1.Instance->CR,DAC_CR_DMAEN1);3 M! }8 b6 m; B% j, p; D

  18. ( S: M& Z* t! u  c

  19. . B" a, ^7 \5 E5 J
  20. ; U2 F  Q* o4 b% ^  ?
  21. HAL_DAC_Start(&hdac1,DAC_CHANNEL_1 );
    ; `0 m$ N; t; l" I& W0 `4 e0 S
  22. & m$ Z6 {5 A( T% q/ q( F1 r' Q) p; A
  23. HAL_Delay(2);5 V- v2 m7 {6 Q# {: E) x, m
  24. & }: l$ h9 y- N3 k0 K) j* }1 E
  25. - d. X! \$ i. @0 ~
  26. - n$ e% I! {# Q( k5 T1 E. W6 w* s" Z
  27. HAL_DMA_Start_IT(&hdma_dac1_ch1,(uint32_t)&PData[0],(uint32_t)&DAC1->DHR12R1, 200);. U' k# k( a9 @+ J* C

  28. / J3 c7 b  ]; r/ H0 i

  29. % X1 K4 |$ _3 Y7 ^

  30. 5 R8 s9 ^/ G$ c. {$ W' i
  31. __HAL_TIM_ENABLE(&htim3);
复制代码
& \' b8 n3 t) g  S0 M# b2 D
1 F1 P0 u: A8 U) l

& q' p# Z& h* }& m- d. T1 D
$ R! z' M2 B. }1 |3 }) T第一种方式就介绍到这里,再来看看第二种实现方式,即TIMER更新事件作为DMA请求源,同时作为DAC转换触发源。! a) V5 g, A6 `: y; m3 D8 S
" {$ c' L& F- j9 S  t
基于CubeMx配置,主要调整下DMA配置,其它配置基本不动。8 C5 i- J. p6 t- @

: }% O1 M$ w  r- V) `
3 y. t" y( x' a5 L. `( f

7 Y. W# Q+ s( {4 m: d2 \* o$ S/ p- J
& J$ x  Y  N) G0 ^: j( V: P主要是DMA请求事件变了,其它配置跟第一种模式基本一样。  V. L1 |$ Q! Y

* M7 Y& W/ W' ~4 n: l% ?% J配置完成后生成初始化代码,再添加下面用户代码:
1 F# W9 Z( {6 t/ C4 ~
: v0 ]3 v& ~2 K0 d
  1. #define   Tpai     (2*3.14159)
    ' Q, W6 l; t2 G" m

  2. + S6 Z4 J+ ~' B+ R
  3. uint16_t PData[200], Dac_data;
    * i$ g/ d! `; f. M
  4. " f- R3 @2 T* k+ c! O
  5. uint16_t     i;, M3 Z) K& B4 O+ n% n; X. J

  6. ) ~! t: B1 Z* l7 M
  7. for (i=0;i<200;i++)8 [! E% i$ t/ h9 I* W
  8. & _0 ~9 f3 U: {, ]3 X4 X3 d
  9. {undefined- w' i/ }* J4 ], {
  10. $ y# ^! a# s& q% G) i
  11. PData=$ q2 z$ K- z- y/ U  q
  12. : i3 B& o- a# z+ O3 o5 @! F
  13. (uint16_t )(2000*(sin((Tpai/200)*i))+2000);
    . Q( g; z" s- o& w4 ?9 P
  14. " a/ h0 a. Y) W0 @' x7 ~
  15. }6 j" K' y2 H2 f$ K2 B
  16. : w6 F4 P+ E$ M6 ?) \2 ?- T+ |
  17. HAL_DAC_Start(&hdac1,DAC_CHANNEL_1 );
    6 [7 J8 ]1 @/ [% z9 p
  18. % _. r' Z7 J8 M2 X
  19. HAL_Delay(3);1 _6 a/ j# O4 I

  20. , T1 v. M: f' ]! P* l* S, ^: ^' K
  21. / U: D; Y0 E9 l0 q8 K9 A
  22. 6 G0 o. d  v4 K! \9 q
  23. HAL_DMA_Start(&hdma_tim3_up,(uint32_t)&PData[0],(uint32_t)&DAC1->DHR12R1, 200);
    7 U% w; ~2 w# j3 s- a

  24. ! L3 Q& j# ~+ F, [, ^  Y) h! ~

  25. 8 o+ E. N' [. B

  26. * t" G- c  l' Q' u9 t' q! j
  27. __HAL_TIM_ENABLE_DMA(&htim3, TIM_DMA_UPDATE);1 K* P# c  @% k* k% J' H

  28. # y; u7 n& x( f$ w
  29. __HAL_TIM_ENABLE(&htim3);
复制代码
2 N/ U. _" G6 ^9 ]

2 X, }- C& T. b& u7 G, q3 w这里要提醒一点,G4系列的DAC1的数据保持寄存器可以一次放2个通道的数据,在使用DMA传输时,即使只用到1个通道,DMA对它的访问也要遵循WORD对齐,不然你可能会遇到麻烦。
) @. V- |- U1 G% p2 i' D4 s+ _: n
如果说,我们不使用DMA做数据传输,只是手动给DAC喂数据,那如何实现上述效果呢?这时我们可以使用软件触发DAC的传输,手动给DAC的数据保持寄存器赋值,参考配置及实现代码如下:* l. Y' I( P4 l6 A& G7 |
5 N; d8 n' K% ~  M8 A; J- H$ U
81958bbf0c7325cd86a0ecbf4dc138ef.png
( ~$ Z" M8 Z; }

( G! j7 p1 V$ B" y% F* R9 ~2 R! k( e2 k
相关用户代码如下:
2 o# m) a2 S. L( ?
" X. p+ A1 F$ }( X
  1. #define   Tpai (2*3.14159)
    + a3 A' Q9 F4 ]4 c: Q2 @2 R$ _. r
  2. ! A7 b1 M7 g: k3 k% i
  3. uint16_t PData[200],Dac_data;
    / f) J1 Y) W9 j) q) Y

  4. ( F, v" A: N8 z9 ~7 Z4 q7 y
  5. uint16_t     i;7 L% M6 j5 u+ N: c0 |

  6. 2 Y8 q5 C! B- q7 l  U# O
  7. for (i=0;i<200;i++)5 B; m# K, \: r0 w

  8. 3 W2 \7 M- Z) s* E
  9. {undefined( s$ j, A7 B: F1 c0 m5 x

  10. " s/ n, Y5 T3 I7 l; `
  11. PData<span style="font-style: italic;"><span style="font-style: normal;">=
    $ `! d8 R5 m( T, d; f1 _& l# Z

  12. 0 G# k7 C3 D7 l" i
  13. (uint16_t)(2000*(sin((Tpai/200)*i))+2000);
    8 ?/ `8 r6 ~" [) F- R- @7 n1 i

  14.   B3 V6 R7 N0 a, c; B
  15. }" K+ y0 [! _0 `5 B& V) Y6 X3 P
  16. 4 c; A* ^; W' B/ V0 _# q6 x9 `4 F( ?
  17. HAL_DAC_Start(&hdac1,DAC_CHANNEL_1 );, J. x  `0 G+ {

  18. , Y9 s, `. `' V) P( @) E) I
  19.    HAL_Delay(3);! x7 r. v0 M9 a6 `9 _$ M
  20. ; I0 S2 J/ [5 c# B5 F" i' v

  21. ( d3 |: Z- s  _4 B8 O! _" ^7 G
  22. # g$ e* q& F! P; ]8 N
  23. while(1), o) ]2 a8 p& b) |

  24. # b% z- @+ z" h* y
  25. {undefined
    . ^3 I0 v) f9 ], \8 _* `0 o
  26. ) R% z8 v& P" B3 ?
  27. for(i=0;i<200;i++)
    8 }& J5 L0 M5 W9 c( X2 M
  28. 7 _0 @0 M% Q' B; J( J/ ?9 G
  29. {undefined) V) j& ^: B# W1 f+ S3 z
  30. + H9 M7 P( s+ Q$ G
  31. DAC1->DHR12R1= PData</span><span style="font-style: normal;">;
    - Y2 [7 z; |+ P" m/ n: W) b

  32. * y& a( H; Z$ L: _
  33. SET_BIT(hdac1.Instance->SWTRIGR,DAC_SWTRIGR_SWTRIG1);( ?* e% ?/ M& @: h2 j1 x3 k
  34. : k3 D6 W: e$ J( M" W# Y1 P
  35.       HAL_Delay(5);- ]% y7 H8 Q4 X$ V& \2 N# B! p

  36. 6 Q) \! I5 K$ L
  37. & N3 @& t: ?( y" F! M# R9 y
  38. , o& [# }/ _- W' m% o6 I
  39. Dac_data = DAC1->DOR1;//for debug( c' D  p# P+ ~+ n% d! f

  40. / ]' m4 S1 _  s) b# n+ `

  41. 9 ~: T! n! A" r; A8 t
  42. ! \+ p1 u9 a1 ]) m5 G, e
  43. } 6 a* ]( _' u) N; g+ i
  44. " X1 a, @( {$ f* G, _* B3 U+ _
  45. }$ ]$ I- O% C" D% Q; C
  46. </span></span>
复制代码

- R7 f, |) b: ]# P" P总之,不论使用哪种方式,都可以实现我们所期望的结果,即输出如下正弦波。/ W/ O* b/ m& I1 k& D0 ~, |7 a
  [6 I0 Q  K0 q  I: ]; K% l3 o' |; S! Z
692bd68b1c31d5aa2a4b73541244f56e.png
! q& l0 R: v5 P1 k; j

! L' p2 z9 G& z( p2 q% Q好,关于STM32G4的DAC应用就简单介绍到这里,STM32G4系列的模拟外设丰富而强大,此处算是抛砖引玉。这里做些分享也是为了让其他有需要的人少走弯路,加速开发进程。【文中代码都很简短、直观,就没做注释说明了。还有个客观原因就是在微信公众号里排版也很费劲,字符不太好对齐。若有需要交流的可以后台留言。】
$ K; v% e2 U9 E) Z) p5 v+ j0 i" c. N6 e
  U3 Y' K$ s; c  Q
79bba335bff508c4f57300f0f57049de.png
收藏 评论0 发布时间:2021-12-8 22:00

举报

0个回答

所属标签

相似技术帖

官网相关资源

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