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

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

[复制链接]
STMCU小助手 发布时间:2021-12-8 22:00
有人使用STM32G431芯片做DAC应用,具体来说就是通过DMA将数据从指定内存传送给DAC数据寄存器,并由定时器触发DAC转换。他发现总是没法实现该功能。这里简单介绍下相关实现过程,并做些提醒。这里要演示的基本功能就是让DAM将内存数据周期性传输给DAC数据寄存器,最后输出一路正弦波。
7 M0 G  R3 _8 b) t2 U4 D( z+ x# m2 @5 Z" m. [4 C
8c8aec0947a9e081baa317138ac945de.png
- ?- p) ]9 P6 y9 K
# Q7 y* I- R: a$ o
' J' o% L* X( e, }
结合STM32G4芯片的特性,这里可以有两种实现方式。
4 }4 \4 o( a. t! Q0 l3 q8 T# b1 b) y7 M1 E* i) W$ Q
第一种,DMA的请求来自于DAC1的转换事件。第二种,DMA的请求来自于定时器事件,下面用到的是定时器的更新事件。这里就两种实现方式的配置及相关用户代码简单介绍下,以供参考。: j. M: A: I& q$ y& I) f
3 O5 G& j9 J7 k  e% j- p6 e
我们先看第一种方式,即DMA请求来自DAC转换事件,定时器3触发DAC的转换。( c. d1 U7 j; k' @* A/ N. c1 @
! c8 l. C) Y* `6 e/ e. o% h+ k
使用CubeMx进行配置,主要配置如下:: O) p' s3 T" i2 L$ ]
d1020b7d0f8f4894eb7b709ab4cbed6d.png

: e7 T1 A: m4 Z" b, R8 k9 v9 L( ?& S% s' C# N7 ^$ q5 {, v0 Z

  P) o' W0 I. S/ H* ^# c; X" l
ddd67d8a4616146cdf0ec6419da513ec.png

. [0 I  w7 {6 e( T6 E8 z: _0 H! N- f$ M: ~3 `) t
0f1f5180cdc185196607e3ef27b9e215.png
( I& `0 {3 ]* `' J

" E* n, h" p3 y. w/ U% C6 l1 p完成配置后生成初始代码,再添加下面代码即可验证测试:& r# u) t; P/ q; G: B
/ A; q) u; r* \
  1. #define   Tpai     (2*3.14159)
    3 Q- l0 N% U8 @
  2. : J! p% A% O+ `5 z* u- q+ ~" y
  3. uint32_t  PData[200],Dac_data;
    # Y6 E# g: O+ q/ t3 M0 o; Z1 \' `
  4. / z! q8 ^: P. s" l2 k: y4 P
  5. uint16_t     i;
    + C; N# T2 e* X& Q8 o& b- Q2 t5 d8 b0 I

  6. 1 g/ y8 @& @2 K: T' Y
  7. for (i=0;i<200;i++)* u8 n) h) V6 F5 P4 `8 M- G

  8. 2 S; z9 F: G5 n3 G: B4 t9 H1 u
  9. {undefined
    ! X( l" }7 j5 o  y, Z' Q
  10. # ?( c1 L6 Q+ Q
  11. PData<i>=</i>
    : T( P+ E; o1 Z& K0 T. N

  12. ( B. q) d, f$ P8 R2 N
  13. (uint32_t ) (2000*(sin((Tpai/200)*i))+2000);; A; u2 G* M& D2 D  i5 c' z
  14. 7 R" _: l3 q/ p7 F5 s
  15. } //prepare data for DAC# f" P; F9 s1 ~& {6 h' X
  16. ; [, c' A8 O. n9 P  [
  17. HAL_DAC_Start_DMA(&hdac1,DAC_CHANNEL_1,(uint32_t*)&PData[0],  200,DAC_ALIGN_12B_R);' L+ L: |# G" {1 u
  18. 9 K, H9 k2 \) |( T/ H
  19. __HAL_TIM_ENABLE(&htim3);
复制代码
6 ?  ?2 e$ \+ [( i1 i2 l  n
0 x" }/ x( v1 D/ b. S

4 B3 A# R( |4 f. r' ^上面配置的DMA传输方向是从内存到外设,目的和源的访问宽度都是32位WORD. 当然也可以是内存访问宽度为16位的半字,外设访问宽度为32位字。即DMA的配置像下面这样也是可以的。) d) J+ P) v" V% b# v5 k5 z/ J7 s" d' R

  u' p% ^* ?6 z: y
d1a3b9537ab66535982e8b0cb86d3bbc.png

2 x2 O3 s4 y' M3 A$ E. s% h5 f6 x: i6 K' Z6 w4 v' h/ Y* D$ V+ Z
其它配置不动,代码稍微改动和整理下即可。参见下面代码:
+ V. J/ V3 ]. r5 G2 ?& {' }" u8 P) F- t' k9 g- j  t
  1. Uint16_t  PData[200],Dac_data;
    5 w$ d$ K/ L0 x% {
  2. " q) X- E6 r' l9 r. a# w) J
  3. #define   Tpai (2*3.14159)( y/ N, l9 d8 C$ a( R
  4. " Q* E: c9 k4 @2 N/ P
  5. uint16_t     i;
    7 p/ F; R# u/ J% d
  6. & b1 R3 n! \% t& e8 v
  7. for (i=0;i<200;i++)
    6 Q, L3 z* g. F- C3 C
  8. / A2 ?/ n9 w% I0 x* N( |% c
  9. {undefined3 `: ~& f2 m8 y9 }: \; z6 q. U% K
  10. # d8 \% H3 h: I
  11. PData=8 c' ^9 c) k8 V: m$ ?8 q( \( o
  12. & w, N! z9 w0 e6 ^* H& s
  13. (uint16_t )(2000*(sin((Tpai/200)*i))+2000);
    * _. J! @3 k* j. |# S4 M

  14. . m) e: C) ]/ w1 i
  15. } //prepare data for DAC
    6 N2 B; i6 }* u" p1 l
  16. $ n5 X& Y0 ~0 t2 D
  17. SET_BIT(hdac1.Instance->CR,DAC_CR_DMAEN1);$ c3 |( Z8 T8 [" Y9 ]2 z2 Z5 P, e; v

  18. & b# L, `: P3 U# a9 t- R5 z

  19. 2 H5 I9 a: ?' q# x! F8 ~

  20. 3 N+ N8 h- m9 o( ]0 d* [! o
  21. HAL_DAC_Start(&hdac1,DAC_CHANNEL_1 );
    , I  q, Q" }3 H0 g0 b+ y& }
  22. & [) w# W% O9 L1 C! C! P
  23. HAL_Delay(2);7 z. _6 D" p% [# E5 H

  24. : y7 }! c. Q) @5 F1 I
  25. ) u$ f. y  ?* |- H; A! x  q

  26. ) Z& D0 s1 ^' O9 R% R' b% I
  27. HAL_DMA_Start_IT(&hdma_dac1_ch1,(uint32_t)&PData[0],(uint32_t)&DAC1->DHR12R1, 200);" J9 Y: r2 J3 U9 O9 l2 r! j

  28. 0 i1 F5 s! o/ W/ T& a* }

  29. 0 ]3 ]/ o5 H! ~8 M# v" b
  30. 6 P" I7 H' \% x" A
  31. __HAL_TIM_ENABLE(&htim3);
复制代码
' E' Y6 R( k4 N' a; ]( A
9 b: X1 M7 q5 r/ t" E
8 r  S  y2 L; }7 v7 L  f

$ ~: w0 Q( R3 q* i第一种方式就介绍到这里,再来看看第二种实现方式,即TIMER更新事件作为DMA请求源,同时作为DAC转换触发源。
) p7 ^6 o! `6 M0 C! O- z, t" ~0 ^3 r2 B2 U9 r) @7 h( V
基于CubeMx配置,主要调整下DMA配置,其它配置基本不动。7 ?* U/ L+ T7 i

5 T; ~" W( f' i
9 ^9 g! [  G0 R# n& y1 |# ]
& d& W! \! t2 B* O' _

; e, \* p1 X4 V- d' x7 p0 M! t主要是DMA请求事件变了,其它配置跟第一种模式基本一样。
# W( b& M4 }5 p7 Z
1 v, F: [' x; m& n6 h+ m配置完成后生成初始化代码,再添加下面用户代码:+ j3 x% u" F8 x" o* p. B1 B

! x4 l4 d& r; T5 _  E
  1. #define   Tpai     (2*3.14159)
    ) W+ x' H# Y7 F

  2. * C; P* t$ y! D0 s
  3. uint16_t PData[200], Dac_data;
    9 B/ v# n3 z) F; D$ {
  4. 0 ?1 m( d6 H- w" _: v2 U% H
  5. uint16_t     i;. ^4 Z: Q4 u# u, f# K8 t

  6. , k3 S  g. z# X9 |
  7. for (i=0;i<200;i++)
    / \) e# K# H9 a, ?  P' e5 m

  8. , @' T: b! k$ r3 _; i1 m, Q
  9. {undefined
    / Y& a9 ]* o/ a0 m: E- S9 n
  10. 2 t- v* a; J# I" o
  11. PData=! V+ y% b: Q$ [# G

  12. " O! W4 R/ F# b3 t2 U$ }
  13. (uint16_t )(2000*(sin((Tpai/200)*i))+2000);7 E! H; l5 j/ h- J4 o
  14. + L7 N- [. L0 ^3 F" r
  15. }- R- ^: m$ e- S2 F0 ^7 w$ {

  16. - A' @5 u% S( S4 ~
  17. HAL_DAC_Start(&hdac1,DAC_CHANNEL_1 );* w4 ~4 p  h  Z4 Y* K- j  m! b

  18. . P% G, G( n8 ?5 P# ]
  19. HAL_Delay(3);
    + W+ l( P  e& i3 y

  20. 6 g# Q4 y. b/ u% B# S
  21. 8 v& }6 C# V, F' O" w6 |

  22. 2 Z- ^# o2 e6 B. r9 f' |8 {
  23. HAL_DMA_Start(&hdma_tim3_up,(uint32_t)&PData[0],(uint32_t)&DAC1->DHR12R1, 200);
    # r# T2 U# X, ]1 H/ i) A  x! s
  24. 2 R* }$ q. l2 k9 @: `$ t0 M
  25. 5 A. i' p$ l3 j2 Y) |

  26. 0 c% `9 O: d; I% J' s
  27. __HAL_TIM_ENABLE_DMA(&htim3, TIM_DMA_UPDATE);- A4 [3 \2 j. q) b/ K% t

  28. ' T; R. y  N) ?* E* ~% O( }
  29. __HAL_TIM_ENABLE(&htim3);
复制代码
& e, {$ W% p6 J3 g

2 Q( G6 @' ?: o! @  m7 Z这里要提醒一点,G4系列的DAC1的数据保持寄存器可以一次放2个通道的数据,在使用DMA传输时,即使只用到1个通道,DMA对它的访问也要遵循WORD对齐,不然你可能会遇到麻烦。
4 I' y* r. M9 @
6 D" L' g4 v  h; h) ~1 m如果说,我们不使用DMA做数据传输,只是手动给DAC喂数据,那如何实现上述效果呢?这时我们可以使用软件触发DAC的传输,手动给DAC的数据保持寄存器赋值,参考配置及实现代码如下:  Z% V1 T; F- A% A' E8 t  Z

+ |, G2 z# I3 p; ]- `* h
81958bbf0c7325cd86a0ecbf4dc138ef.png

# v/ _, f& D, q. u( I
% ?! `3 I# F7 W- @! J/ x
! s4 J2 c. d# |5 l9 b. P相关用户代码如下: . Z* `4 Z6 ]! ]3 Z( I. [9 J9 }
' N2 Q+ }5 E& y  Z9 D. K/ K
  1. #define   Tpai (2*3.14159)
    % e% e  {$ m) z# M" j. c
  2. # {! k0 O% w& N
  3. uint16_t PData[200],Dac_data;% M2 k1 ^8 j1 X/ v( f9 ~

  4. " Q$ q9 ?* r# {7 h& H
  5. uint16_t     i;
    ) O8 ?( X; b$ \, g5 _

  6. 1 R9 I! }  H1 O% J0 g
  7. for (i=0;i<200;i++)
    - Y- I7 e8 g5 S  U  X$ x) }
  8. 2 c  ^- k$ Q* d: Q+ E* v1 S
  9. {undefined4 C# u4 n1 S2 l' F/ `; o

  10. / t; x- O5 n% S  @5 C
  11. PData<span style="font-style: italic;"><span style="font-style: normal;">=, f  p, }2 Z) e* D' I

  12. 0 |2 u* I9 B# c6 n6 M
  13. (uint16_t)(2000*(sin((Tpai/200)*i))+2000);
    1 ]0 \6 U* g% ?" w: v9 K
  14. - |( X$ p# G( Z* X! P8 \
  15. }+ b' T, S! `  [  W+ D) t/ u

  16. * b- q% g% `: V: K, x4 S- M
  17. HAL_DAC_Start(&hdac1,DAC_CHANNEL_1 );
    ' ?* `4 C3 S% J6 L5 Z

  18. 3 I% ]* s% g& n3 ~/ R
  19.    HAL_Delay(3);$ T9 C8 N$ a" R: Q) @5 M
  20. # M  F: p1 M( S) {5 E, [

  21. & K9 C7 K5 W8 e: x0 {- H' }9 e2 B2 B

  22. ) n+ ~( R, q+ d" N9 b. X% z5 l
  23. while(1)* ^+ M+ O7 @( Y$ l# A: c

  24. ! |. b0 M. z1 I8 k  C( a7 m
  25. {undefined0 C1 r8 J6 x4 D* s, v! h6 I
  26. $ X: }6 h; _. ]1 {3 \3 q
  27. for(i=0;i<200;i++)$ F. L& {6 c: n; p0 c( w

  28. 5 P! Z/ y5 c; k; d& i" M( W
  29. {undefined
    3 J3 W9 o0 [- }$ k& [
  30. 1 C2 u4 L4 t! U# ?! O" Y6 I+ @
  31. DAC1->DHR12R1= PData</span><span style="font-style: normal;">;   z4 f8 z" i' U& B% A7 Y. N9 p
  32. , \) [" r* n" Y1 W; F
  33. SET_BIT(hdac1.Instance->SWTRIGR,DAC_SWTRIGR_SWTRIG1);# ?% d, w0 l$ {% A. X, o0 d

  34. 9 C+ |+ X5 y$ f: `% S
  35.       HAL_Delay(5);% E3 t! n0 g: r; V% @: G" ?! Q8 ~
  36. + r  Q# K  x" ^4 y" ^

  37. ; z6 ~4 ]  z, \( J* H

  38. & f8 ~" v* o2 ^4 f
  39. Dac_data = DAC1->DOR1;//for debug
    / s" T  i, c2 r9 {" u) _' Q/ R

  40. 4 k( l: C; z4 U$ x4 Y1 J
  41. % d/ r- x: {; q% Q# s0 \$ V) M4 L0 H  |+ V
  42. ' j* k( Y) R5 ?2 ~% ]/ T5 \! ?. }
  43. } 3 K# S$ j7 \. c6 ?
  44. 9 k0 T: s9 i6 N! ^% M
  45. }
    4 B/ K  a! |- Q2 t( V+ D$ T
  46. </span></span>
复制代码

$ R: M" }( v8 e0 K5 c& Y( u总之,不论使用哪种方式,都可以实现我们所期望的结果,即输出如下正弦波。- `8 p1 o. _6 D8 A! _  v
1 b6 K* v8 y# o" B6 V2 ~$ n" {# q
692bd68b1c31d5aa2a4b73541244f56e.png

' A9 s5 s1 e0 Z$ E2 n6 r: ]7 W& y5 a: o; K  y9 o2 i
好,关于STM32G4的DAC应用就简单介绍到这里,STM32G4系列的模拟外设丰富而强大,此处算是抛砖引玉。这里做些分享也是为了让其他有需要的人少走弯路,加速开发进程。【文中代码都很简短、直观,就没做注释说明了。还有个客观原因就是在微信公众号里排版也很费劲,字符不太好对齐。若有需要交流的可以后台留言。】( E& O, s% ]1 x3 [. N

% s2 w7 K. Y- l/ H/ [+ ?
3 Q8 E3 T, l3 p( d7 _; i
79bba335bff508c4f57300f0f57049de.png
收藏 评论0 发布时间:2021-12-8 22:00

举报

0个回答

所属标签

相似分享

官网相关资源

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