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

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

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

$ P* i5 F8 v: z* U3 y
8c8aec0947a9e081baa317138ac945de.png
( f' z; H7 _, R+ y
/ I( |  k: v3 K" c, m5 J- ?* s
- I- _4 ^  x) M' J! v  [
结合STM32G4芯片的特性,这里可以有两种实现方式。& F& K) Q: ~1 [
  x  Q' f6 O) q- t/ x# U# I
第一种,DMA的请求来自于DAC1的转换事件。第二种,DMA的请求来自于定时器事件,下面用到的是定时器的更新事件。这里就两种实现方式的配置及相关用户代码简单介绍下,以供参考。
; f, P3 ~! S& S' x4 {9 q& P
7 v+ b1 V6 D; d4 p我们先看第一种方式,即DMA请求来自DAC转换事件,定时器3触发DAC的转换。
: J( F2 `$ @5 {1 c; v9 a" J
' D# o9 G2 L6 q% B6 @2 p使用CubeMx进行配置,主要配置如下:1 l# W4 L) y  q% }' n
d1020b7d0f8f4894eb7b709ab4cbed6d.png

- t1 z0 @& G$ Q$ U, m6 z6 H
$ u8 d" w. }: e& h. ]
" V# Z/ x: P, G
ddd67d8a4616146cdf0ec6419da513ec.png

4 B: Q! w9 N% \( t$ {) t& \0 f4 f6 H( i$ P; Q. a
0f1f5180cdc185196607e3ef27b9e215.png
" ^' h! H' w1 p- U6 d! R+ J

% i$ D. \+ P) {& B1 r+ K2 n完成配置后生成初始代码,再添加下面代码即可验证测试:8 X! m9 U9 P( x& ^( e9 p8 j

, Y# B! R" x& m: N4 e" I' @! h
  1. #define   Tpai     (2*3.14159)( `, K8 H" N- ~
  2.   C5 E. u/ Z  z3 u0 f( L% I
  3. uint32_t  PData[200],Dac_data;
    , Z, ?& y7 K1 I! V7 M
  4. $ H, q4 B' @' c% _, Q- Q/ x
  5. uint16_t     i;
    7 [7 q" D/ \' s; S

  6. ) [: {8 }5 l# e) y
  7. for (i=0;i<200;i++)) A' S3 Z5 _& g
  8. 8 g/ C7 Y& _% E3 x1 u' n
  9. {undefined
    9 N* C  P* P- n5 a

  10. 8 @0 ~+ }, g- J2 M0 M
  11. PData<i>=</i>0 z* p; \* I  j) o6 c8 {

  12. + F" X5 y. t2 w
  13. (uint32_t ) (2000*(sin((Tpai/200)*i))+2000);6 i2 o* c  A. h" S9 p
  14. 1 l5 L/ ?% O8 T* c. w& B2 T
  15. } //prepare data for DAC) z1 x; h7 C* k& m

  16. 4 w4 ~/ ?+ i: K- N2 }- Z9 g
  17. HAL_DAC_Start_DMA(&hdac1,DAC_CHANNEL_1,(uint32_t*)&PData[0],  200,DAC_ALIGN_12B_R);
    * e* C% t- v8 N1 u! R

  18. 6 c7 b- c) X& m/ n2 Q
  19. __HAL_TIM_ENABLE(&htim3);
复制代码

8 \7 b4 Y* p& L  i: @9 q* m
5 W8 E% P+ X" M% T$ I* h3 l" O6 t, J. A! u# ?
上面配置的DMA传输方向是从内存到外设,目的和源的访问宽度都是32位WORD. 当然也可以是内存访问宽度为16位的半字,外设访问宽度为32位字。即DMA的配置像下面这样也是可以的。
: c0 B8 s' w; [9 V
. f7 ^! \& v! R& z- n' l( o
d1a3b9537ab66535982e8b0cb86d3bbc.png

, [* v) @" o+ s) w1 M$ Y$ T! }3 Q, J0 ^4 b: T
其它配置不动,代码稍微改动和整理下即可。参见下面代码:" ^/ G; O7 r- [! H% Z

# _4 l. S' n( {" [
  1. Uint16_t  PData[200],Dac_data;
    ! b& X5 T" j' E  H& l
  2. 3 u( b7 R/ @! S( h. d. b
  3. #define   Tpai (2*3.14159)
    ( v4 C) v, }  m; w
  4. + ]5 A$ @0 U4 l( z" P3 {
  5. uint16_t     i;! L1 G, T3 Z# j3 Q7 [' {4 L
  6. 5 d3 b* ~' [0 K& V/ H
  7. for (i=0;i<200;i++)! G% X9 c. N- ?/ I, U: l0 w! X# O! T
  8. 4 [+ U9 ^6 a+ f/ u
  9. {undefined: ]+ B/ n) S9 D- \- Y% K8 S/ U
  10. 3 g3 d; L! `+ X$ v# B9 j& {  f% b
  11. PData=1 m, h) }: p' B+ X7 E
  12. , \( x+ k# n! r4 |4 n( B
  13. (uint16_t )(2000*(sin((Tpai/200)*i))+2000);4 x! ~' G, P. s
  14. , R8 S9 u3 Z$ e
  15. } //prepare data for DAC
    " ]3 Y! w& G! \$ y! T* ?
  16. 5 g4 M1 U: L, C5 }$ v
  17. SET_BIT(hdac1.Instance->CR,DAC_CR_DMAEN1);
    1 B1 a6 U8 a+ k5 A
  18. 6 ^3 v( V: N, C# e3 B" T

  19. " j9 [! v% G. x8 G9 G, H
  20. 9 c6 w2 E" a, J
  21. HAL_DAC_Start(&hdac1,DAC_CHANNEL_1 );1 q3 [9 o% |8 J2 J
  22. . o3 G" d" h2 a
  23. HAL_Delay(2);- q: J2 u) A; j& l

  24. ( o" o9 M/ Q6 R0 L* n; O; L

  25. . ]& L% V1 [1 m
  26. ! x  g. M) r/ U2 d  k
  27. HAL_DMA_Start_IT(&hdma_dac1_ch1,(uint32_t)&PData[0],(uint32_t)&DAC1->DHR12R1, 200);
    1 x9 T1 \- U, T
  28. 8 r$ Q6 d% {9 v5 f; w
  29.   A7 A8 Y! n! F" Y9 X4 h: D
  30. ) p9 A6 O9 r+ B3 b/ @/ V
  31. __HAL_TIM_ENABLE(&htim3);
复制代码
9 q- z4 |$ T7 [. v$ ~" k

/ T* _1 c3 b& I* p/ \; ~8 z8 s/ k+ U* \& E. e) z6 r5 `" q
0 |, A  R, h; I
第一种方式就介绍到这里,再来看看第二种实现方式,即TIMER更新事件作为DMA请求源,同时作为DAC转换触发源。$ }+ x3 A6 I& U! j7 U

# @+ Z5 F- O! @3 v- X基于CubeMx配置,主要调整下DMA配置,其它配置基本不动。
+ s0 B  Z2 a% R" f/ O+ i% R$ h
+ V( ~8 N2 D0 i/ n  x. d, j

" e- M% @! b  N1 q! k
6 c$ [1 i# S% H% @5 `! C/ B
  v! b$ F+ y7 B5 h! U主要是DMA请求事件变了,其它配置跟第一种模式基本一样。; o' x/ z  h) W7 F& O; I
/ c6 a( Z  `# {- S4 Z' F: C% M
配置完成后生成初始化代码,再添加下面用户代码:  d' \( u' x) P# v& R# z" e

" \" W* u5 ^& }; ]; U6 q
  1. #define   Tpai     (2*3.14159)! O! B0 J3 L7 [# t* L1 X  y
  2. " \% z. N0 C; S& o( t
  3. uint16_t PData[200], Dac_data;
    1 p, J! R/ c* l1 v: p; N2 ]" i
  4. ) U4 E( o# c. b; q. P
  5. uint16_t     i;
    7 E$ I/ }# @1 H7 G  }; n
  6. 6 O: E( v/ }, u& p! j- [' A
  7. for (i=0;i<200;i++); o- O% Y# x7 i) n& Y  U) i. w

  8. % z3 u, ?( B9 e0 A+ v- t; i4 X
  9. {undefined
    6 d4 s" _3 p- B+ t" m& X. ?
  10. 3 G* g, e6 p2 |# K" [! z/ o
  11. PData=6 x' e# T  I  I

  12. 4 R2 k0 w( t% f+ R
  13. (uint16_t )(2000*(sin((Tpai/200)*i))+2000);6 x3 K. D9 x3 h: }( ~6 ^- N

  14. ) E8 l* k/ I0 ]  \) ~# _2 ?
  15. }* L3 r7 ^" ?( d9 s% f. c0 f4 y* ^

  16. $ M9 C9 c; r% o. u
  17. HAL_DAC_Start(&hdac1,DAC_CHANNEL_1 );
    ; J/ O* }- _6 a: l/ q- {5 ^
  18.   g  i4 T0 E! s. f5 `1 X
  19. HAL_Delay(3);
    7 U# {/ o( ^4 H0 C6 d4 p

  20. # [* R  e, N, W/ k0 a: [2 P

  21. 6 p( D- m% u! z0 |7 [( ~+ ]
  22. $ r' c8 E7 b1 D' v& k  q/ i  u8 Z
  23. HAL_DMA_Start(&hdma_tim3_up,(uint32_t)&PData[0],(uint32_t)&DAC1->DHR12R1, 200);
    + j2 A8 M0 G( \0 ^

  24. 1 ^$ F8 ]3 E# g7 z

  25. & Q- l' w( m1 @( ~2 c
  26. % q& |% r" }' Q% g/ {4 z
  27. __HAL_TIM_ENABLE_DMA(&htim3, TIM_DMA_UPDATE);
    # e6 g) j- x! p4 C, {2 g

  28. 3 ~7 Y/ J' x0 X) l$ q9 h9 I
  29. __HAL_TIM_ENABLE(&htim3);
复制代码
9 y8 N9 [6 T* s" b8 q/ s
& u+ N8 w) J' Q" G+ N' l
这里要提醒一点,G4系列的DAC1的数据保持寄存器可以一次放2个通道的数据,在使用DMA传输时,即使只用到1个通道,DMA对它的访问也要遵循WORD对齐,不然你可能会遇到麻烦。& m7 c* n2 s+ z' s* \% l

! ^! G/ c7 i# z% H  Q* J如果说,我们不使用DMA做数据传输,只是手动给DAC喂数据,那如何实现上述效果呢?这时我们可以使用软件触发DAC的传输,手动给DAC的数据保持寄存器赋值,参考配置及实现代码如下:9 w8 w# c, c$ [9 G- y& U

2 m. u8 @& d. R# t6 Y* }( A1 @& Q
81958bbf0c7325cd86a0ecbf4dc138ef.png
5 G: m# M+ F( l7 C% B5 ?! h

6 r4 m% e2 D' E0 I$ Z& x1 ~! G
& M: s  G1 P  h1 f相关用户代码如下: % F" t. e/ Y4 A# t* g; p

. m! z6 T+ w( M8 D0 T
  1. #define   Tpai (2*3.14159)
    ' s# l) Z, y1 `% o9 |+ t
  2. 0 n- y, H" l! g# O- L$ f- b2 {- W
  3. uint16_t PData[200],Dac_data;
    4 C& t* @$ X+ H7 ^! Y: k: c/ x
  4. " {+ u. |: c4 l$ G5 l
  5. uint16_t     i;; p* G* }1 A) a9 F3 B
  6. ' Y: y2 d0 O1 }" P
  7. for (i=0;i<200;i++)
    * h& f) L0 M9 s
  8. 5 R7 M  x( d- K& u: G
  9. {undefined
    ) V7 F$ n- ~$ M8 V2 R- j, ~0 O

  10. 4 x# f5 b5 W- _8 o9 `/ f
  11. PData<span style="font-style: italic;"><span style="font-style: normal;">=
    ! ^4 Q' p6 G5 p( p
  12. " \+ Q4 q2 J  v
  13. (uint16_t)(2000*(sin((Tpai/200)*i))+2000);
    : t8 A. K7 ^1 ^( ]+ A: Z# L
  14. 7 P. c8 o8 k6 ?, b, c4 |. B
  15. }0 U& U9 `# A( N! N+ C8 y

  16. ; _& d1 g9 t6 T. n9 m5 s
  17. HAL_DAC_Start(&hdac1,DAC_CHANNEL_1 );& v& A0 m, M! a7 A
  18. 8 ^; J, }6 A' l- ]
  19.    HAL_Delay(3);) Q- y* t) D* @. Z  I

  20. ( B( o* P  b+ i/ J: Q3 i* W

  21. 7 k8 ]$ i# U5 g) d- a

  22. " }( ?- H" T9 d3 C& v
  23. while(1)
    8 t  X6 d- r9 v

  24. - Y' R1 K) u' @
  25. {undefined8 n9 Y9 t) y2 r
  26. ; w3 }  ~2 N/ ?3 S
  27. for(i=0;i<200;i++)
    " l; w# R4 ?2 H. c6 L2 a
  28. 7 v, r+ K  i2 e& I) v1 n/ p1 M& b+ u
  29. {undefined
    4 c' I$ B2 @( O+ ^' X) K

  30. ! a, Q% I8 p; w' y
  31. DAC1->DHR12R1= PData</span><span style="font-style: normal;">;
    0 K/ o" O9 D; v1 h4 `+ C
  32. 0 T* |7 R" A$ I: e* l4 ]
  33. SET_BIT(hdac1.Instance->SWTRIGR,DAC_SWTRIGR_SWTRIG1);' W1 h$ ~8 K8 M# e
  34. * S" A0 `* k' M, o3 n
  35.       HAL_Delay(5);0 S5 W8 R! j' L( w, E, y
  36. - `  T/ H% K" t' C% ^$ z
  37. 4 H2 f% J9 N2 ^& p" k0 t
  38.   ]# N4 U4 ?+ h. `4 n4 L
  39. Dac_data = DAC1->DOR1;//for debug
    5 d% ]5 v, v9 C6 C' x
  40. 3 q  `$ A" l" b" t9 t/ ?+ B8 b5 {

  41. 3 H$ S, i4 ^; ]0 `% E
  42. ' t2 D6 q+ S" r/ [# s
  43. }   y6 q# @4 b4 j8 i
  44. ' u) ^3 D3 j3 h5 X
  45. }/ \( T  @7 }! K9 f. f* n4 x# i. m9 ~
  46. </span></span>
复制代码

/ w& A7 E6 E& O: ~: e5 g总之,不论使用哪种方式,都可以实现我们所期望的结果,即输出如下正弦波。2 c3 O8 [/ f9 f; E4 T1 p* K

" L" @5 I3 c1 U) x  N( I0 r- }
692bd68b1c31d5aa2a4b73541244f56e.png

1 J* {2 u; r5 ?' {/ h  U9 ~. X) y$ U
好,关于STM32G4的DAC应用就简单介绍到这里,STM32G4系列的模拟外设丰富而强大,此处算是抛砖引玉。这里做些分享也是为了让其他有需要的人少走弯路,加速开发进程。【文中代码都很简短、直观,就没做注释说明了。还有个客观原因就是在微信公众号里排版也很费劲,字符不太好对齐。若有需要交流的可以后台留言。】. B; o) u9 [+ }

/ s6 k3 h8 g2 [+ ~, E& V1 j8 E& C; E2 [7 X  ?8 w
79bba335bff508c4f57300f0f57049de.png
收藏 评论0 发布时间:2021-12-8 22:00

举报

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