第十五章 DAC (上篇)

第十五章 DAC (上篇)

目录

第十五章 DAC (上篇)

1 DAC简介

2 DAC主要特征

3 DAC功能描述

3.1 使能DAC通道

3.2 使能DAC输出缓存

3.3 DAC数据格式

3.4 DAC转换

3.5 DAC输出电压

3.6 选择DAC触发

3.7 DMA请求

3.8 噪声生成

3.9 三角波生成

4 双DAC通道转换

4.1 不使用波形发生器的独立触发

4.2 使用相同LFSR的独立触发

4.3 使用不同LFSR的独立触发

4.4 产生相同三角波的独立触发

4.5 产生不同三角波的独立触发

4.6 同时软件启动

4.7 不使用波形发生器的同时触发

4.8 使用相同LFSR的同时触发

4.9 使用不同LFSR的同时触发

4.10 使用相同三角波发生器的同时触发

4.11 使用不同三角波发生器的同时触发

5 例程设计

5.1 DAC_OutAudio例程

6 下载验证

5.2 DAC_OutAudio例程


1 DAC简介

数字/模拟转换模块(DAC)是 12 位数字输入,电压输出的数字/模拟转换器。DAC 可以配置为 8 位或 12 位模式,也可以与 DMA 控制器配合使用。DAC 工作在 12 位模式时,数据可以设置成左对齐或右对。DAC 模块有 2 个输出通道,每个通道都有单独的转换器。在双 DAC 模式下,2 个通道可以独立地进行转换,也可以同时进行转换并同步地更新 2 个通道的输出。DAC 可以通过引脚输入参考电压 VREF+以获得更精确的转换结果。

2 DAC主要特征

  • 2 个 DAC 转换器:每个转换器对应 1 个输出通道
  • 8 位或者 12 位单调输出
  • 12 位模式下数据左对齐或者右对齐
  • 同步更新功能
  • 噪声波形生成
  • 三角波形生成
  • 双 DAC 通道同时或者分别转换
  • 每个通道都有 DMA 功能
  • 外部触发转换
  • 输入参考电压 VREF+

DAC通道模块框图如下:

DAC 通道模块框图

名称

型号类型

注释

VREF+

输入,正模拟参考电压

DAC使用的高端/正极参考电压,2.4V≤VREF+≤VDDA(3.3V)

VDDA

输入,模拟电源

模拟电源

VSSA

输入,模拟电源地

模拟电源的地线

DAC_OUTx

模拟输出信号

DAC通道x的模拟输出

注意: 一旦使能 DACx 通道,相应的 GPIO 引脚(PA4 或者 PA5)就会自动与 DAC 的模拟输出相连(DAC_OUTx)。为了避免寄生的干扰和额外的功耗,引脚 PA4 或者 PA5 在之前应当设置成模拟输入(AIN)。

3 DAC功能描述

3.1 使能DAC通道

将 DAC_CR 寄存器的 ENx 位置'1'即可打开对 DAC 通道 x 的供电。经过一段启动时间 tWAKEUP,DAC 通道 x 即被使能。注意: ENx 位只会使能 DAC 通道 x 的模拟部分,即便该位被置'0',DAC 通道 x 的数字部分仍然工作

3.2 使能DAC输出缓存

DAC 集成了 2 个输出缓存,可以用来减少输出阻抗,无需外部运放即可直接驱动外部负载。每个DAC 通道输出缓存可以通过设置 DAC_CR 寄存器的 BOFFx 位来使能或者关闭。

3.3 DAC数据格式

根据选择的配置模式,数据按照下文所述写入指定的寄存器:

  • 单 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 寄存器。

单 DAC 通道模式的数据寄存器

  • 双 DAC 通道,有 3 种情况:
    • 8 位数据右对齐:用户须将 DAC 通道 1 数据写入寄存器 DAC_DHR8RD[7:0]位(实际是存入寄存器 DHR1[11:4]位),将 DAC 通道 2 数据写入寄存器DAC_DHR8RD[15:8]位(实际是存入寄存器 DHR2[11:4]位)
    • 12 位数据左对齐:用户须将 DAC 通道 1 数据写入寄存器 DAC_DHR12LD[15:4]位(实际是存入寄存器 DHR1[11:0]位),将 DAC 通道 2 数据写入寄存器 DAC_DHR12LD[31:20]位(实际是存入寄存器 DHR2[11:0]位)
    • 12 位数据右对齐:用户须将 DAC 通道 1 数据写入寄存器 DAC_DHR12RD[11:0]位(实际是存入寄存器 DHR1[11:0]位),将 DAC 通道 2 数据写入寄存器 DAC_DHR12RD[27:16]位(实际是存入寄存器 DHR2[11:0]位)

根据对 DAC_DHRyyyD 寄存器的操作,经过相应的移位后,写入的数据被转存到 DHR1 和 DHR2 寄存器中(DHR1 和 DHR2 是内部的数据保存寄存器 x)。随后,DHR1 和 DHR2 的内容或被自动地传送到 DORx 寄存器,或通过软件触发或外部事件触发被传送到 DORx 寄存器。

双 DAC 通道模式的数据寄存器

3.4 DAC转换

不能直接对寄存器 DAC_DORx 写入数据,任何输出到 DAC 通道 x 的数据都必须写入 DAC_DHRx 寄存器(数据实际写入DAC_DHR8Rx、DAC_DHR12Lx、DAC_DHR12Rx、DAC_DHR8RD、DAC_DHR12LD、或者 DAC_DHR12RD 寄存器)。

如果没有选中硬件触发(寄存器 DAC_CR1 的 TENx 位置'0'),存入寄存器 DAC_DHRx 的数据会在一个 APB1 时钟周期后自动传至寄存器 DAC_DORx。如果选中硬件触发(寄存器 DAC_CR1 的 TENx 位置'1'),数据传输在触发发生以后 3 个 APB1 时钟周期后完成。一旦数据从 DAC_DHRx 寄存器装入 DAC_DORx 寄存器,在经过时间 tSETTLING 之后,输出即有效,这段时间的长短依电源电压和模拟输出负载的不同会有所变化。

TEN=0 触发失能时转换的时间框图

3.5 DAC输出电压

数字输入经过 DAC 被线性地转换为模拟电压输出,其范围为 0 到 VREF+。

任一 DAC 通道引脚上的输出电压满足下面的关系:

  • DAC 输出=VREFx(DOR/4095)。

3.6 选择DAC触发

如果 TENx 位被置 1,DAC 转换可以由某外部事件触发(定时器计数器、外部中断线)。配置控制TSELx[2:0]可以选择 8 个触发事件之一触发 DAC 转换。

触发源

类型

TSELx[2:0]

定时器 6TRGO 事件

来自片上定时器的内部信号

000

定时器 8TRGO 事件

001

定时器 7TRGO 事件

010

定时器 5TRGO 事件

011

定时器 2TRGO 事件

100

每次 DAC 接口侦测到来自选中的定时器 TRGO 输出,或者外部中断线 9 的上升沿,最近存放在寄存器 DAC_DHRx 中的数据会被传送到寄存器 DAC_DORx 中。在 3 个 APB1 时钟周期后,寄存器DAC_DORx 更新为新值。

如果选择软件触发,一旦 SWTRIG 位置'1',转换即开始。在数据从 DAC_DHRx 寄存器传送到DAC_DORx 寄存器后,SWTRIG 位由硬件自动清'0'。

注意: 1.不能在 ENx 为'1'时改变 TSELx[2:0]位。2.如果选择软件触发,数据从寄存器 DAC_DHRx 传送到寄存器 DAC_DORx 只需要一个 APB1 时钟周期。

3.7 DMA请求

任一 DAC 通道都具有 DMA 功能。2 个 DMA 通道可分别用于 2 个 DAC 通道的 DMA 请求。如果DMAENx 位置'1',一旦有外部触发(而不是软件触发)发生,则产生一个 DMA 请求,然后DAC_DHRx 寄存器的数据被传送到 DAC_DORx 寄存器。

在双 DAC 模式下,如果 2 个通道的 DMAENx 位都为'1',则会产生 2 个 DMA 请求。如果实际只需要一个 DMA 传输,则应只选择其中一个 DMAENx 位置'1'。这样,程序可以在只使用一个 DMA 请求,一个DMA 通道的情况下,处理工作在双 DAC 模式的 2 个 DAC 通道。DAC 的 DMA 请求不会累计,因此如果第 2 个外部触发发生在响应第 1 个外部触发之前,则不能处理第 2 个 DMA 请求,也不会报告错误。

3.8 噪声生成

可以利用线性反馈移位寄存器(Linear Feedback Shift Register LFSR)产生幅度变化的伪噪声。设置WAVE[1:0]位为'01'选择DAC噪声生成功能。寄存器LFSR的预装入值为0xAAA。按照特定算法,在每次触发事件后 3 个 APB1 时钟周期之后更新该寄存器的值。

DACLFSR 寄存器算法

设置 DAC_CR 寄存器的 MAMPx[3:0]位可以屏蔽部分或者全部 LFSR 的数据,这样的得到的 LSFR 值与 DAC_DHRx 的数值相加,去掉溢出位之后即被写入 DAC_DORx 寄存器。

如果寄存器 LFSR 值为 0x000,则会注入'1'(防锁定机制)。将 WAVEx[1:0]位置'0'可以复位 LFSR 波形的生成算法。

带 LFSR 波形生成的 DAC 转换(使能软件触发)

3.9 三角波生成

可以在 DC 或者缓慢变化的信号上加上一个小幅度的三角波。设置 WAVEx[1:0]位为'10'选择 DAC 的三角波生成功能。设置 DAC_CR 寄存器的 MAMPx[3:0]位来选择三角波的幅度。内部的三角波计数器每次触发事件之后 3 个 APB1 时钟周期后累加 1。计数器的值与 DAC_DHRx 寄存器的数值相加并丢弃溢出位后写入 DAC_DORx 寄存器。在传入 DAC_DORx 寄存器的数值小于 MAMP[3:0]位定义的最大幅度时,三角波计数器逐步累加。一旦达到设置的最大幅度,则计数器开始递减,达到 0 后再开始累加,周而复始。

将 WAVEx[1:0]位置'0'可以复位三角波的生成。

DAC 三角波生成

带三角生成的 DAC 转换(使能软件触发)

注意: 1.为了产生三角波,必须使能 DAC 触发,即设 DAC_CR 寄存器的 TENx 位为'1'。

MAMP[3:0]位必须在使能 DAC 之前设置,否则其值不能修改。

4 双DAC通道转换

在需要 2 个 DAC 同时工作的情况下,为了更有效地利用总线带宽,DAC 集成了 3 个供双 DAC 模式使用的寄存器:DHR8RD、DHR12RD 和 DHR12LD,只需要访问一个寄存器即可完成同时驱动 2 个DAC 通道的操作。

对于双 DAC 通道转换和这些专用寄存器,共有 11 种转换模式可用。这些转换模式在只使用一个DAC 通道的情况下,仍然可通过独立的 DHRx 寄存器操作。

4.1 不使用波形发生器的独立触发

按照下列顺序设置 DAC 工作在此转换模式:

  • 分别设置 2 个 DAC 通道的触发使能位 TEN1 和 TEN2 为'1';
  • 通过设置 TSEL1[2:0]和 TSEL2[2:0]位为不同值,分别配置 2 个 DAC 通道的不同触发源;
  • 将双 DAC 通道转换数据装入所需的 DHR 寄存器(DHR12RD、DHR12LD 或 DHR8RD)。

当发生 DAC 通道 1 触发事件时,(延迟 3 个 APB1 时钟周期后)寄存器 DHR1 的值传入寄存器DAC_DOR1。

当发生 DAC 通道 2 触发事件时,(延迟 3 个 APB1 时钟周期后)寄存器 DHR2 的值传入寄存器DAC_DOR2。

4.2 使用相同LFSR的独立触发

按照下列顺序设置 DAC 工作在此转换模式:

  • 分别设置 2 个 DAC 通道的触发使能位 TEN1 和 TEN2 为'1';
  • 通过设置 TSEL1[2:0]和 TSEL2[2:0]位为不同值,分别配置 2 个 DAC 通道的不同触发源;
  • 设置 2 个 DAC 通道的 WAVEx[1:0]位为”01”,并设置 MAMPx[3:0]为相同的 LFSR 屏蔽值;
  • 将双 DAC 通道转换数据装入所需的 DHR 寄存器(DHR12RD、DHR12LD 或 DHR8RD)。

当发生 DAC 通道 1 触发事件时,具有相同屏蔽的 LFSR1 计数器值与 DHR1 寄存器数值相加,(延迟3 个 APB1 时钟周期后)结果传入寄存器 DAC_DOR1,然后更新 LFSR1 计数器。当发生 DAC 通道 2 触发事件时,具有相同屏蔽的 LFSR2 计数器值与 DHR2 寄存器数值相加,(延迟3 个 APB1 时钟周期后)结果传入寄存器 DAC_DOR2,然后更新 LFSR2 计数器。

4.3 使用不同LFSR的独立触发

按照下列顺序设置 DAC 工作在此转换模式:

  • 分别设置 2 个 DAC 通道的触发使能位 TEN1 和 TEN2 为'1';
  • 通过设置 TSEL1[2:0]和 TSEL2[2:0]位为不同值,分别配置 2 个 DAC 通道的不同触发源;
  • 设置 2 个 DAC 通道的 WAVEx[1:0]位为”01”,并设 MAMPx[3:0]为不同的 LFSR 屏蔽值;
  • 将双 DAC 通道转换数据装入所需的 DHR 寄存器(DHR12RD、DHR12LD 或者 DHR8RD)。

当发生 DAC 通道 1 触发事件时,按照 MAMP1[3:0]所设屏蔽的 LFSR1 计数器值与 DHR1 寄存器数值相加,(延迟 3 个 APB1 时钟周期后)结果传入寄存器 DAC_DOR1,然后更新 LFSR1 计数器。当发生 DAC 通道 2 触发事件时,按照 MAMP2[3:0]所设屏蔽的 LFSR2 计数器值与 DHR2 寄存器数值相加,(延迟 3 个 APB1 时钟周期后)结果传入寄存器 DAC_DOR2,然后更新 LFSR2 计数器。

4.4 产生相同三角波的独立触发

按照下列顺序设置 DAC 工作在此转换模式:

  • 分别设置 2 个 DAC 通道的触发使能位 TEN1 和 TEN2 为'1';
  • 通过设置 TSEL1[2:0]和 TSEL2[2:0]位为不同值,分别配置 2 个 DAC 通道的不同触发源;
  • 设置 2 个 DAC 通道的 WAVEx[1:0]位为”1x”,并设 MAMPx[3:0]为相同的三角波幅值;

将双 DAC 通道转换数据装入所需的 DHR 寄存器(DHR12RD、DHR12LD 或 DHR8RD)。

当发生 DAC 通道 1 触发事件时,相同的三角波幅值加上 DHR1 寄存器的值,(延迟 3 个 APB1 时钟周期后)结果传入寄存器 DAC_DOR1,然后更新 DAC 通道 1 三角波计数器。

当发生 DAC 通道 2 触发事件时,相同的三角波幅值加上 DHR2 寄存器的值,(延迟 3 个 APB1 时钟周期后)结果传入寄存器 DAC_DOR2,然后更新 DAC 通道 2 三角波计数器。

4.5 产生不同三角波的独立触发

按照下列顺序设置 DAC 工作在此转换模式:

  • 分别设置 2 个 DAC 通道的触发使能位 TEN1 和 TEN2 为'1';
  • 通过设置 TSEL1[2:0]和 TSEL2[2:0]位为不同值,分别配置 2 个 DAC 通道的不同触发源;
  • 设置 2 个 DAC 通道的 WAVEx[1:0]位为'1x',并设 MAMPx[3:0]为不同的三角波幅值。
  • 将双 DAC 通道转换数据装入所需的 DHR 寄存器(DHR12RD、DHR12LD 或 DHR8RD)。

当发生 DAC 通道 1 触发事件时,MAMP1[3:0]所设的三角波幅值加上 DHR1 寄存器数值,(延迟 3 个APB1 时钟周期后)结果传入寄存器 DAC_DOR1,然后更新 DAC 通道 1 三角波计数器。

当发生 DAC 通道 2 触发事件时,MAMP2[3:0]所设的三角波幅值加上 DHR2 寄存器数值,(延迟 3 个APB1 时钟周期后)结果传入寄存器 DAC_DOR2,然后更新 DAC 通道 2 三角波计数器。

4.6 同时软件启动

按照下列过程设置 DAC 工作在此转换模式:

  • 将双 DAC 通道转换数据装入所需的 DHR 寄存器(DHR12RD、DHR12LD 或 DHR8RD)。在此配置下,一个 APB1 时钟周期后,DHR1 和 DHR2 寄存器的数值即被分别传入 DAC_DOR1 和DAC_DOR2 寄存器。

4.7 不使用波形发生器的同时触发

按照下列顺序设置 DAC 工作在此转换模式:

  • 分别设置 2 个 DAC 通道的触发使能位 TEN1 和 TEN2 为'1';
  • 通过设置 TSEL1[2:0]和 TSEL2[2:0]位为相同值,分别配置 2 个 DAC 通道使用相同触发源;
  • 将双 DAC 通道转换数据装入所需的 DHR 寄存器(DHR12RD、DHR12LD 或 DHR8RD)。

当发生触发事件时,(延迟 3 个 APB1 时钟周期后)DHR1 和 DHR2 寄存器的数值分别传入 DAC_DOR1和 DAC_DOR2 寄存器。

4.8 使用相同LFSR的同时触发

按照下列顺序设置 DAC 工作在此转换模式:

  • 分别设置 2 个 DAC 通道的触发使能位 TEN1 和 TEN2 为'1';
  • 通过设置 TSEL1[2:0]和 TSEL2[2:0]位为相同值,分别配置 2 个 DAC 通道使用相同触发源;
  • 设置 2 个 DAC 通道的 WAVEx[1:0]位为”01”,并设 MAMPx[3:0]为相同的 LFSR 屏蔽值;
  • 将双 DAC 通道转换数据装入所需的 DHR 寄存器(DHR12RD、DHR12LD 或 DHR8RD);

当发生触发事件时,MAMP1[3:0]所设屏蔽的 LFSR1 计数器值与 DHR1 寄存器的数值相加,(延迟 3个 APB1 时钟周期后)结果传入 DAC_DOR1 寄存器,然后更新 LFSR1 计数器。同样,MAMP1[3:0]所设屏蔽的 LFSR2 计数器值与 DHR2 寄存器的数值相加,(延迟 3 个 APB1 时钟周期后)结果传入寄存器 DAC_DOR2,然后更新 LFSR2 计数器。

4.9 使用不同LFSR的同时触发

按照下列顺序设置 DAC 工作在此转换模式:

  • 分别设置 2 个 DAC 通道的触发使能位 TEN1 和 TEN2 为'1';
  • 通过设置 TSEL1[2:0]和 TSEL2[2:0]位为相同值,分别配置 2 个 DAC 通道使用相同触发源;
  • 设置 2 个 DAC 通道的 WAVEx[1:0]位为'01',并设 MAMPx[3:0]为不同的 LFSR 屏蔽值;
  • 将双 DAC 通道转换数据装入所需的 DHR 寄存器(DHR12RD、DHR12LD 或 DHR8RD)。

当发生触发事件时,具有相同屏蔽的 LFSR1 计数器值与 DHR1 寄存器数值相加,(延迟 3 个 APB1时钟周期后)结果传入寄存器 DAC_DOR1,然后更新 LFSR1 计数器。同时,具有相同屏蔽的 LFSR2 计数器值与 DHR2 寄存器数值相加,(延迟 3 个 APB1 时钟周期后)结果传入寄存器 DAC_DOR2,然后更新 LFSR2 计数器。

4.10 使用相同三角波发生器的同时触发

按照下列顺序设置 DAC 工作在此转换模式:

  • 分别设置 2 个 DAC 通道的触发使能位 TEN1 和 TEN2 为'1':
  • 通过设置 TSEL1[2:0]和 TSEL2[2:0]位为相同值,分别配置 2 个 DAC 通道使用相同触发源。
  • 设置 2 个 DAC 通道的 WAVEx[1:0]位为'1x',并设 MAMPx[3:0]为相同的三角波幅值。将双 DAC 通道转换数据装入所需的 DHR 寄存器(DHR12RD、DHR12LD 或 DHR8RD)。

当发生触发事件时,相同的三角波幅值与 DHR1 寄存器数值相加,(延迟 3 个 APB1 时钟周期后)结果传入寄存器 DAC_DOR1,然后更新 LFSR1 计数器。同时,相同的三角波幅值与 DHR2 寄存器数值相加,(延迟 3 个 APB1 时钟周期后)结果传入寄存器DAC_DOR2,然后更新 LFSR2 计数器。

4.11 使用不同三角波发生器的同时触发

按照下列顺序设置 DAC 工作在此转换模式:

  • 分别设置 2 个 DAC 通道的触发使能位 TEN1 和 TEN2 为'1':
  • 通过设置 TSEL1[2:0]和 TSEL2[2:0]位为相同值,分别配置 2 个 DAC 通道使用相同触发源。
  • 设置 2 个 DAC 通道的 WAVEx[1:0]位为'1x',并设 MAMPx[3:0]为不同的三角波幅值。
  • 将双 DAC 通道转换数据装入所需的 DHR 寄存器(DHR12RD、DHR12LD 或 DHR8RD)。

当发生触发事件时,MAMP1[3:0]所设的三角波幅值与 DHR1 寄存器数值相加,(延迟 3 个 APB1 时钟周期后)结果传入寄存器 DAC_DOR1,然后更新 LFSR1 计数器。同时,MAMP2[3:0]所设的三角波幅值与 DHR2 寄存器数值相加,(延迟 3 个 APB1 时钟周期后)结果传入寄存器 DAC_DOR2,然后更新 LFSR2 计数器。

5 例程设计

5.1 DAC_OutAudio例程

1.UART 模块:配置 USART1,波特率为 115200,将printf输出重定向到该串口,用于输出系统时钟信息与测试提示。

// UART初始化函数
void UART_Configuration(uint32_t bound)
{
    GPIO_InitTypeDef  GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;

    // 使能USART1和GPIOA时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);

    // 配置TX引脚(PA9)为复用推挽输出
    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    // 配置RX引脚(PA10)为浮空输入
    GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    // 配置串口参数:115200bps,8位数据,1位停止位
    USART_InitStructure.USART_BaudRate = bound;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_Parity = USART_Parity_No;
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

    USART_Init(USART1, &USART_InitStructure);
    USART_Cmd(USART1, ENABLE);
}

// 重定向printf函数到USART1
int SER_PutChar(int ch)
{
    while (!USART_GetFlagStatus(USART_TEST, USART_FLAG_TC)); // 等待发送完成
    USART_SendData(USART_TEST, (uint8_t)ch);
    return ch;
}

int fputc(int c, FILE *f)
{
    if (c == '\n') SER_PutChar('\r'); // 自动添加回车符
    return SER_PutChar(c);
}

2.GPIO 模块:使能 GPIOA 时钟,把引脚 4 和 5 配置成模拟输入模式,为 DAC 输出做准备。

3.DAC 模块:使能 DAC 时钟,对 DAC 通道 1 和通道 2 进行初始化,设置初始输出值,将触发源设为定时器 2 的触发输出,同时使能 DMA 请求。

4.定时器模块:使能定时器 2 时钟,配置其参数以产生 8kHz 的更新事件,将更新事件选为触发输出。

5.DMA 模块:使能 DMA2 时钟,配置通道 4 和通道 3,将Sine12bit数组的数据循环传输到 DAC2 和 DAC1 的数据寄存器。

void DMA_Configuration(void)
{
    DMA_InitTypeDef DMA_InitStructure;

    // 使能DMA2时钟
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);

    // 配置DMA2通道4(DAC2)
    DMA_InitStructure.DMA_PeripheralBaseAddr = DAC2_DHR12RD_ADDRESS; // DAC2数据寄存器地址
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&Sine12bit;      // 数据源:正弦波数组
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;                // 内存到外设
    DMA_InitStructure.DMA_BufferSize = DATA_LEN;                      // 传输长度
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;           // 内存地址递增
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; // 16位数据
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;                   // 循环模式
    DMA_Init(DMA2_Channel4, &DMA_InitStructure);
    DMA_Cmd(DMA2_Channel4, ENABLE);

    // 配置DMA2通道3(DAC1,参数与通道4相同)
    DMA_InitStructure.DMA_PeripheralBaseAddr = DAC1_DHR12RD_ADDRESS;
    DMA_Init(DMA2_Channel3, &DMA_InitStructure);
    DMA_Cmd(DMA2_Channel3, ENABLE);
}
  1. 数据转换模块:把 8 位数据转换为 12 位数据,存于Sine12bit数组。

6 下载验证

6.2 DAC_OutAudio例程

初始输出

在 DAC 配置过程中,代码会先将 DAC 通道 1 和通道 2 的输出设置为一个初始值(代码中设置为 3102)。因此,在程序启动的瞬间,DAC 的两个通道会输出对应于该初始值的电压信号。

在完成所有配置后,DMA 会将Sine12bit数组中的数据循环传输到 DAC 的数据寄存器,同时定时器 TIM2 会以 8kHz 的频率产生触发信号,触发 DAC 进行数模转换。因此,DAC 的两个通道会持续输出软件生成的正弦波信号。

  • 频率:由于定时器 TIM2 的周期设置为 8999,预分频器设置为 0,所以定时器的更新频率为 8kHz,这意味着 DAC 输出的正弦波信号的频率也为 8kHz。
  • 幅度:正弦波的幅度取决于Sine12bit数组中的数据,该数组中的数据是通过uint8_uint16函数将data数组中的 8 位数据转换为 12 位数据得到的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值