简介
DAC(Digital-to-Analog Converter,数模转换器)是将数字信号转换为模拟信号的外设,广泛应用于音频输出、波形生成、电机控制等场景。STM32F407 系列芯片配备了 2 个 DAC 通道(DAC1 和 DAC2),支持 12 位分辨率,支持多种触发方式,可输出稳定的模拟电压。本文从 DAC 的基本原理出发,详细讲解 STM32F407 DAC 的配置方法、代码实现、波形生成以及实际应用案例。
一、DAC 核心概念与分类
1.1 基本概念
DAC 是将数字信号转换为模拟信号的外设,其主要特点包括:
- 双通道:支持 2 个独立的 DAC 通道
- 12 位分辨率:可输出 0-4095 级模拟电压
- 多种触发方式:支持软件触发、定时器触发、外部触发等
- 波形生成:支持噪声波形、三角波波形生成
- DMA 支持:支持 DMA 传输,实现连续输出
关键参数:
- 分辨率:12 位,输出范围 0-4095
- 输出电压范围:0-VREF+(通常为 0-3.3V)
- 更新速率:最高可达 1MSPS
- 触发方式:软件触发、定时器触发、外部触发
1.2 STM32F407 的 DAC 资源
STM32F407 系列芯片配备了 2 个 DAC 通道:
| DAC 通道 | 引脚 | 触发源 | 适用场景 |
|---|---|---|---|
| DAC1 | PA4 | 软件触发、TIM2、TIM4、TIM5、TIM6、TIM7、TIM8、EXTI9 | 主要 DAC 通道 |
| DAC2 | PA5 | 软件触发、TIM2、TIM4、TIM5、TIM6、TIM7、TIM8、EXTI9 | 辅助 DAC 通道 |
关键特性:
- 支持 12 位分辨率
- 支持左右对齐
- 支持多种触发方式
- 支持噪声波形生成
- 支持三角波波形生成
- 支持 DMA 传输
- 支持双 DAC 同步转换
二、DAC 工作原理
2.1 基本工作原理
DAC 的基本工作原理是将数字信号转换为模拟信号。
工作流程:
- CPU 或 DMA 将数字数据写入 DAC 数据保持寄存器
- DAC 数据保持寄存器将数据传输到 DAC 数据寄存器
- DAC 数据寄存器将数字数据转换为模拟电压
- 模拟电压通过 DAC 输出引脚输出
2.2 触发方式
DAC 支持多种触发方式:
软件触发:
- 通过软件写入 DAC 数据寄存器触发转换
- 适用于手动控制输出电压的场景
定时器触发:
- 通过定时器事件触发转换
- 适用于周期性输出模拟电压的场景
外部触发:
- 通过外部中断触发转换
- 适用于外部事件触发输出模拟电压的场景
2.3 波形生成
DAC 支持两种波形生成:
噪声波形生成:
- 生成伪随机噪声波形
- 可用于音频效果、信号测试等场景
三角波波形生成:
- 生成三角波波形
- 可用于信号测试、电机控制等场景
三、DAC 配置与代码实现
3.1 标准库配置步骤
以 DAC1 为例,使用标准库配置 DAC 的基本步骤:
- 使能 DAC 时钟和 GPIO 时钟
- 配置 GPIO 为模拟模式
- 配置 DAC 基本参数
- 使能 DAC
- 配置 DMA(可选)
3.2 代码实现(DAC1,软件触发)
#include "stm32f4xx.h"
/**
* @brief 初始化 DAC1
* @param 无
* @retval 无
*/
void DAC1_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
DAC_InitTypeDef DAC_InitStructure;
// 1. 使能时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);
// 2. 配置 GPIO
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; // 模拟模式
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 3. 配置 DAC1
DAC_InitStructure.DAC_Trigger = DAC_Trigger_None; // 软件触发
DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None; // 无波形生成
DAC_InitStructure.DAC_LFSRUnmask_TriangleAmplitude = DAC_LFSRUnmask_Bit0;
DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Enable; // 使能输出缓冲
DAC_Init(DAC_Channel_1, &DAC_InitStructure);
// 4. 使能 DAC1
DAC_Cmd(DAC_Channel_1, ENABLE);
}
/**
* @brief 设置 DAC1 输出电压
* @param value: 数字值(0-4095)
* @retval 无
*/
void DAC1_SetVoltage(uint16_t value)
{
// 设置 DAC1 数据寄存器
DAC_SetChannel1Data(DAC_Align_12b_R, value);
}
/**
* @brief 获取 DAC1 输出电压
* @param 无
* @retval 数字值(0-4095)
*/
uint16_t DAC1_GetVoltage(void)
{
// 获取 DAC1 数据寄存器
return DAC_GetDataOutputValue(DAC_Channel_1);
}
/**
* @brief 将电压值转换为 DAC 数字值
* @param voltage: 电压值(0-3300mV)
* @retval 数字值(0-4095)
*/
uint16_t Voltage_To_DAC(uint16_t voltage)
{
if (voltage > 3300) voltage = 3300;
()(voltage * / );
}
四、总结
通过上述配置,STM32F407 的 DAC 模块可以灵活地输出模拟电压。结合定时器触发可实现周期波形,配合 DMA 可实现大数据量连续输出。开发者可根据具体应用场景选择合适的触发方式和波形生成模式。

