跳到主要内容

STM32 DAC DMA 传输

介绍

在 STM32 微控制器中,DAC(数字模拟转换器)用于将数字信号转换为模拟信号。DMA(直接内存访问)则是一种无需 CPU 干预即可在内存和外设之间传输数据的技术。结合 DAC 和 DMA,可以实现高效的数据传输,特别适用于需要连续输出模拟信号的场景,如音频播放、波形生成等。

本教程将逐步讲解如何配置 STM32 的 DAC 和 DMA,并通过代码示例展示如何实现 DAC DMA 传输。

硬件配置

在开始之前,确保你的 STM32 开发板支持 DAC 和 DMA 功能。通常,STM32 的 DAC 输出引脚为 PA4PA5,但具体引脚请参考你的开发板手册。

软件配置

1. 初始化 DAC

首先,我们需要初始化 DAC。以下是一个简单的 DAC 初始化代码示例:

c
void DAC_Init(void) {
// 使能 DAC 时钟
RCC->APB1ENR |= RCC_APB1ENR_DACEN;

// 配置 DAC 通道 1
DAC->CR |= DAC_CR_EN1; // 使能 DAC 通道 1
}

2. 配置 DMA

接下来,我们需要配置 DMA 以将数据从内存传输到 DAC。以下是一个 DMA 配置的示例:

c
void DMA_Init(void) {
// 使能 DMA 时钟
RCC->AHB1ENR |= RCC_AHB1ENR_DMA1EN;

// 配置 DMA 流
DMA1_Stream5->CR &= ~DMA_SxCR_EN; // 禁用 DMA 流
DMA1_Stream5->CR |= DMA_SxCR_CHSEL_2; // 选择通道 2
DMA1_Stream5->CR |= DMA_SxCR_MINC; // 内存地址递增
DMA1_Stream5->CR |= DMA_SxCR_DIR_0; // 内存到外设
DMA1_Stream5->CR |= DMA_SxCR_TCIE; // 使能传输完成中断

// 设置外设地址
DMA1_Stream5->PAR = (uint32_t)&(DAC->DHR12R1);

// 设置内存地址
DMA1_Stream5->M0AR = (uint32_t)&dac_buffer;

// 设置数据长度
DMA1_Stream5->NDTR = BUFFER_SIZE;

// 使能 DMA 流
DMA1_Stream5->CR |= DMA_SxCR_EN;
}

3. 启动 DAC DMA 传输

配置完成后,我们可以启动 DAC DMA 传输:

c
void DAC_DMA_Start(void) {
// 使能 DAC DMA 请求
DAC->CR |= DAC_CR_DMAEN1;

// 启动 DMA 传输
DMA1_Stream5->CR |= DMA_SxCR_EN;
}

实际应用案例

假设我们需要生成一个正弦波信号。我们可以预先计算正弦波的数据,并将其存储在内存中。然后,通过 DMA 将这些数据传输到 DAC,从而实现连续的正弦波输出。

c
#define BUFFER_SIZE 100
uint16_t dac_buffer[BUFFER_SIZE];

void Generate_Sine_Wave(void) {
for (int i = 0; i < BUFFER_SIZE; i++) {
dac_buffer[i] = (uint16_t)(2048 * (1 + sin(2 * M_PI * i / BUFFER_SIZE)));
}
}

int main(void) {
DAC_Init();
DMA_Init();
Generate_Sine_Wave();
DAC_DMA_Start();

while (1) {
// 主循环
}
}

总结

通过本教程,我们学习了如何在 STM32 中使用 DMA 传输来实现 DAC 输出。这种方法可以显著提高数据传输的效率,特别适用于需要连续输出模拟信号的场景。

附加资源

练习

  1. 修改代码,生成一个三角波信号。
  2. 尝试使用双缓冲技术,进一步提高数据传输的效率。
提示

在实际项目中,确保 DMA 传输的数据长度和缓冲区大小匹配,以避免数据丢失或溢出。