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

【经验分享】STM32之DAC君

[复制链接]
STMCU小助手 发布时间:2022-1-14 22:38
我们来看看STM32之DAC的Resume(简历简介):
101534479485393.png
   ● 2个DAC转换器:每个转换器对应1个输出通道
   ● 8位或者12位单调输出
   ● 12位模式下数据左对齐或者右对齐
   ● 同步更新功能
   ● 噪声波形生成
   ● 三角波形生成
   ● 双DAC通道同时或者分别转换
   ● 每个通道都有DMA功能
   ● 外部触发转换
   ● 输入参考电压VREF+
   哇、、哇、、哇、、好多特征呀、、还记得上篇博客中ADC也有很多功能吗?在这里,我觉得,因为其功能多、所以其复杂、、这也没什么奇怪的哈、、
   那我们今天要干嘛呢?DAC顾名思义,输入量是D,也就是D、、而输出量是A、也顾名思义、当然、对于聪明的你们来说D A代表哪个英文单词和普通话意思是知道的、
    由上图可以清晰的看出,DAC的输出是受DORX寄存器直接控制的,而用户的写的数据是写在DHRX寄存器里的、说明我们不能直接操控DORX,而要通过DORX间接操作DORX,从而实现对DAC的输出、
    今天我们是采用DAC的通道1,采用12位的右对齐方式,对于对齐方式,大家翻开中文参考手册可以看到:
       ● 单DAC通道x,有3种情况:
       ─ 8位数据右对齐:用户须将数据写入寄存器DAC_DHR8Rx[7:0]位(实际是存入寄存器DHRx[11:4]位)
       ─ 12位数据左对齐:用户须将数据写入寄存器DAC_DHR12Lx[15:4]位(实际是存入寄存器DHRx[11:0]位)
       ─ 12位数据右对齐:用户须将数据写入寄存器DAC_DHR12Rx[11:0]位(实际是存入寄存器DHRx[11:0]位)
       根据对DAC_DHRyyyx寄存器的操作,经过相应的移位后,写入的数据被转存到DHRx寄存器中(DHRx是内部的数据保存寄存器x)。随后,DHRx寄存器的内容或被自动地传送到DORx寄存器,或通过软件触发或外部事件触发被传送到DORx寄存器。(这段话也就是对上张图片的描述)
       接下来我们看看
      1、输入输出使能:
      通道使能控制:EN1@DAC_CR
      一旦通道使能,输出引脚PA.4就被自动连到模拟转换器的输出
      使能通道之前,PA.4要配置成模拟模式AIN
   
% s# d0 J4 S, {' a# X$ K" R      该使能信号只使能了模拟部分,数字接口部分由DACEN@RCC_APB1ENR控制WAKEUP
: b6 R( V* t0 R      经过t WAKEUP时间后DAC通道准备就绪
# J5 s3 w; Y; X8 W5 r# R/ ~; ?      DAC通道上的引脚输出模拟电压 = VREF+ * (DOR / 4095)9 O3 ?- G5 m" c1 |7 `
      输出通道上集成可配置的输出缓冲,以减小自身的输出阻抗+ J$ Y/ ^3 H& s% U
      使能控制:BOFF1@DAC_CR
     2、输出通道上的缓冲:
      通道内嵌输出缓冲以增加驱动能力     
      外部负载较大时,无需增加外部放大器
      可使能或禁止该缓冲
      外部有大负载,且缓冲禁止时,输出电压可能达不到预期
      介绍两张图片:大家可以对比对比下,在这就不细讲了、
101606335429495.png   
101606421671231.png
3、DAC的转换过程:
    用户写入DAC_DHRx的值,自动或者在外部触发条件下经过一段时间后,传输到DAC_DORx;再经过一段固定时间tSETTLING,在外部引脚输出转换后的模拟信号(电压)。
        (1)对DAC_DHRx的写操作
) S' P9 S) z( A+ W: s( ?& G      (2)数据从DHRx到DORx的搬移, c4 i0 B/ s. X3 k4 ]
      (3)输出电压信号到外部引脚
我们来看看寄存器DAC控制寄存器(DAC_CR)
     DMAEN1:DAC通道1 DMA使能 (DAC channel1 DMA enable),我们不使用DMA,故设置为0
     MAMP1[3:0]:DAC通道1屏蔽/幅值选择器 (DAC channel1 mask/amplitude selector)我们没有用到 故这几位也设置为0
     WAVE1[1:0]:DAC通道1噪声/三角波生成使能 (DAC channel1 noise/triangle wave generation enable)我们也没用到 故也设置为0
     TEN1:DAC通道1触发使能 (DAC channel1 trigger enable)我们不用触发,所以设置为0
     TSEL1[2:0]:DAC通道1触发选择 (DAC channel1 trigger selection)注意:该位只能在TEN1= 1(DAC通道1触发使能)时设置。我们TEN1设为0,所以这几位就不用设置,默认为04 Y6 Y) m2 C7 M, g! ?7 ^+ S6 ]
     BOFF1:关闭DAC通道1输出缓存 (DAC channel1 output buffer disable)我们关闭输出缓冲 故设置为1
     EN1:DAC通道1使能 (DAC channel1 enable)我们要使能DAC通道、故设置为1
    至此,我们已经设置了以上寄存器,我们就可以操作DAC了,但是我们并不是通过寄存器操作的、在这里摆出寄存器的设置,是为了大家有一个更好的了解,那我们打开"stm32f10x_dac.h"
     可以看到:
  1. typedef struct
    % R+ I  g& U7 R4 n- ^4 U# O' Q' w
  2. {2 I; _3 l% L7 |6 r1 O5 u
  3.   uint32_t DAC_Trigger;                      /*!< Specifies the external trigger for the selected DAC channel.设置是否使用触发功能
    ) [4 Q0 c5 g) Q
  4.                                                   This parameter can be a value of @ref DAC_trigger_selection */
    * J6 m% Z3 F4 y4 G: [$ r9 j

  5. : V. O; `% Q4 g% N5 e( r3 O
  6.   uint32_t DAC_WaveGeneration;               /*!< Specifies whether DAC channel noise waves or triangle waves设置是否使用波形发生
    ' U% W* j5 M- m! W
  7.                                                   are generated, or whether no wave is generated.
    4 d, `# W8 _" ?6 T7 z2 d
  8.                                                   This parameter can be a value of @ref DAC_wave_generation */" o% M/ b! I2 c8 F' W

  9. 0 L4 ?- H. o1 Q% D
  10.   uint32_t DAC_LFSRUnmask_TriangleAmplitude; /*!< Specifies the LFSR mask for noise wave generation or设置屏蔽/幅值选择器. I" H( |5 Y0 R* _# \! L
  11.                                                   the maximum amplitude triangle generation for the DAC channel. " Y9 J) N& e; C% \2 }
  12.                                                   This parameter can be a value of @ref DAC_lfsrunmask_triangleamplitude */
      f' A0 D6 S" s3 W! d

  13. # h1 x6 r3 g+ o+ Z
  14.   uint32_t DAC_OutputBuffer;                 /*!< Specifies whether the DAC channel output buffer is enabled or disabled.设置输出缓存控制位
复制代码
! U7 S( x* x1 c
& x6 v& z" N, Z* {+ B1 L2 @% n; X
     根据以上说明,具体的设置请看代码、、
   那好、、现在我们来看看具体的步骤:
  1、使能DAC的时钟和GPIOA的时钟,并配置GPIOA
  2、设置DAC的工作模式等功能
  3、使能DAC通道
  4、设置DAC的输出值
  1. void Dac1_Init(void); z- p/ g6 W. s3 e) G/ T
  2. {
    $ c$ W1 o0 [5 a' D* j
  3.    DAC_InitTypeDef  DAC_InitStructure;
    " E. V5 z/ B8 \- m: x. F8 p
  4.      GPIO_InitTypeDef GPIO_InitStructure;
    9 h" h2 Z! _+ u7 |0 L, \. F
  5. 6 N4 b" n7 r' R5 S, n+ Q0 K  h# M
  6.     /* Enable peripheral clocks ------------------------------------------------*/8 Q( m& r; C. y3 B* D( N7 D! M
  7.   /* GPIOA Periph clock enable */
    . C& f/ K& j# d
  8.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);2 }: h  S, ]& f0 S7 p
  9.   /* DAC Periph clock enable */
      J/ M5 o* }. d3 P
  10.   RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);
    ! S$ f7 J7 {& c4 E! c" }
  11.     - N. x2 L, k* F% k
  12.   /* Once the DAC channel is enabled, the corresponding GPIO pin is automatically 7 ]* Q( j4 `* s! m
  13.      connected to the DAC converter. In order to avoid parasitic consumption, 8 o/ l1 r+ D+ B! k# G: Z: _: T
  14.      the GPIO pin should be configured in analog */
    " N& c6 R9 Y' W
  15.   GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_4;
    8 E' [8 A- X. }8 }) V
  16.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;; t7 o1 Q& \7 ~0 n2 [' `
  17.   GPIO_Init(GPIOA, &GPIO_InitStructure);  \. `% Y# p- L/ q! C2 g1 ]6 @
  18.     GPIO_SetBits(GPIOA,GPIO_Pin_4);
    : p" W& x0 i+ j" B8 n- n
  19.      /* DAC channel1 Configuration */2 }* _# X% |9 w6 ~  i9 k
  20.   DAC_InitStructure.DAC_Trigger = DAC_Trigger_None;$ N2 z1 p( c2 A
  21.   DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;
    4 w5 c9 e) ?$ j5 m5 x+ B+ d7 G
  22.   DAC_InitStructure.DAC_LFSRUnmask_TriangleAmplitude = DAC_LFSRUnmask_Bit0;6 N9 V- p! J/ j1 ?
  23.   DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Disable;; D) D, e+ w( ?3 ~! T+ U
  24.   DAC_Init(DAC_Channel_1, &DAC_InitStructure);) f, z1 N  s# s& [8 O! N% B
  25.     ' ^' V4 p! `" v. V8 L9 O
  26.   /* Enable DAC Channel1: Once the DAC channel1 is enabled, PA.04 is
    ( \7 I: i9 V0 ~& s& Y, T
  27.      automatically connected to the DAC converter. */% ]' Q$ ^/ R$ o2 I- G- v" `1 }# B
  28.   DAC_Cmd(DAC_Channel_1, ENABLE);
    $ j( S( h3 A& Q; S, S1 q9 Z
  29.     , [2 \7 b4 A! |7 V. |; O
  30.       /* Set DAC Channel1 DHR12L register *初始化/
    4 S! s+ ^2 v0 U' R( y; j6 g8 y
  31.   DAC_SetChannel1Data(DAC_Align_12b_R, 0);+ t/ l; l- X( q/ p
  32. ) ^1 r- ^, e4 ?2 t3 X
  33. }
    + u+ F1 U3 w. w% z
  34. //设置DAC通道的值我们可以通过按键   例如  P# M6 J" |% w$ u  i
  35. if(按键按下)" ~9 l1 E. d/ t' f- R, T  D, D
  36. {
    / @* U6 X: K+ ^: _2 t
  37.    delay_ms(10);
    9 I) u8 ~, h# ?. D3 _, q- U( p, e
  38. 3 C' H( N, N, g( t9 e: `# C9 b
  39. DAC_SetChannel1Data(DAC_Align_12b_R, a += 200);
    ) o+ V9 A4 ]7 y6 @5 ]( ~
  40.   if(a>4000)
    * {: H. [4 q1 |) b4 M9 |
  41. {- N; l) B4 ^6 L6 W3 g
  42. a = 0;! P9 [1 M* T' T) L- o( R  Y  ?
  43. }4 [) R& y' D0 x9 i+ R- ~
  44. }$ m' r$ m$ |% a
  45. ,或者由ADC转换后的值,给DAC采集' G7 }* G1 }- `& L  z' V7 {
  46.   adcx=DAC_GetDataOutputValue(DAC_Channel_1);//通过此函数我们可以读取设置DAC通道里的值也就是DOR里的数(0~4095)- A& \6 Q* n- x# E7 n( c) A( S1 l
  47.   DAC通道上的引脚输出模拟电压 = VREF+ * (DOR / 4095)//根据此公式就可以计算出模拟输出电压、、0 X# |9 c( C4 c0 c; F
  48. 此模拟电压又可以被ADC采集,从而输出(0~4095),你可以把两者结合起来,通过一定的编程,通过串口发送到窗口,看你设置的值和经ADC转换的值(0~4095)是否相等
    ) h- r1 ]6 i, P8 Z5 |1 c8 L) h5 g

  49. ! [, v# X( R/ q* b& o6 z  r7 o4 t
  50. PS:此步骤也可以在官方的例程里找到步骤哈、、
复制代码

( g4 x) a' p) X
2 _+ ~3 z. ?) m4 X% v
3 R! E5 I4 N3 W/ ^: D( p0 M- a. g5 z: i, u: T
赞 收藏 评论0 发布时间:2022-1-14 22:38

举报

0个回答

所属标签

相似技术帖

官网相关资源

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