本文将介绍DAC的概念、相关函数以及STM32CubeMX生成DAC的配置函数以及对生成DAC的配置函数进行分析(包括结构体配置、相关寄存器配置)。最后针对于DAC实践:DAC输出与读取、DAC+TIM 使用芯片内置生成三角波;TIM+DMA+DAC生成正弦波。
1. 什么是DAC?
1.1 DAC概念
DAC:数字信号转模拟信号,向单片机内部寄存器写入值(12/8bit),经过内部转换成模拟量电压。
1.1.1 DAC功能
· DAC 有两个转换器(各对应一个输出通道),可以按 8 位或 12 位模式进行配置。
· 12 位模式下数据左对齐或者右对齐
· 每个通道都有 DMA 控制器
· 双 DAC 双通道同时或者分别转换
1.1.2 DAC框图
1.2 DAC功能说明
1.2.1 DAC-通道使能、输出缓冲器使能
- DAC_CR.ENx:置1,DAC通道使能
ENx位只会使能模拟DAC Channelx宏单元。即使ENx位复位, DAC Channelx 数字接口仍处于使能状态。 - DAC_CR.BOFFx:置1,DAC输出缓冲器使能
(不使用外部运算放大器)将内部高阻抗转换从低阻抗,从而直接驱动外部负载。
1.2.2 DAC-数据格式
1. 对于 DAC 单通道 x,数据格式存放方式
DAC_DHRyyyx -> DHRx ->(软件或外部触发) DORx
- 8 位右对齐:软件必须将数据加载到 DAC_DHR8Rx [7:0] 位(存储到 DHRx[11:4] 位)。
- 12 位左对齐:软件必须将数据加载到 DAC_DHR12Lx [15:4] 位(存储到 DHRx[11:0] 位)。
- 12 位右对齐:软件必须将数据加载到 DAC_DHR12Rx [11:0] 位(存储到 DHRx[11:0] 位)。
2. 对于 DAC 双通道,数据格式存放方式
DAC_DHRyyyD -> DHR1、DHR2 ->(软件或外部触发) DOR1、DOR2
-
8 位右对齐:将 DAC 1 通道的数据加载到 DAC_DHR8RD [7:0] 位(存储到 DHR1[11:4] 位),将 DAC 2 通道的数据加载到 DAC_DHR8RD [15:8] 位(存储到 DHR2[11:4] 位)
-
12 位左对齐:将 DAC 1 通道的数据加载到 DAC_DHR12RD [15:4] 位(存储到 DHR1[11:0] 位),将 DAC 2 通道的数据加载到 DAC_DHR12RD [31:20] 位(存储 到 DHR2[11:0] 位)
-
12 位右对齐:将 DAC 1 通道的数据加载到 DAC_DHR12RD [11:0] 位(存储到 DHR1[11:0] 位),将 DAC 2 通道的数据加载到 DAC_DHR12RD [27:16] 位(存储 到 DHR2[11:0] 位)
1.2.3 DAC-触发转换(DAC_CR.TENx)、输出电压
1. DAC-触发使能(DAC_CR.TENx):
0:禁止 DAC 1 通道触发:写入 DAC_DHRx ,一个APB1 时钟周期之后转移到 DAC_DORx
1:使能 DAC 1 通道触发:外部触发条件到来,三个 APB1 时钟周期后进行转移DAC_DORx
2. DAC-触发选择(DAC_CR.TSELx[2:0]):
ENx 位置 1 时,无法更改 TSELx[2:0] 位。
3. 输出电压:
数字输入会转换为 0 到 VREF+ 之间的输出电压。各 DAC 通道引脚的模拟输出电压通过以下公式确定:
1.2.4 DAC-DMA请求(DAC_CR.DMAENx)、DMA下溢
当DMAENx位置1时,如果发生外部触发(而不是软件触发),则将产生DAC DMA请求:DAC_DHRx寄存器的值随后转移到DAC_DORx寄存器。
在双通道模式下,如果两个DMAENx位均置1,则将产生两个DMA请求。
如果只需要一个DMA请求,应仅将相应DMAENx位置1。应用程序可以在双通道模式下通过一个DMA 请求和一个特定 DMA 通道来管理两个 DAC 通道。(将双通道数据在内存中连续排列,DMA单次传输加载双通道数据(需配置DMA为双缓冲或循环模式)。)
DMA下溢(DAC_SR.DMAUDRx)
DAC的DMA请求没有缓冲队列。若前一次DMA传输未完成时,新的外部触发信号到达,DMA控制器无法及时响应新请求,导致下溢错误。
- DAC的
SR
寄存器(状态寄存器)中的DMAUDRx
(DMA下溢标志)置1,表示下溢错误。 - 发生下溢后,DMA数据传输被自动禁止,后续DMA请求被忽略,但DAC仍继续使用旧数据转换输出(避免信号中断)。
DMA下溢软件处理流程
-
清除下溢标志:
- 通过向
DMAUDRx
位写入1,清除下溢标志。
- 通过向
-
重新配置DMA与DAC:
- 将DMA数据流的
DMAEN
位清零,停止当前DMA传输。 - 重新初始化DMA控制器(配置数据地址、传输长度、优先级等)。
- 重新使能DAC的
DMAENx
位,恢复DMA请求功能。
- 将DMA数据流的
-
优化触发频率或DMA负载:
- 降低触发频率:调整外部触发源(如定时器)的周期,确保DMA有足够时间完成传输。
- 优化DMA效率:
- 使用DMA双缓冲模式,减少数据传输延迟。
- 增加DMA传输数据块长度,减少中断次数。
-
中断处理(可选):
- 若使能 DAC_CR.
DMAUDRIEx
位(DMA下溢中断使能位),下溢时会触发中断。 - 在中断服务程序(ISR)中执行上述清除和重配置操作。
- 若使能 DAC_CR.
1.3 DAC-通道噪声/三角波生成使能
1.3.1 DAC-生成噪声 DAC_CR.WAVEx[1:0]
-
DAC_CR.WAVEx[1:0] - 01 生成噪声
-
生成可变振幅的伪噪声,可使用 LFSR(线性反馈移位寄存器)
LFSR屏蔽后的值与用户写入DAC_DHRx
寄存器的值 相加,结果存入DAC_DORx
并输出。
如果 LFSR 为 0x0000 ,将向其注入“1”(防锁定机制)。
-
DAC_CR.MAMPx[3:0]:选择LFSR的输出位数(即噪声幅度)。
1.3.2 DAC-生成三角波(波形点数与MAMPx有关)
-
DAC_CR.WAVEx[1:0] - 10 生成三角波
-
MAMPx[3:0] 位必须在使能 DAC 之前进行配置,否则将无法更改
1.4 DAC-转换流程参考
具体查看芯片的参考手册
2. 基于HAL库配置DAC外设
2.1 CubeMX配置DAC外设
2.1.1 DAC 输出与读取
2.1.2 DAC 输出三角波(软件触发/定时器触发)(一个周期 4096*2 个点)
2.1.3 DAC 输出三角波(定时器+DMA触发)
2.2 DAC寄存器
3. DAC实践
3.1 DAC 输出与读取
- main函数
- 实践结果
3.2 DAC 输出三角波(软件触发/定时器触发)
- main函数
- 实践结果
3.3 DAC 输出正弦波(TIM+DMA)
- main函数
- 实践结果
4. 本文的工程文件下载链接
工程Github下载链接:https://github.com/chipdynkid/MCU-DL-STM32
(国内)工程Gitcode下载链接https://gitcode.com/chipdynkid/MCU-DL-STM32