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

【经验分享】STM32 F1 系列 DAC 的示例详解

[复制链接]
STMCU小助手 发布时间:2022-2-23 18:36
前言
, M5 r0 |. m0 Z1 K基于学习的目的,详细讲解关于 Cube 库中的 DAC 的功能。本次介绍 DAC。
, C8 E( j# X7 d- A  q, B
% y2 D5 B0 q5 U8 V( V' \$ A, I; w( ^# ]; M
一、示例详解# W( N( O2 k# [$ @! J& k
基于硬件平台:STM32F10C-EVAL,MCU 的型号是 STM32F107VCT6。
  h1 U6 w" ~% ^软件则是其 Cube 库,路径:
* k! N, B. |, H. h* w1 Q5 U9 y& qSTM32Cube\Repository\STM32Cube_FW_F1_V1.3.0\Projects\STM3210C_EVAL\Examples\DAC\DAC_SignalsGeneration 。3 H8 U- U% V0 ~8 w5 X8 \1 L
1、主程序
1 {0 Y) k. ?- Y9 A4 e软件配置,运行程序可以发现,系统时钟设置为 72MHz,定时器使用到的是 TIM6;
3 d8 b, E) e: f+ Z0 k! L
  1. int main(void)( \( y9 H% ?/ D! X& f( X; J  C' ~" ?
  2. {
      e1 D0 b- K7 Z4 m( _/ Z" Q
  3. HAL_Init();: B: f! G- [, `
  4. /* Configure the system clock to 72 MHz */% p& f# S( E' c: N) x$ m, H* p0 j
  5. SystemClock_Config();
    4 p) B% O! l9 M& B* m
  6. % @- ?' U0 k7 w0 u! K2 ^1 z
  7. /* Configure LED3 */
    * K9 m2 u4 t( e. \* U$ S" o: v
  8. BSP_LED_Init(LED3);3 F' V* ^! p* K! b$ P
  9. /* Configures Key push-button */, }' @! Z$ e' v
  10. BSP_PB_Init(BUTTON_KEY, BUTTON_MODE_EXTI);
    + m$ n8 _" s5 o
  11. /*##-1- Configure the DAC peripheral #######################################*/
    * u4 f! P0 q3 W/ c0 I
  12. DacHandle.Instance = DACx;
    ; I, y9 i3 a, E4 w  t4 B& Q
  13. /*##-2- Configure the TIM peripheral #######################################*/6 i# T4 |$ e' |/ R4 `) W
  14. TIM6_Config();; i5 W" j  V# W( }
  15. /* Infinite loop *// L4 ^5 c# h) b, ^4 p- o/ q& p
  16. while (1)
    2 Z1 i, ?1 Z  g: u% d7 w, L' l- ^
  17. {
    2 i2 A, O& J+ O) J& P$ O/ O- r
  18. /* If the Key is pressed */
    ( g( `. a0 Y( P. W( ^4 j  h6 M8 q
  19. if (ubKeyPressed != RESET); Q0 j! e' l, x/ ~; G( X4 N, a2 P
  20. {8 l+ ^$ p9 n% U1 f: ~9 i
  21. HAL_DAC_DeInit(&DacHandle);
    6 b# H2 ^' X  A' f& [
  22. /* select waves forms according to the Key push-button status */
    9 F1 T, n% N3 i" y& c1 g
  23. if (ubSelectedWavesForm == 1); H4 W/ ^+ R" ~
  24. {
    ; a% H/ d9 M1 Z
  25. /* The triangle wave has been selected */: Y% F! Y: V7 L# O: s9 j; M
  26. /* Triangle Wave generator -------------------------------------------*/
    1 l/ ^" k! M7 O7 B- i
  27. DAC_Ch1_TriangleConfig();% s% d" M, a0 F! P0 U
  28. }
    * ?0 X% Y' l5 d! P! [+ H
  29. else
    1 s, z; M; @9 X
  30. {2 u" d% P3 }6 z0 J
  31. /* The escalator wave has been selected */
    . M" I: U4 L+ P6 R' H: E
  32. /* Escalator Wave generator -------------------------------------------*/
    ' V: a0 N) A& x" r+ k2 o6 {# J
  33. DAC_Ch1_EscalatorConfig();
    # e/ @: h) H# w; g1 ]6 N
  34. }
    4 R/ B9 y/ U6 L4 r0 h7 P. L
  35. ubKeyPressed = RESET;7 H0 z5 P' w5 b3 V
  36. }
    . r0 l* {0 `) [
  37. }- n# E2 d# x" E: x1 |; B# X3 Y
  38. }
复制代码

$ h$ Z: _$ n9 [  r% Z, h根据时钟树的图谱及其程序, 该示例选择的是内部时钟源作为定时器的时钟源;TIM6 的时钟源来自 APB1 的分频。- T* D/ G( Z* e  c( c" n

7 P0 u$ ]/ V, _* N. B( h; Y* a BOJGIK$J9Y1T)GWEOLDORNY.png 3 a# S9 N7 t4 Y; M

' k+ [7 Z2 ?- P: j+ w 77WD7)KJ43(PDZ(H~BOM[O7.png , s# M) B+ R8 D: l/ @

- W8 O3 f! w9 H. ?AHB 时钟 (HCLK)在 RCC_CFGR 寄存器中的分频系数 HPRE 的值为 0,即 SYSCLK not divided,即/1,所以 HCLK 就是72MHz;8 K3 S8 p0 F, f
APB1 的 prescaler 的系数是 PPRE1:0x4,HCLK divided 2,即/2,APB1CLK 为 36MHz;由于 APB1 的 prescaler 系数部分频,即/4,所以倍频器起作用,即为上图中的 TIMxCLK = 72Mhz。; ^& E: q9 ?* K5 j, m/ e' o
2、 定时器 Tim6
; d. L/ h( g* n8 B( K% ?! N
  1. void TIM6_Config(void)' ~8 x. Z- a1 ]7 [
  2. {
    & D2 `# T1 |3 g( w6 O/ q- T  p( }; {
  3. static TIM_HandleTypeDef htim;
    # Y  h- q% x7 `' ]7 \3 h
  4. TIM_MasterConfigTypeDef sMasterConfig;4 k' ?4 z; P# z+ O  A5 q. m
  5. /*##-1- Configure the TIM peripheral #######################################*/6 Z1 ?5 i/ w0 [
  6. /* Time base configuration */+ z0 P) [0 M8 X" b/ P: ^
  7. htim.Instance = TIM6;: R* x9 _' ]4 {: l5 k6 o& X" m
  8. htim.Init.Period = 0x7FF;  h% K, L) Z  x$ o$ q7 V
  9. htim.Init.Prescaler = 0;
    + [0 \: Z& i4 l' X  u, D
  10. htim.Init.ClockDivision = 0;
    ( L) U3 n( N$ j9 }
  11. htim.Init.CounterMode = TIM_COUNTERMODE_UP;
    4 o6 N4 ^5 c& e* R
  12. htim.Init.RepetitionCounter = 0;
    ! g2 _) X. V* o* W
  13. HAL_TIM_Base_Init(&htim);
    - w; ~! I+ C8 o  l. v6 _
  14. /* TIM6 TRGO selection */
    . V' a! s! d  g2 Z
  15. sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
    8 d8 H/ Y4 v$ i' N8 {/ I2 w, }9 _. `0 i
  16. sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;5 e! z9 X) _% V& S, Z  R
  17. HAL_TIMEx_MasterConfigSynchronization(&htim, &sMasterConfig);
    . ?9 ?, h. ~/ x/ N# j+ f; v
  18. /*##-2- Enable TIM peripheral counter ######################################*/
    & @% Q: m8 d2 E) k. F* e
  19. HAL_TIM_Base_Start(&htim);
    - G( @0 r' Z. d# p; u# P' V1 f% U
  20. }
复制代码

$ h$ H6 G* Y" \/ ~设置的是向上计数,周期是 0x7FF(2047),从 0 开始计数到 2047,所以该定时器的更新周期:(2047+1)/72 = 28us,7 k, w; v0 ^' A8 R

8 Z8 G" b5 e1 i" i! U! a' x UD%CQTP%_3DB8V(4{EY%4.png + a  X$ ?% u# k$ J5 P
: S3 ]. U) z; Q5 q# k; T. w
所以传输的 6 个数值:1 U5 H5 L. w0 l5 M* S; B1 N4 e
  s) a2 Q  ^) S/ u( w# P
P_({2T$L6~XQN4K@H4]NMGD.png
3 k3 w+ v5 @0 d5 }5 A9 g9 n# W3 g7 Z% r+ N, i7 d
对于 8 位的 DAC,程序中设定的是右对齐,6 Z% y9 v  _( t3 z6 y* t9 Y
! w& d5 D: G: _) D8 v1 n
5C[%R)IG%8H@80JPTHDWIZ2.png
9 P9 O  N+ f( d# J. g
4 N0 I" b2 t; X% V  m8 B所以,对应的 DOR 分别为% }; U4 L9 @: w( V
0x000(0), 0x330(816), 0x660(1632), 0x990(2448), 0xCC0(3264), 0xFF0(4080) ;8 X' H2 [: Z$ Q" r5 @
而 Vref = 3.3V, 所以:0 j  h0 s& F9 B
Vdac 分别等于:也是约在 0V; 0.66V; 1.32V; 1.98V; 2.64V; 3.3V 之间;
2 t7 q4 H" ], U% `4 r5 S) y) U. @; I3、阶梯波形% [8 t( A3 E; R" m% k, O* `
  1. static void DAC_Ch1_EscalatorConfig(void)& o, C$ y8 F; \/ h/ _- R
  2. {
    % p# n; M6 R7 p$ h3 }0 G
  3. /*##-1- Initialize the DAC peripheral ######################################*/- L' ~. g  T' I3 T" x8 M- ~
  4. if (HAL_DAC_Init(&DacHandle) != HAL_OK)( \' [+ Z! w" g
  5. {, w$ R% A5 D1 T/ d2 \
  6. /* Initialization Error */8 b" {; g9 i# L( r; T4 M
  7. Error_Handler();
    4 S7 L: A) U" M- W
  8. }
    ! p  e" E5 V: n  G1 b4 [" p: l
  9. /*##-1- DAC channel1 Configuration #########################################*/
    ) ~  E; o2 l) |% g
  10. sConfig.DAC_Trigger = DAC_TRIGGER_T6_TRGO;- [+ V$ ^' E' F/ A) b) x
  11. sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE;+ F6 ?3 P" r7 |% x9 u$ M3 r
  12. if (HAL_DAC_ConfigChannel(&DacHandle, &sConfig, DACx_CHANNEL) != HAL_OK)7 K! m* }' }7 T5 M, ~+ V; O4 F
  13. {
    $ B5 r; Y* ]0 Q
  14. /* Channel configuration Error */
    9 a8 p1 k# l4 J; ]
  15. Error_Handler();' M: j: q  a) r6 j# c
  16. }" ~- i0 ~9 @8 v9 n) H- ?
  17. /*##-2- Enable DAC selected channel and associated DMA #############################*/8 C# {- n# E/ A7 a# ~5 ~
  18. if (HAL_DAC_Start_DMA(&DacHandle, DACx_CHANNEL, (uint32_t *)aEscalator8bit, 6,
    & g4 C% `/ T; M! c3 H( G
  19. DAC_ALIGN_8B_R) != HAL_OK)
    5 r% E% ?6 ~7 U  _7 `; z" }1 h  [
  20. {$ }1 \, K$ F. `# V& J3 G
  21. /* Start DMA Error */* d" [. L7 m" x' y
  22. Error_Handler();
    9 z! O; K& U/ Z$ v7 N
  23. }# P) D& g( ~/ @. V+ b, i" Y
  24. }
复制代码
' k) V+ y2 ?, c# f( E
对于阶梯波形比较简单:! ]) F5 |! i2 V- f
就是上述的 6 个数值每个 28us 触发 DMA 传输一次到 DOR 的寄存器;
! Y9 G- w( X, S; e所以测得的实际波形(6 个梯阶,电压分别 0V; 0.66V; 1.32V; 1.98V; 2.64V; 3.3V; 周期 28*6 = 168us);
8 D( P  u3 X% Z8 Z0 h- {  i0 z验证的波形如下:
/ W5 c+ _' v/ {, Y' Q3 G# @$ k, P9 {- {3 T! h3 q. f
KZ{B_~0$B{QM6{738FWZDVS.png
: l  i6 G+ \/ h
6 b" L  k& {3 R) j$ x `78VU$NQP$H`4QXGF40~7[6.png
' m# W& ]6 ?, o' y* ~7 N) r- F) J% G7 ]
对于阶梯波形的产生,WAVE 设置的是 0x00;即:wave generation disable;
( S& l1 B8 Y' A, |! F: p
; ?* k4 s! I4 U5 h9 l
3 R2 Y8 q- J$ r )_`}[[`@_O~0WBY[)K~(AOG.png 8 q6 n7 F6 d  n6 z1 N! @9 T

, d" g/ O5 a' a9 L4 C, _  L1 T2 l4、三角波
, K3 r4 z, f8 n" W  |9 K
  1. HAL_StatusTypeDef HAL_DACEx_TriangleWaveGenerate(DAC_HandleTypeDef* hdac, uint32_t
    2 b. }4 i# P  M- k' u1 R
  2. Channel, uint32_t Amplitude)) |( w* m7 o. Q, L
  3. {! K) o8 D' U: n, Z
  4. /* Check the parameters *// P, F/ `- P8 M3 R0 N9 z
  5. assert_param(IS_DAC_CHANNEL(Channel));
    " Y/ q: b" r6 q8 H# c3 e7 ^/ U( ~
  6. assert_param(IS_DAC_LFSR_UNMASK_TRIANGLE_AMPLITUDE(Amplitude));
    1 C5 [( g7 E& f$ U1 j- y
  7. ) Z! _, l1 a9 g# W. f6 H' L& L
  8. /* Process locked */5 q1 v. W8 `+ a& r* s) S/ I
  9. __HAL_LOCK(hdac);4 i8 n+ \9 ^) L- L- |! m" t

  10. ! y8 L/ U8 s* g4 ?6 p1 A& w7 c
  11. /* Change DAC state */
    0 `! T. C& a. F3 f
  12. hdac->State = HAL_DAC_STATE_BUSY;
    4 v0 v8 ~% Q& a6 K7 u8 t1 Y: S
  13. 1 Y' |0 D' h+ ^4 y
  14. /* Enable the selected wave generation for the selected DAC channel */( \# `% I. R' O0 m+ Y& J
  15. MODIFY_REG(hdac->Instance->CR, ((DAC_CR_WAVE1)|(DAC_CR_MAMP1))<<Channel,% N8 W5 }0 I7 F& ^
  16. (DAC_CR_WAVE1_1 | Amplitude) << Channel);
    1 k, a" E8 \: U  P: m
  17. - e0 E0 }9 t/ [/ r6 _, O3 R
  18. /* Change DAC state */* e+ w# d, o3 s0 Z' S
  19. hdac->State = HAL_DAC_STATE_READY;
    * \+ z9 J5 o1 p) Q! s

  20. 6 {: B4 @0 i! ^! m) a
  21. /* Process unlocked */
    + K' Q- m& q1 `8 U
  22. __HAL_UNLOCK(hdac);. I7 C5 \" j9 V! |$ U( B
  23. + o/ E- B4 m; o+ G: J4 d6 F( A
  24. /* Return function status */. A0 G' a* z/ L$ o
  25. return HAL_OK;4 V0 j$ N: d, Y: F0 l
  26. }' ~& Y( d) S7 U) e5 k3 G1 @: z
复制代码
9 I5 T( O% ]) v
! L  P' O1 n3 G7 u; L. T# }
产生三角波的主要代码如上,其实也就是下面的这一段代码:3 ?6 a; G, ~/ A: j- O, ?7 L' [
  1. /* Enable the selected wave generation for the selected DAC channel */6 T0 K" b1 k' J* f, T# o
  2. MODIFY_REG(hdac->Instance->CR, ((DAC_CR_WAVE1)|(DAC_CR_MAMP1))<<Channel,
    6 }- G2 M5 y% H. {, S0 S8 p0 g
  3. (DAC_CR_WAVE1_1 | Amplitude) << Channel);
复制代码
其实也就是设置下面的寄存器的比特位;& J1 p9 y0 \1 I4 N) r& P9 @1 ?% A

6 T( ?( q7 ^* R% A! q3 J E}H]QH04B{%%~7AFM}7WR3X.png
4 q' B, @+ [# N
1 K+ e- ~7 b2 O( X最大的振幅是 3.3V,即对应的是 4095,
% o/ ~/ I+ p3 @; Y( ^0 k# T软件里面设置的 2047,所以振幅是大约 1.65V- e: F, |& m9 x/ m

& p2 t4 {0 n2 l
0 a1 H! a0 H- z% e& y" k; Q7 n
: a. h! e% O, b# f该三角波的产生是由单片机的硬件产生的,软件控制的是:振幅和周期;6 O7 `6 W4 y4 _1 n; o! b
振幅通过上述寄存器中的 MAMP1 来控制;
2 P; v- y( w8 o7 L: Y% p周期则是定时器 Tim6 的触发事件?3 X. o. m& e7 F0 m; y% m
但是这里的周期并不是 128us 啊?
3 V- L% u2 k( G! x改变幅值也会改变三角波的周期的,2 u& I# W+ Q8 N* m2 ^! z% B
那么这幅值和周期以及定时器之间三者的关系如何呢?# B" `" P4 O7 g  W# g# B, f, P
答案:
' E) U8 Z; I  D8 Q
# A1 s2 ^. e5 B$ e8 F) m
  1. 因为每个时钟节拍才步进 1 格,如果是满幅值输出时,要步进 4095*2 个定时器时钟节拍。/ `" c' H  _, z
  2. 我的程序中,设定的幅值是 2047,所以输出一个三角波需要 2047*2 个时钟节拍;6 k) _2 r1 q5 H) Y% K1 I
  3. 一个时钟节拍在上面计算的 TIM6 的更新是大约 28us;所以周期 28*2047*2us;即大约是 115ms;
复制代码

2 v+ O0 {, P) b* E2 h$ Y7 E
2 o" f! o9 Z/ \+ j PPH2K@RB]M6`O~W08AX3R~V.png
7 V# B! e5 u1 Q1 k
: |& u$ ]% \! K符合推论。/ S) P: @. l) i+ e  T4 ~* T% V7 D
设置的波形控制模式:WAVE1 = 0x02,即产生三角波;
4 S- h6 \# ]" T* p
: F: [6 A; O6 u5 i G5Q5A8[6VBWMIUJA6UNG28E.png % X# X* Z% `( y* k
% ?  E5 F  q2 ]
对于三角波的产生器,还有一段函数代码的作用是什么意思呢?
2 @4 `7 t# o0 K& J/ f  ]5 v/ X
# E9 H8 u2 `5 P! u2 l
# o3 r6 c0 `1 }" k, t% \
  1. /*##-3- DAC channel2 Triangle Wave generation configuration ################*/% |; n  R+ w! r8 ]* Q
  2. if (HAL_DACEx_TriangleWaveGenerate(&DacHandle, DACx_CHANNEL,  u; J" Y) u* u! X6 H( Z7 f* Y1 x/ \
  3. DAC_TRIANGLEAMPLITUDE_2047) != HAL_OK)$ a/ T" c* @( Y+ g% e0 G: z
  4. {! O4 Q3 Z+ V4 J
  5. /* Triangle wave generation Error */
    ! t6 z4 B  x, q
  6. Error_Handler();1 y- O5 y" @' O9 ^3 ^; m
  7. }3 \2 f: n# U7 _; x; ^% k. I% I
  8. #if 1
    * {% _( a* [7 ~' b2 u% ]
  9. /*##-4- Enable DAC Channel1 ################################################*/
    $ Y7 n) b7 s2 N/ ~1 h
  10. if (HAL_DAC_Start(&DacHandle, DACx_CHANNEL) != HAL_OK)) b' ?& d0 L3 {2 O( p) [9 \8 y# `5 i  G
  11. {0 t% u( |- \, R! n1 {
  12. /* Start Error */0 D& ~6 d" @% ?2 b
  13. Error_Handler();
    ' @+ n. Z) Q  t  L3 x
  14. }
    . y+ g0 @" r  }5 E- P. u. U! x8 u/ R2 q  U
  15. #endif
    6 G) U, p: D- n' N5 _2 j* r
  16. #if 0
    & A: F. f+ o+ o
  17. /*##-5- Set DAC channel1 DHR12RD register9 _9 R" O) Q7 {, n
  18. ################################################*/
    1 ^7 j: F$ C+ T/ y# v$ w7 v& ~" B
  19. if (HAL_DAC_SetValue(&DacHandle, DACx_CHANNEL, DAC_ALIGN_12B_R, 0) != HAL_OK)) ^1 t! B% ]1 u$ y: p9 ]
  20. {
    ' e8 Y1 |1 E0 c0 O; F1 ~% M
  21. /* Setting value Error */
    9 l: y7 j6 [1 ^5 y2 w
  22. Error_Handler();
      x' T5 v7 X  V1 p8 M
  23. }, `2 h/ j8 k0 m3 Q; A" X& T: w
  24. #endif
复制代码

4 F2 T- \8 [+ E5 l- V# \% w4 ~) Q# D2 q& k4 P6 t
即其中的代码:2 _, g) g; F1 a1 g) f
  1. if (HAL_DAC_SetValue(&DacHandle, DACx_CHANNEL, DAC_ALIGN_12B_R, 0) != HAL_OK)
    * B- q9 @; ~7 b7 M6 d$ i8 R
  2. {) ^% S# I2 e& `% {
  3. /* Setting value Error */
    ' _' d( K! t0 x. D2 C
  4. Error_Handler();7 _. ~8 L: Z2 ~
  5. }
复制代码
. X$ H- R0 N( _! [! _

  L, z" _6 q& ?2 Y" b' H是什么作用呢?" K& e; Y1 H/ N/ D( `3 @' t& o, ?6 {
产生的波形:8 u  t* f, e# D+ }( I
4 M4 E# k& s: R4 |
  1. /*##-5- Set DAC channel1 DHR12RD register
    - x+ m2 H' M, b
  2. ################################################*/
    3 c: r/ s' m& U, d; \! z
  3. if (HAL_DAC_SetValue(&DacHandle, DACx_CHANNEL, DAC_ALIGN_12B_R, 0) != HAL_OK)
    ' j, Y! `( R0 o0 o
  4. {
    - m. j; D" }5 f" t6 P; L
  5. /* Setting value Error */
    9 L2 |' j  F6 T/ [# f/ C2 g
  6. Error_Handler();
    ( s0 [% Q6 K/ |5 X; }1 A" m
  7. }
复制代码

9 L0 m7 y3 t4 x
. w9 C: z$ l& w0 o8 z7 r1 G' \ PF95M`$(5D[@%V5]AW_1ZNJ.png
- r6 `  G' i# Z% w/ |  q$ K5 v7 ~$ h  t/ j, s. c. l
在加了函数之后:
% i9 G# E5 ^# D( I: `0 L- J) h
  1. /*##-5- Set DAC channel1 DHR12RD register# [0 n4 X" E3 n
  2. ################################################*/+ S9 K# ^4 m2 U3 d0 ]
  3. if (HAL_DAC_SetValue(&DacHandle, DACx_CHANNEL, DAC_ALIGN_12B_R, 10000) != HAL_OK)* g/ y1 e9 \5 u3 K
  4. {3 W6 E. t  ^6 v
  5. /* Setting value Error */
    : r" K1 p4 g# W1 ~: E: i
  6. Error_Handler();
    % u3 }9 B5 k: }1 A
  7. }
复制代码

7 i2 O( O0 n( r( q  r* l 6KAJS6$~[D2BJK`TWFS~K(A.png
5 O& v' D" s" [" M! b: l8 o2 M% S" [* X
! a6 w/ Q( C, ?3 T" A从波形上来看,当参数数值不为 0 时,波形更像三角波,那这个参数影响的是什么呢?
, G) R# h5 S; \5 w' E% a  p$ `; _. l2 Y% S
HY$E2N_T)KB0(A9$)5RB$SN.png
' {' \& I; L" [5 @* a参数的 tmp 的值,位于 0x200004A4 处,初始值为 0,运行到:
4 n; D5 Q* C+ R- [
  1. tmp = (uint32_t)hdac->Instance;
复制代码
* P9 r) L/ n' S3 m' l$ l: `

8 \0 ]8 X  k6 F  b& h后 tmp 的值为 0x40007400,该值是解释得通的:DAC 外设的基地址(0x40007400)4 S- @: }  y" @/ r0 `) B0 W, F

! Z6 X! L, f8 c# O. t. r 0VFS)9`NB1@(H90VCS6HE{L.png ) c; b  L; F' U. i/ y8 `% x

% Q# d: I) [' `4 y, {+ F执行完语句之后:由于传递的参数是#define DAC_ALIGN_12B_R                  ((uint32_t)0x00000000)
3 Z7 r& j; a" l' ~
  1. DAC_DHR12R2_ALIGNMENT(Alignment);
复制代码

' k) H, L, n& `! K) W得到的结果是(注意上图中虽然断点停在了 DAC_DHR12R2_ALIGNMENT 处,但是程序是 DAC_CHANNEL_1,所以最终执行的还是下面的语句)
2 s7 _- p% t4 [6 V5 \9 I1 L
  1. #define DAC_DHR12R1_ALIGNMENT(__ALIGNMENT__) (((uint32_t)0x00000008) + (__ALIGNMENT__))
复制代码
3 X, Z- J- f+ C4 y% s; P6 E
所以最终产生的效果就是:9 P- F; H- Y0 d+ ~% {, w  w, s
  1. *(__IO uint32_t *) tmp = Data;
复制代码

9 w  K+ t! q) o% o5 f2 s* a+ l; A6 A: D地址为 0x40007408 的寄存器赋值,即下面寄存器赋值:
& p2 O) {7 b3 R5 u* ?$ f6 ~9 o
) v9 ?6 P5 G1 H. R7 s! j% ~  {+ ? $VY8TU)HK7YNVS7381$J1)9.png * n4 }' z8 N0 z4 T
5 i) W6 {* s/ t& w- o3 N$ [" T
但是这寄存器的作用是什么呢?holding data?
* _( z$ j' W% ~) k2 c7 {# G. I! HHolding data 寄存器,可以简单的理解为:
, u0 g+ L& ], u" z# F设置影响 DAC 的直流分量(直流分量还是根据下面的公式计算出来的):. W3 s1 [/ j; t( `: \

! A( D+ \5 N' Y9 z$ Y* z
( S0 N: M5 c& Y- g/ d* L! a' M  L7 s- f6 D3 a1 o* _4 k: O$ A# h
当传递的参数设置为 0 是,DACoutput 即三角波的最低电平为 0:, W3 k* u2 I( j" {# O* G% m
当传递的参数设置为 2047,DACoutput 即三角波的最低电平为 1.65V
5 ?. o6 ]( v8 s) |! {/ j7 }: s; @% N: m0 d1 Y* \% L
((~IQBBQ`%8]8OY$)C~ZSMG.png
! Q) e4 j) l6 a. z, I6 r1 d9 l+ U& i" S
如果传递的参数设置为 1024,DACoutput 即三角波的最低电平为 0.82V;, |" P, _! P5 m* x* E" Y( ?

# Z: f# Q" x) _3 F  O/ o5 M YKU_`@}WQ1HO[_64VHLHR~D.png
. L3 H" E1 ~! u5 `9 f- ~, i0 q& I# d9 u$ V+ `% W
如果传递的参数设置为 3000,DACoutput 即三角波的最低电平为 2.42V;
8 ]/ a( o9 f2 n, y3 O9 N; O
  P# c8 j) J# S7 W: _" g, p QO]W{{MY9ISBI`VH9NZ[25Q.png
+ V% t" w, ^$ X# d# L8 p  V8 x0 H" U, F1 k0 J
50}5O~JR4M]C~)J04DY)~13.png
0 A. @0 r& G: W$ Z5 P& r
  x2 V$ r+ h5 n: a3 Z5、噪声产生器: c: A9 j& X( E* ]9 F, _, _2 C4 R- W
主要函数的代码如下:
# u) I# [8 W8 s
  1. if (HAL_DACEx_NoiseWaveGenerate(&DacHandle, DACx_CHANNEL,) Y: m# a# h! T# j- r
  2. DAC_TRIANGLEAMPLITUDE_2047) != HAL_OK)- w: m4 n+ Q( B
  3. {) Y, C# R3 n& Y" y5 f* b4 \; G
  4. /* Triangle wave generation Error */
    ! A) Y9 a( w2 j  d# ]
  5. Error_Handler();
    ' i% [% j* q( _! B
  6. }
    : @) @8 Q8 X* v6 _; a6 c9 ?
  7. /*##-4- Enable DAC Channel1 ################################################*/) L3 o3 J4 h0 c! C0 _
  8. if (HAL_DAC_Start(&DacHandle, DACx_CHANNEL) != HAL_OK)
    ! h8 V; C; [# I: m1 [8 R$ p: ~$ a
  9. {
    - E! x. B' O1 Z. T# x+ _$ u, D
  10. /* Start Error */
    7 N% P. B5 Y9 o  h1 x/ k
  11. Error_Handler();! U. a* \0 }7 [2 G* b
  12. }
复制代码
/ Z  r2 `$ @+ v

$ L9 t4 P# b& `* Y0 z. @& v2 l1 M" O; S7 E
由于一般的认为噪声是随机性的,所以可以认为只是修改幅值,对于其周期不可控;
9 T$ ?. ^: H/ ?" \8 x8 I! u  G- S8 j/ K2 A3 b# l" e( g
) p' ]! k1 a0 r: F3 S5 s+ {
- Y: [6 ~* Q* n# j5 W

  \- E6 B  g! W9 @- B* I4 M: k/ u2 Y- m- R

  c' U* G  [& L4 K5 e
' h0 O  U+ \! i2 P& W
PDZKNYI_I07HJNH`(NQ2ANG.png
收藏 评论0 发布时间:2022-2-23 18:36

举报

0个回答

所属标签

相似分享

官网相关资源

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