请选择 进入手机版 | 继续访问电脑版

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

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

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

( s% y+ R% j% i& t
8c8aec0947a9e081baa317138ac945de.png

* V3 S! @4 Z5 |' @: f+ H" z6 {3 x8 `  w) _: h

# t" t- y4 I& N. O4 n结合STM32G4芯片的特性,这里可以有两种实现方式。, s7 W5 q* x0 q6 T+ ~, B% ~

5 E% ~2 E* P- A. u2 v第一种,DMA的请求来自于DAC1的转换事件。第二种,DMA的请求来自于定时器事件,下面用到的是定时器的更新事件。这里就两种实现方式的配置及相关用户代码简单介绍下,以供参考。
7 i- L" |' m- E$ ~
" c" l9 _& s. d/ x9 k. U, y我们先看第一种方式,即DMA请求来自DAC转换事件,定时器3触发DAC的转换。
. Y+ o! N. d3 G
( p! p1 d9 f/ H* U/ S, i& R使用CubeMx进行配置,主要配置如下:
7 y8 w2 Q$ u$ a0 W5 A' p( s3 {
d1020b7d0f8f4894eb7b709ab4cbed6d.png

& Z7 G, _8 n, w7 K1 Z* e" u
7 p4 M: E% B) e* u/ h
2 k/ @( A) Y2 h
ddd67d8a4616146cdf0ec6419da513ec.png

: g& y) G8 M% b# f7 |1 s- w* ^1 Z8 P& c# u& w9 z) l0 c
0f1f5180cdc185196607e3ef27b9e215.png

9 o' h# C. L: j* p) d
. k, P& f/ E3 Z+ G完成配置后生成初始代码,再添加下面代码即可验证测试:
* D* W" O6 g% z! B* c
: x0 o5 O2 g, n+ @% U5 B8 }
  1. #define   Tpai     (2*3.14159)1 O. x8 C' t, K( L/ R" t- U
  2. ( u0 E# D% n/ p
  3. uint32_t  PData[200],Dac_data;, j) \/ \( d. |# S6 Y6 n$ Q- m
  4. 8 n; f) K! C/ ]8 H2 x7 H# T* s
  5. uint16_t     i;, m0 B, R9 r5 @7 s/ t( o  c
  6. ( y- p' W. q1 m& l
  7. for (i=0;i<200;i++)" h* F4 M" |8 i& a) T( o

  8. ) g9 c8 J. r( Q! w0 ]7 w, V
  9. {undefined
    # n/ n- g4 j4 s7 a  I6 v2 t. c
  10. * i. o& ^3 P/ X" P7 g' @' I
  11. PData<i>=</i>0 S( ~8 i0 ^$ s, E2 G( B
  12. & B  x+ `% N" E% a
  13. (uint32_t ) (2000*(sin((Tpai/200)*i))+2000);1 F0 m( n6 J: R* n1 U
  14. ) q! X5 z1 M% E
  15. } //prepare data for DAC8 @0 N( u! G: t
  16. ; S- o& b  R9 B3 a3 |: F0 D
  17. HAL_DAC_Start_DMA(&hdac1,DAC_CHANNEL_1,(uint32_t*)&PData[0],  200,DAC_ALIGN_12B_R);$ A4 L) D* \/ ^1 O" ^0 }
  18. 7 m/ v3 I7 ^! H- t* q/ A
  19. __HAL_TIM_ENABLE(&htim3);
复制代码
" N7 k+ N4 M* |$ n" n, J, ~

" J; G; c. @* u3 n, F9 T* J/ V4 Q. \: `. a
上面配置的DMA传输方向是从内存到外设,目的和源的访问宽度都是32位WORD. 当然也可以是内存访问宽度为16位的半字,外设访问宽度为32位字。即DMA的配置像下面这样也是可以的。
! i3 W5 R  Q+ K
. p- [$ y/ _1 a  z
d1a3b9537ab66535982e8b0cb86d3bbc.png

- Y& N3 e5 V# G6 |) s$ y! G
* @: i# l0 ~: b  i其它配置不动,代码稍微改动和整理下即可。参见下面代码:% u5 z8 L, C0 P. W0 m# L

2 T8 c# t' J8 a3 i) [8 V- S) q
  1. Uint16_t  PData[200],Dac_data;
    8 P7 S7 n) N6 X- Y& j
  2. . z6 W" ?3 R; X: n- A* u
  3. #define   Tpai (2*3.14159)# q3 H# M, r6 s- u8 g
  4. - R$ n; V# G: B
  5. uint16_t     i;
    , Y2 n3 w: n$ ~" B3 E
  6. 7 B$ V: U  S+ E* \  R# U" z
  7. for (i=0;i<200;i++)  z# \* Z3 G3 P0 h
  8. 0 C' ^# U& J+ j' ~
  9. {undefined- D0 V$ [, `# D. i# i

  10. ( M. j# r5 q) v8 [  ?( p6 R, I
  11. PData=
    9 v* X$ @5 Z) O7 I+ D

  12. $ [4 X6 w! {6 x, @  e" _2 D, S) I! _
  13. (uint16_t )(2000*(sin((Tpai/200)*i))+2000);9 W* [+ [0 Q& p" @' Y" P

  14. , M5 \4 t" S4 [' U
  15. } //prepare data for DAC1 [4 E' O- ]; e9 P& x4 M

  16. 5 v- A# U" d# x8 w8 ?" E
  17. SET_BIT(hdac1.Instance->CR,DAC_CR_DMAEN1);' y5 w8 Z( s1 }2 l. y, \! A" o! S

  18. 0 U) _+ H8 W4 y! K$ I8 O/ O0 ?
  19.   D2 w7 K6 ?8 o3 k
  20.   K. q. N4 T2 X+ O' F- M
  21. HAL_DAC_Start(&hdac1,DAC_CHANNEL_1 );/ ]" D( [$ M1 `( E; F1 o1 L) f
  22. % y% u% J% j& t$ N  G. r& t
  23. HAL_Delay(2);3 q" i/ H; H7 }" q" U3 S$ i! ~
  24. / z9 e4 ]1 R4 A& M: V4 B; p( R

  25. : P/ ?  z/ [* C  c
  26. ( {7 Z$ c. X  Z* `
  27. HAL_DMA_Start_IT(&hdma_dac1_ch1,(uint32_t)&PData[0],(uint32_t)&DAC1->DHR12R1, 200);' S, ?6 q. m& o& K

  28. ; C5 {' h# P, Y4 |* L

  29.   s! _0 B* c$ C& a3 H5 ?4 U: k; s3 j. s

  30. 8 o/ X$ l3 {1 n
  31. __HAL_TIM_ENABLE(&htim3);
复制代码

# S" [4 g5 f4 X# w5 O! j; J+ H7 `  N4 x/ d1 P/ p" C: o5 z5 J2 t# s

) R0 ^/ O, |$ h# U1 B( v* a
- Y  L* C# n- K" [; ?2 E第一种方式就介绍到这里,再来看看第二种实现方式,即TIMER更新事件作为DMA请求源,同时作为DAC转换触发源。
' _  i1 j+ F$ x) h2 ^/ c! Y6 ?, S$ p3 R" c, \- ?
基于CubeMx配置,主要调整下DMA配置,其它配置基本不动。
& n. }% [( u9 h& I6 `( I! X$ d# T5 q! l0 k1 n. a

% p1 B  U% {% L6 ?
% C# v3 _* U" v% @$ R2 k9 j% f, I
  R- b* `! F0 R5 g主要是DMA请求事件变了,其它配置跟第一种模式基本一样。  e) A0 P3 H* b2 `! E* h! v% y
- i4 E  p+ k' g' n8 ?
配置完成后生成初始化代码,再添加下面用户代码:
. O+ d0 |3 k, c# O" X- J. J; f8 y6 P% i! Z- q5 j7 y* l% J: F
  1. #define   Tpai     (2*3.14159)
    1 Q5 I9 U7 h7 x6 d

  2. 9 P# f: w; P4 Z& Y: j- s8 H
  3. uint16_t PData[200], Dac_data;  ?0 M! y* A3 W9 e6 J1 ]
  4. $ r8 x8 i" ~$ e& a% @# H3 ?& y# l
  5. uint16_t     i;% o$ ~$ K/ r4 `$ t# V$ F* g
  6. " B/ n% \8 F. i
  7. for (i=0;i<200;i++)9 P# Z! J& a' M* R1 Q2 T4 [
  8. ( Y6 R0 u/ M- N  P; T# a
  9. {undefined
    3 ]. U; d# }5 q& U4 }  r0 }0 ?6 ?/ ?/ ^

  10. 0 Z3 R  C/ L) a8 ^  i7 |- N
  11. PData=" ^) V, @' H8 Q) d" n4 {

  12. 3 \) p' T# }  H! u
  13. (uint16_t )(2000*(sin((Tpai/200)*i))+2000);
    0 H' k( h3 L4 o

  14. + J0 v2 C6 {" G7 I
  15. }3 G1 _6 a  y/ y! I6 C

  16. 6 ]7 Y0 e: a: P" P
  17. HAL_DAC_Start(&hdac1,DAC_CHANNEL_1 );( Z2 V3 I3 A+ ~, t( Q' e8 U8 d" [
  18. 9 S4 C, C* M' [! ]/ z7 K. x* f
  19. HAL_Delay(3);0 a5 x8 p: x) m0 U2 n' c

  20. + z: I$ [: ^0 }0 ~' B
  21. 2 V3 s9 V3 q7 r
  22. $ j7 U, A: [  _' d0 R
  23. HAL_DMA_Start(&hdma_tim3_up,(uint32_t)&PData[0],(uint32_t)&DAC1->DHR12R1, 200);& e+ n/ L* d# ]$ @

  24. 6 x) r  I6 u7 j5 q2 d- L8 {) Y) u  `) |

  25. 7 U1 z% v, `- {* l

  26. # `4 O/ P5 _4 a4 w0 e5 s8 l
  27. __HAL_TIM_ENABLE_DMA(&htim3, TIM_DMA_UPDATE);! v# Y" ]8 D; t; K, h* C  x
  28. ) S7 T9 n! N% v5 j7 Z3 X0 h9 S
  29. __HAL_TIM_ENABLE(&htim3);
复制代码
4 H! w, ], B, H$ x

2 J, K& V7 d7 i3 n+ q7 X这里要提醒一点,G4系列的DAC1的数据保持寄存器可以一次放2个通道的数据,在使用DMA传输时,即使只用到1个通道,DMA对它的访问也要遵循WORD对齐,不然你可能会遇到麻烦。5 a" H7 ~4 x6 A" I, l7 q1 I
% g5 w. S) |; {% o
如果说,我们不使用DMA做数据传输,只是手动给DAC喂数据,那如何实现上述效果呢?这时我们可以使用软件触发DAC的传输,手动给DAC的数据保持寄存器赋值,参考配置及实现代码如下:7 b, y; M% {" [- O' z
6 p- J0 G+ E9 s& n* u
81958bbf0c7325cd86a0ecbf4dc138ef.png
- m. K, e6 n: Z7 W( {) C
3 X' i5 f. }$ ?5 t7 r* R! k

* r4 e, z! a# `+ \8 e相关用户代码如下: 9 Z3 v8 g) _3 T
. S* a1 f% l. _
  1. #define   Tpai (2*3.14159)
    7 F+ w# v8 B) i

  2. 4 b0 `5 X' L4 J. I% S4 f
  3. uint16_t PData[200],Dac_data;* W5 Y; u' c& q3 v" n
  4. / q' w. z( t- w  S/ _4 P$ }) M# t/ r
  5. uint16_t     i;2 a; @0 e0 t# m0 u
  6. 1 o5 r  b4 u0 H( A( q5 Z
  7. for (i=0;i<200;i++)
    , D- `6 g) Z% j

  8. 1 L1 Z$ y3 Y. ^& r' [0 {
  9. {undefined4 ]6 }/ w8 ?& V- u
  10. ' p' Q1 w% P+ [) L4 a" k
  11. PData<span style="font-style: italic;"><span style="font-style: normal;">=
    0 Q# ~( B/ L( T3 ]% _' p5 y

  12. 3 O6 Y% _- `/ ]
  13. (uint16_t)(2000*(sin((Tpai/200)*i))+2000);
    - @0 q, u2 \0 T( n* J

  14. 7 M" `/ c' q3 A3 R6 s4 j
  15. }* q# r: C- F% ]8 B
  16. . W( l- g1 {: ^. V
  17. HAL_DAC_Start(&hdac1,DAC_CHANNEL_1 );  @3 P* b. D5 u
  18. ' N% _+ m, Y% d
  19.    HAL_Delay(3);  j8 j; P9 N9 s- U

  20. 3 ~- X; g. F# X1 W  h: K7 y& ]! \

  21. ) u! g1 [! W) t* e/ m
  22. 9 w. |0 t3 |/ O3 W) J  V
  23. while(1). ^- h+ i1 i# v$ b

  24. " |7 d* y8 |5 w# x! Q7 m4 _
  25. {undefined
    * n  [  k9 x4 L& A- D7 t
  26. 4 B3 R' v: {; \9 O3 D; x& i" N
  27. for(i=0;i<200;i++)6 Y  \& Z6 ^& I* E

  28. ' M" {- P) e. X+ K0 o
  29. {undefined: g+ Q) {6 e* w* n( H+ m
  30. ' c# a* v; ]- m7 W( Q
  31. DAC1->DHR12R1= PData</span><span style="font-style: normal;">; 4 K2 M/ ?& J- G5 X7 z2 S  Z+ P

  32. 3 R) K  ^% j& J2 H# S- t( I. \! e) O! g
  33. SET_BIT(hdac1.Instance->SWTRIGR,DAC_SWTRIGR_SWTRIG1);% v2 D9 ^$ {* E, a
  34. ' y6 R7 t( @5 ]7 u$ I  S
  35.       HAL_Delay(5);5 F* W5 c3 x* y" R" _
  36. ; z* F' @5 U0 R8 z* l7 U
  37. 6 d; N* f0 a  J9 ~

  38. 9 ]3 k$ d6 k, L* @
  39. Dac_data = DAC1->DOR1;//for debug  c0 S3 K: Z! K" k8 e( _
  40. ) {! e, q* [+ p" i/ n! z, b# u8 Q1 f

  41. 7 W4 r4 v- s. u' Y

  42. 9 J; I0 {3 [2 Q1 J1 v' e6 \
  43. } 4 F( I3 Q- C* G: `1 ~3 v/ t
  44. : k/ l2 R0 H0 P9 G( Q; ^' l' n, {$ W
  45. }# t( a2 i/ V2 I! x1 s' a, L
  46. </span></span>
复制代码

3 b3 E5 N0 L* ~% N9 A1 Z总之,不论使用哪种方式,都可以实现我们所期望的结果,即输出如下正弦波。
9 ]1 c8 ]$ y% Z# Q
! R3 _; ?5 {( Z3 N0 ^& W, a6 @1 T
692bd68b1c31d5aa2a4b73541244f56e.png

4 {8 U$ s# K9 K. d! \7 X
( ]6 ~( f# Q7 p好,关于STM32G4的DAC应用就简单介绍到这里,STM32G4系列的模拟外设丰富而强大,此处算是抛砖引玉。这里做些分享也是为了让其他有需要的人少走弯路,加速开发进程。【文中代码都很简短、直观,就没做注释说明了。还有个客观原因就是在微信公众号里排版也很费劲,字符不太好对齐。若有需要交流的可以后台留言。】1 U" U! v4 F3 c
. W( \3 Z  Z* u5 z

, l/ }) t1 f; }8 A/ T+ A
79bba335bff508c4f57300f0f57049de.png
收藏 评论0 发布时间:2021-12-8 22:00

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版