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

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

[复制链接]
STMCU小助手 发布时间:2022-2-23 18:36
前言
$ x5 X$ i+ D$ k- M基于学习的目的,详细讲解关于 Cube 库中的 DAC 的功能。本次介绍 DAC。4 d# L% E3 A% @3 L
: z7 d4 }. R. k0 V

$ ?/ E: @! d5 H; z一、示例详解# O+ }) D. e3 B+ }
基于硬件平台:STM32F10C-EVAL,MCU 的型号是 STM32F107VCT6。
& T  w$ |$ ^- L, @. ^; _7 v, h软件则是其 Cube 库,路径:, d$ x3 U' T: I
STM32Cube\Repository\STM32Cube_FW_F1_V1.3.0\Projects\STM3210C_EVAL\Examples\DAC\DAC_SignalsGeneration 。
! y; s6 e& X( [: B9 I* e( H! p- h1、主程序
8 l5 p. K, G+ v9 i/ j5 o, `软件配置,运行程序可以发现,系统时钟设置为 72MHz,定时器使用到的是 TIM6;* G6 s: I5 U" n9 P1 H
  1. int main(void)
    8 V# [4 v) F! \8 T8 v  K
  2. {
    3 n5 X$ p% {  w5 Z) H0 q$ u6 P, C
  3. HAL_Init();  d9 n: B- l  \7 T
  4. /* Configure the system clock to 72 MHz */
    2 n' d$ S% j9 z7 I
  5. SystemClock_Config();2 b7 o" D1 x/ N1 x

  6. & C" R* d- J3 m! G
  7. /* Configure LED3 */
    6 e2 u. v; F5 O
  8. BSP_LED_Init(LED3);
    & I' b6 W& @: `7 S6 q9 I. W
  9. /* Configures Key push-button */
    - {- X+ w) }- y( ]3 p
  10. BSP_PB_Init(BUTTON_KEY, BUTTON_MODE_EXTI);$ D5 N0 c- v# Q
  11. /*##-1- Configure the DAC peripheral #######################################*/. H5 ^, C0 c5 K3 K7 r
  12. DacHandle.Instance = DACx;" H' [! @& _2 T: u7 }6 W+ o
  13. /*##-2- Configure the TIM peripheral #######################################*/
    7 b( U) M" H$ w8 t( ?5 ?  E
  14. TIM6_Config();7 V$ u: K& W# m0 C4 H
  15. /* Infinite loop */6 w( K2 ^% t* x4 Y
  16. while (1)
    6 t: K5 O+ g# z/ B
  17. {
    , d  B2 A/ Z# D3 V4 ~" t1 A0 ]7 C
  18. /* If the Key is pressed */
    0 m1 D' K+ Y) K7 x$ f/ q$ ?
  19. if (ubKeyPressed != RESET)3 `$ d$ z9 t3 H7 P. Z, ]
  20. {: p7 T$ O# o* S
  21. HAL_DAC_DeInit(&DacHandle);+ K! w8 ?, @0 S# |( @/ B) E
  22. /* select waves forms according to the Key push-button status */
    " O9 c) A) V. O6 O( G# }7 |1 g, k4 t
  23. if (ubSelectedWavesForm == 1): S# |- a' `. I* q& }! a
  24. {
      R- S( i- _8 C
  25. /* The triangle wave has been selected *// o' @; \8 Y1 H
  26. /* Triangle Wave generator -------------------------------------------*/
    ' x1 k# _% a' x, k3 k
  27. DAC_Ch1_TriangleConfig();
    ) ?- L' m0 t! o: Q- y3 T; o
  28. }/ N2 A6 p/ E3 X! Y0 c7 f3 u
  29. else
    6 E5 L7 g9 s4 Z: N* m0 G3 B1 l: c) Q
  30. {
    ; K6 H2 K/ ?1 u9 f4 |* v! B$ E2 k
  31. /* The escalator wave has been selected */! N! z. |6 @) }0 ?
  32. /* Escalator Wave generator -------------------------------------------*/9 Q! s2 B; ^  f* }' ~  t7 z9 \
  33. DAC_Ch1_EscalatorConfig();
      x4 f4 k0 Y" n) J0 O% o; b* D9 q
  34. }
    " a# D  J* K" @$ s" m1 {4 X- v4 z
  35. ubKeyPressed = RESET;6 _8 N) P0 [( f2 A* X5 ]
  36. }) e4 b" k9 U& W; ^
  37. }
    4 A8 F# y$ w8 `# C
  38. }
复制代码

5 Z5 q8 x7 h. @7 T5 y6 M根据时钟树的图谱及其程序, 该示例选择的是内部时钟源作为定时器的时钟源;TIM6 的时钟源来自 APB1 的分频。' T$ l5 o% Y& Q: A( r! i% L+ _
3 J3 j2 R: \/ Y- ~6 p$ a0 V1 Z. s
BOJGIK$J9Y1T)GWEOLDORNY.png
2 w% {: L" |' ^' r7 z
0 o3 T1 F8 o0 v: c  l 77WD7)KJ43(PDZ(H~BOM[O7.png - @$ b- M% z% q, h/ W* I

- e0 r% D/ T. u! dAHB 时钟 (HCLK)在 RCC_CFGR 寄存器中的分频系数 HPRE 的值为 0,即 SYSCLK not divided,即/1,所以 HCLK 就是72MHz;
! j5 `) M* X+ j1 O! KAPB1 的 prescaler 的系数是 PPRE1:0x4,HCLK divided 2,即/2,APB1CLK 为 36MHz;由于 APB1 的 prescaler 系数部分频,即/4,所以倍频器起作用,即为上图中的 TIMxCLK = 72Mhz。* m& S& k) Z; O2 }1 B9 G
2、 定时器 Tim6
; E* d. B# E7 `. k, q/ `
  1. void TIM6_Config(void)
    . o/ f3 f0 ^' K, _9 k9 f
  2. {
    : |; ?" K( J$ ^+ j- J2 r2 S) t* I
  3. static TIM_HandleTypeDef htim;& e/ L" e* s9 P. n: _
  4. TIM_MasterConfigTypeDef sMasterConfig;; {" W- l8 h! ?( V
  5. /*##-1- Configure the TIM peripheral #######################################*/
    $ O& q* ]5 a" g' M: O- m$ Z
  6. /* Time base configuration */! n2 [. @- g4 e7 b8 S8 f1 s* l
  7. htim.Instance = TIM6;( M  R6 @# Q/ m& E! i
  8. htim.Init.Period = 0x7FF;
    4 u9 z  o+ ?3 d) h3 j# {! f% Z
  9. htim.Init.Prescaler = 0;2 y$ D3 g: w% ~
  10. htim.Init.ClockDivision = 0;
      o7 a" S9 w3 z2 F1 w& U" p
  11. htim.Init.CounterMode = TIM_COUNTERMODE_UP;6 I) Z" ~" r/ j$ r' A
  12. htim.Init.RepetitionCounter = 0;
    6 Y4 d" X$ Y6 O, M0 {
  13. HAL_TIM_Base_Init(&htim);8 _. }, Z8 {; s* M" D# x, C$ k
  14. /* TIM6 TRGO selection */
    % m4 Y: E) x' Y! F7 F6 ~' ~) X
  15. sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
    ' P. c" s8 C5 M  X5 D9 P/ l4 K
  16. sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;+ i4 Y/ ]0 a! K" X
  17. HAL_TIMEx_MasterConfigSynchronization(&htim, &sMasterConfig);& D- g& l6 ]5 x+ \
  18. /*##-2- Enable TIM peripheral counter ######################################*/
    - X% e1 e2 D) v) u4 z2 |
  19. HAL_TIM_Base_Start(&htim);
    4 h/ Z7 ~2 O8 `+ f& j. N% P  ^
  20. }
复制代码

8 m: P( c3 Q( ?! U  L/ D; T设置的是向上计数,周期是 0x7FF(2047),从 0 开始计数到 2047,所以该定时器的更新周期:(2047+1)/72 = 28us,
  D: U. o! B) ]
0 i; X. ~. j" n4 g8 V* G* E7 _ UD%CQTP%_3DB8V(4{EY%4.png
8 E* @; H% L% C3 k& u, B
5 R5 i, T1 _, `, M% Q所以传输的 6 个数值:
/ C: U) H2 J) m8 y2 c, U* V
1 z0 W0 C# K' B/ F P_({2T$L6~XQN4K@H4]NMGD.png
. S/ D: W9 ]4 `. e3 p3 K6 ]  f: ?# L/ }, f( _
对于 8 位的 DAC,程序中设定的是右对齐,
. N9 X; V: W% g; F3 n
6 O- `. P6 k% Q/ V( i 5C[%R)IG%8H@80JPTHDWIZ2.png " G% N) k% R6 }0 q
  l; \7 [8 x$ j( \1 L  T* J: |5 A
所以,对应的 DOR 分别为: F, n( Y4 Y5 [, T" n
0x000(0), 0x330(816), 0x660(1632), 0x990(2448), 0xCC0(3264), 0xFF0(4080) ;% A5 m8 S$ L. h0 _4 s" n- D4 F
而 Vref = 3.3V, 所以:
- `+ \1 h' g+ |1 }7 x* hVdac 分别等于:也是约在 0V; 0.66V; 1.32V; 1.98V; 2.64V; 3.3V 之间;
$ `& e# x) q! w. c" X3、阶梯波形
6 j8 x9 k2 m2 C9 J1 N
  1. static void DAC_Ch1_EscalatorConfig(void)0 D; j/ x8 P# R) ?" n: G
  2. {" J% T% Y. ?8 y' Y4 L; z. d
  3. /*##-1- Initialize the DAC peripheral ######################################*/' _; j5 I! m) M
  4. if (HAL_DAC_Init(&DacHandle) != HAL_OK)8 M2 n/ x5 W$ r1 I7 \
  5. {
    / ^$ f5 n: W! m  _
  6. /* Initialization Error */
    / x* N# k/ V( ~2 j. a* Y9 d
  7. Error_Handler();
      Y9 L$ o7 o1 g! T. g
  8. }
    ; ^9 H) j  \, M
  9. /*##-1- DAC channel1 Configuration #########################################*/
    " T: W% Y0 V+ N* R1 ?% |' m. r
  10. sConfig.DAC_Trigger = DAC_TRIGGER_T6_TRGO;3 U( S: ?5 q' O) b$ d, F( v
  11. sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE;, k# y# N' G* a3 U0 E
  12. if (HAL_DAC_ConfigChannel(&DacHandle, &sConfig, DACx_CHANNEL) != HAL_OK)
    , V! T; q4 I2 Q, {0 `
  13. {+ H5 B7 s3 K, v  _1 f# r7 P
  14. /* Channel configuration Error *// Q' I! X! K* o/ y
  15. Error_Handler();
    4 [; ?2 H% @" {' ~
  16. }3 z# N9 A3 K" R; O8 G6 w
  17. /*##-2- Enable DAC selected channel and associated DMA #############################*/
    ) m1 [) N* Z  r# F7 l
  18. if (HAL_DAC_Start_DMA(&DacHandle, DACx_CHANNEL, (uint32_t *)aEscalator8bit, 6,$ V% ]  H- [7 d/ }
  19. DAC_ALIGN_8B_R) != HAL_OK)2 c- O# c+ R* u, L( U
  20. {
    : R8 q2 b5 o7 n* P7 p
  21. /* Start DMA Error */: t1 i5 M. I- _6 a0 Z
  22. Error_Handler();
    1 a0 Q+ n8 L1 J8 ?
  23. }
    5 ^" o5 E# D0 C3 ~( V
  24. }
复制代码
$ k6 W. n( j2 _8 X- ?
对于阶梯波形比较简单:( d$ m+ k: p. ^' z1 t1 n3 ?* C% H
就是上述的 6 个数值每个 28us 触发 DMA 传输一次到 DOR 的寄存器;
& F: ]* `; Z; _; E) o* }所以测得的实际波形(6 个梯阶,电压分别 0V; 0.66V; 1.32V; 1.98V; 2.64V; 3.3V; 周期 28*6 = 168us);% ]2 C" z7 E5 b4 B2 t
验证的波形如下:
" v+ X% G8 E: g, S- N
/ K& v+ K2 d& Y4 a( o& y8 o% } KZ{B_~0$B{QM6{738FWZDVS.png
- d2 V: b$ g1 ]& Q8 t- q+ l4 C
9 O$ P$ ^+ X( v' ~  g& i9 l& ^ `78VU$NQP$H`4QXGF40~7[6.png
- n3 R9 F; [" T4 E, R- ~) W
$ |2 D$ }/ A  G+ }- |% @8 k对于阶梯波形的产生,WAVE 设置的是 0x00;即:wave generation disable;
' q0 f) H+ C2 F2 }) d( ~- d# G$ H% Q: _: Y7 @! f: Z# v  _' C5 v' R

% ]! {& V7 d4 a3 B )_`}[[`@_O~0WBY[)K~(AOG.png
7 ~( s" }8 g2 }: g# W' q3 |0 [' B4 R9 n% |% Q+ `
4、三角波
# B1 j( b1 w. Q. g# Z: I' i
  1. HAL_StatusTypeDef HAL_DACEx_TriangleWaveGenerate(DAC_HandleTypeDef* hdac, uint32_t
    4 g5 P( K, ~1 W' W* }% s
  2. Channel, uint32_t Amplitude)- ]8 l6 c5 Y2 V
  3. {
    : N9 j% E- y! \) e& U
  4. /* Check the parameters */+ X2 \3 \) L/ ]' l: l* _
  5. assert_param(IS_DAC_CHANNEL(Channel));
    " I  Z0 {! u- }& s
  6. assert_param(IS_DAC_LFSR_UNMASK_TRIANGLE_AMPLITUDE(Amplitude));0 E2 U4 b3 c- U* r) w6 i6 |

  7. 6 [. B+ l; W1 f. F: x! i( u  z
  8. /* Process locked */$ j" t4 r# Q# F8 @
  9. __HAL_LOCK(hdac);
    0 j8 T) q+ S% g  u6 \

  10.   F# w, K  \5 r& ]% u
  11. /* Change DAC state */7 l7 P9 ^9 z$ W. S: ?5 T( y) p
  12. hdac->State = HAL_DAC_STATE_BUSY;
    5 o6 y, W. K% {2 B0 k% i9 {4 I
  13. % ~' q6 ^& T$ k5 f$ k  _' K
  14. /* Enable the selected wave generation for the selected DAC channel */% E4 ^2 \" l* ~; J) o
  15. MODIFY_REG(hdac->Instance->CR, ((DAC_CR_WAVE1)|(DAC_CR_MAMP1))<<Channel,- e- _5 v8 }1 i* _; c( {/ p9 ]
  16. (DAC_CR_WAVE1_1 | Amplitude) << Channel);4 M9 s0 v3 z# c/ h# ?
  17. * g+ \! e$ Z5 P7 {7 h& h; h: Y6 n7 s2 s1 i
  18. /* Change DAC state */
    - U" H8 T$ W7 B& a! K7 m4 M
  19. hdac->State = HAL_DAC_STATE_READY;
    ; x0 M- Z9 E: d/ C& m

  20. & h3 X/ r+ e3 u1 Y) I
  21. /* Process unlocked */2 Z) r3 K- \' @4 I+ v0 g$ p
  22. __HAL_UNLOCK(hdac);8 R$ W+ H% ^" G- t
  23. ' i0 w# I& [% [6 f
  24. /* Return function status */& P6 z  `/ n! c+ ~/ F
  25. return HAL_OK;
    % o7 T) j: u" l# u( o
  26. }
    5 x) Z. b. \% P
复制代码

2 P+ h% H1 y& Y- i- d$ S; b, X4 e0 X0 o8 P) y
产生三角波的主要代码如上,其实也就是下面的这一段代码:
$ L9 {3 @$ i4 {% O! N) y9 K4 @
  1. /* Enable the selected wave generation for the selected DAC channel */2 w; {, C! |7 P
  2. MODIFY_REG(hdac->Instance->CR, ((DAC_CR_WAVE1)|(DAC_CR_MAMP1))<<Channel,
    . }. X6 |2 w# ]3 ~
  3. (DAC_CR_WAVE1_1 | Amplitude) << Channel);
复制代码
其实也就是设置下面的寄存器的比特位;6 v# n0 m& X2 V8 H$ v; S- p
- n9 M' x' j9 u& O2 H) Z
E}H]QH04B{%%~7AFM}7WR3X.png
: n# O" g" ~; V: p, C; N5 ?& u# ?/ f: K4 K
最大的振幅是 3.3V,即对应的是 4095,
4 k& x2 X2 p0 i软件里面设置的 2047,所以振幅是大约 1.65V/ g. {! ?; p" P7 d

. b, q* L% S1 s0 `; _ ( @' T5 T% ~9 U" s- U: E

. Z+ Y' C% u  c4 H该三角波的产生是由单片机的硬件产生的,软件控制的是:振幅和周期;# a: G6 u$ r$ I, B  K! a
振幅通过上述寄存器中的 MAMP1 来控制;
$ V2 p' ?- ^, q. ?周期则是定时器 Tim6 的触发事件?
  W$ }) T" c* ^" g4 c# F但是这里的周期并不是 128us 啊?
8 n( ]0 p( N) l# l" r$ y8 c( t改变幅值也会改变三角波的周期的,# A+ g1 O0 J6 Q% x0 u
那么这幅值和周期以及定时器之间三者的关系如何呢?. _$ f+ f9 U  a3 W* f
答案:  g3 X3 U6 s& @  Z
# P+ c7 A$ l/ ~
  1. 因为每个时钟节拍才步进 1 格,如果是满幅值输出时,要步进 4095*2 个定时器时钟节拍。
    6 ?& m9 i0 J( K: E) h8 O7 Y
  2. 我的程序中,设定的幅值是 2047,所以输出一个三角波需要 2047*2 个时钟节拍;" a3 m* M# _& P2 z0 S1 k. Q3 ?3 y
  3. 一个时钟节拍在上面计算的 TIM6 的更新是大约 28us;所以周期 28*2047*2us;即大约是 115ms;
复制代码

. N, t* D$ A$ E1 C: G8 q3 T5 [; F0 Y3 T/ L' C7 L  b
PPH2K@RB]M6`O~W08AX3R~V.png
+ S0 B/ Z& m  s( p! Z# {' U* ?
% ]# m3 |& I  o6 E: g符合推论。
, ]  C: A2 u6 U4 e7 b& M设置的波形控制模式:WAVE1 = 0x02,即产生三角波;
, b7 E) ~5 _$ m+ _, e
( k/ k3 R( \$ l( u! X; _# I G5Q5A8[6VBWMIUJA6UNG28E.png
- l+ b3 v0 Y' w+ D4 d$ n3 o' e5 d# I
对于三角波的产生器,还有一段函数代码的作用是什么意思呢?- F2 ~" V0 r& r5 j

% w2 a( v# h+ J/ I7 T
" Y3 l4 x2 W* M# H: j+ o
  1. /*##-3- DAC channel2 Triangle Wave generation configuration ################*/! K2 N" t* t, ]6 w
  2. if (HAL_DACEx_TriangleWaveGenerate(&DacHandle, DACx_CHANNEL,2 o) e7 n* T  t% z
  3. DAC_TRIANGLEAMPLITUDE_2047) != HAL_OK)
    # ~) ^$ E5 X* g3 y: z$ Q2 C
  4. {, q0 l3 P" n$ W7 k3 Q
  5. /* Triangle wave generation Error *// g4 Q- T, g6 S' M/ a/ E2 s
  6. Error_Handler();
    * K& k1 o' I  J. P  {# ], i
  7. }
    - }8 Y6 n# J# c: u  Z: c
  8. #if 1$ D5 i3 Q/ w4 X6 ]
  9. /*##-4- Enable DAC Channel1 ################################################*/
    - X! i0 E/ y- }7 y& H
  10. if (HAL_DAC_Start(&DacHandle, DACx_CHANNEL) != HAL_OK), n% ?6 g& W8 M# k% p
  11. {
    ! Y$ ]! ^- z- J0 e5 w
  12. /* Start Error */
    7 Z" R% e$ c8 S: m; q/ {% n' }
  13. Error_Handler();2 c7 V3 M8 y; U1 S( a
  14. }! L3 j9 I4 P' v
  15. #endif6 c, R! b1 _" K- ^0 d2 n) j- s4 a
  16. #if 0
    . Z% C/ L& ~9 B, V5 s" j
  17. /*##-5- Set DAC channel1 DHR12RD register8 \% W0 b( I+ }# P
  18. ################################################*/
    ( i' H3 T7 O" H# u- T
  19. if (HAL_DAC_SetValue(&DacHandle, DACx_CHANNEL, DAC_ALIGN_12B_R, 0) != HAL_OK)7 n* L" }; \; j% B2 m2 w1 C
  20. {
    : ^8 \7 f& u0 |0 Z' w8 Y
  21. /* Setting value Error */4 j2 x, A  _+ `7 n0 H$ _  y8 @
  22. Error_Handler();
    , Z! q; h" A% L3 _1 D
  23. }
    7 K  U# a2 [2 s) h/ _; P3 I* q
  24. #endif
复制代码
3 D& k+ l. S) {. f4 H) _5 ^

* v3 y$ s3 ]9 @0 [即其中的代码:
, [5 @3 Y( O* g
  1. if (HAL_DAC_SetValue(&DacHandle, DACx_CHANNEL, DAC_ALIGN_12B_R, 0) != HAL_OK)" C. F/ U( U; @/ {
  2. {( d: N2 _& Z$ B& z) @
  3. /* Setting value Error */
    + Q$ E2 E+ {, K8 R0 {5 H3 s' o
  4. Error_Handler();, u0 ?4 k7 V+ Q7 T: n' n, s# q* H. Q
  5. }
复制代码
+ d, [. S5 r2 D  Z9 V- ], z
: F- `$ E- X9 ]1 j- l) W
是什么作用呢?" r) C: b! q- P) X
产生的波形:9 U2 Q) m- i+ H# w4 z( O
) w  U, C5 q8 `3 c7 E4 F
  1. /*##-5- Set DAC channel1 DHR12RD register6 L- G3 V4 _# t( X9 E
  2. ################################################*/
    * h; @- n2 @  z
  3. if (HAL_DAC_SetValue(&DacHandle, DACx_CHANNEL, DAC_ALIGN_12B_R, 0) != HAL_OK)
    3 I" T% {. q2 a- ^( {2 i/ `0 O& F
  4. {
    " m' ]- r/ P( b* h6 n
  5. /* Setting value Error */0 p' G2 i( M# ?7 C- t( y
  6. Error_Handler();
    / Q) k( m7 h, W# d. x  O( P+ _8 b
  7. }
复制代码
1 [' [& S4 [, H! ?' p8 e
0 P. p1 W% W! G2 q3 M1 v/ v' S3 H# X
PF95M`$(5D[@%V5]AW_1ZNJ.png * ^: p/ }" o4 L1 e
0 k4 {: [0 k, l: j9 u
在加了函数之后:
/ F. Q- b+ m9 @% H* z* X! |
  1. /*##-5- Set DAC channel1 DHR12RD register
    ' [/ S+ x4 `7 N) U
  2. ################################################*/" @* t$ w1 A8 O5 Z; a, \% O
  3. if (HAL_DAC_SetValue(&DacHandle, DACx_CHANNEL, DAC_ALIGN_12B_R, 10000) != HAL_OK)
    ; g! X" V* b3 e% O/ i+ y
  4. {
      r* Z; B0 b% y- b1 n
  5. /* Setting value Error */1 O) Y: J* Q& _& }
  6. Error_Handler();
    * q& a1 f3 A4 M2 Q3 }& T" |- X
  7. }
复制代码

! j" m) k' j+ b0 z. S0 C( ] 6KAJS6$~[D2BJK`TWFS~K(A.png ; y- H# q. k  H' ]! h
. Q# [' I! w, H$ C3 z6 J
从波形上来看,当参数数值不为 0 时,波形更像三角波,那这个参数影响的是什么呢?5 D, b" n$ c! p, m. c3 b: x

7 N' k( r7 [' z+ ^4 X' l HY$E2N_T)KB0(A9$)5RB$SN.png & D" E, ~3 u! _1 [
参数的 tmp 的值,位于 0x200004A4 处,初始值为 0,运行到:
  j& L+ Z. M/ v: Q" J
  1. tmp = (uint32_t)hdac->Instance;
复制代码

9 @) C% z1 S8 B, U1 Q
: F8 H8 m/ Z  \6 B8 ~后 tmp 的值为 0x40007400,该值是解释得通的:DAC 外设的基地址(0x40007400)
6 b3 w8 V! N6 d8 U6 s/ d  t$ Q9 h: T1 d- e2 `& Q8 c# {( w
0VFS)9`NB1@(H90VCS6HE{L.png 5 u. ^9 W6 H( g. y" G/ {& I
1 O- u2 b  V# z1 E; d9 N
执行完语句之后:由于传递的参数是#define DAC_ALIGN_12B_R                  ((uint32_t)0x00000000)7 v+ D8 |& \) ^" c* T, S- Z  `4 P; y
  1. DAC_DHR12R2_ALIGNMENT(Alignment);
复制代码
& M4 [# L; Z2 F6 K
得到的结果是(注意上图中虽然断点停在了 DAC_DHR12R2_ALIGNMENT 处,但是程序是 DAC_CHANNEL_1,所以最终执行的还是下面的语句)
& G: d  K" e8 w/ x: y/ d
  1. #define DAC_DHR12R1_ALIGNMENT(__ALIGNMENT__) (((uint32_t)0x00000008) + (__ALIGNMENT__))
复制代码
/ i' Q0 O/ [& s
所以最终产生的效果就是:
: e2 d4 |# f4 G0 w3 t- ]7 b7 B, O4 J
  1. *(__IO uint32_t *) tmp = Data;
复制代码

9 ^6 o# Y5 }* D4 e" m6 k1 I地址为 0x40007408 的寄存器赋值,即下面寄存器赋值:' A7 q! s" X, ]) A8 v% b% P+ G

. D  Z* c3 q! o9 U6 g $VY8TU)HK7YNVS7381$J1)9.png , \3 t: Y& e7 h0 ~( c/ c; [5 i8 [  t

- L" b& x3 p: f& J; J+ o但是这寄存器的作用是什么呢?holding data?' {6 ~3 p* Q3 t5 i
Holding data 寄存器,可以简单的理解为:
8 \0 Q  n5 C9 l  `7 c4 C4 O设置影响 DAC 的直流分量(直流分量还是根据下面的公式计算出来的):6 S& I1 I$ P! O* i0 R% T% b3 M

7 ~1 I( p; ?) p+ p0 k2 u
5 K! V3 a; y3 t, \$ J3 Q, x
* A5 \4 Q! A& U; n( ~0 X当传递的参数设置为 0 是,DACoutput 即三角波的最低电平为 0:" A# }2 @& K! S; q- A
当传递的参数设置为 2047,DACoutput 即三角波的最低电平为 1.65V1 Z; l& P' E3 h, M4 ^5 J' W3 f
( X6 S- h' t' X* C. g2 t
((~IQBBQ`%8]8OY$)C~ZSMG.png ' q' K1 P5 r5 Z' J( k/ A5 I

/ s  t6 g* k( w$ f4 }如果传递的参数设置为 1024,DACoutput 即三角波的最低电平为 0.82V;
! ^$ ?7 D8 }+ U% p- `
" B( a( @. h8 k, q4 D& L YKU_`@}WQ1HO[_64VHLHR~D.png 2 |9 v  C# o3 l8 I! w( l

; [; i9 P, A5 \7 V如果传递的参数设置为 3000,DACoutput 即三角波的最低电平为 2.42V;
8 `, C( ]) P. X2 I: m3 y9 ~6 V
7 {0 z2 Y/ N* V0 w! k8 q QO]W{{MY9ISBI`VH9NZ[25Q.png ' C, f9 m, v% x& C; h

3 ]# p% i! M( V  o$ R 50}5O~JR4M]C~)J04DY)~13.png ( Y  A/ I) W& Y8 w4 ^

4 r& z6 ~0 n& u( w, C5、噪声产生器$ p* ]# b& w( A/ ~0 D7 P8 D+ |0 m
主要函数的代码如下:
! k- ?: a$ x' c8 Q: A
  1. if (HAL_DACEx_NoiseWaveGenerate(&DacHandle, DACx_CHANNEL,
    7 B4 ]- F/ `+ I3 g
  2. DAC_TRIANGLEAMPLITUDE_2047) != HAL_OK)
      N: z- l7 j7 L& v+ G
  3. {
    & b4 R" b  r" m4 w9 Y, m# h' P
  4. /* Triangle wave generation Error */; c# U* X5 }, h2 r8 J" c% ^
  5. Error_Handler();
    : Y% m1 H4 g% {! t
  6. }
    - E, z4 n  x0 V: Z& }" ^9 J( U% A2 [/ }8 \
  7. /*##-4- Enable DAC Channel1 ################################################*/
    1 z( ?# E4 A- O" Q3 V
  8. if (HAL_DAC_Start(&DacHandle, DACx_CHANNEL) != HAL_OK)
    9 u9 ?+ {/ b$ A3 F5 {9 _
  9. {$ @9 [+ J& X$ W% v2 Z
  10. /* Start Error */
    ' O: N, i9 S6 ^3 b3 P" \. o
  11. Error_Handler();' H  ^2 S& w: _* q* g9 f* i
  12. }
复制代码
/ Z; z8 }8 q3 F0 A$ e% K

3 `& V5 x/ {# `' {4 }" R4 u: \' C4 I
由于一般的认为噪声是随机性的,所以可以认为只是修改幅值,对于其周期不可控;
% W$ G/ ?( @4 A  k
3 H  f; }, r: t( ]9 [3 `2 o7 l# }5 K* a5 n4 @

+ s0 u. e$ Q% {/ N2 G2 e
5 f) u- m) ]6 D! H) r3 V- y. t# _# {. n
1 P! W6 [4 B2 u) e; }
- \# Z5 I" Y; [# f( s
PDZKNYI_I07HJNH`(NQ2ANG.png
赞 收藏 评论0 发布时间:2022-2-23 18:36

举报

0个回答

所属标签

相似技术帖

官网相关资源

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