STM32单片机DMA技术应用:10个实战案例,带你玩转高效数据传输
发布时间: 2024-07-02 23:00:42 阅读量: 140 订阅数: 61
![STM32单片机DMA技术应用:10个实战案例,带你玩转高效数据传输](https://img-blog.csdnimg.cn/37d67cfa95c946b9a799befd03f99807.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAT2NlYW4mJlN0YXI=,size_20,color_FFFFFF,t_70,g_se,x_16)
# 1. DMA技术概述**
**1.1 DMA简介**
DMA(Direct Memory Access)是一种允许外设直接访问内存的硬件技术,无需CPU干预。它通过减少CPU参与数据传输的过程,从而提高系统效率。
**1.2 DMA的工作原理**
DMA控制器是一个独立的硬件模块,负责管理数据传输。它将数据从源地址(如外设寄存器)传输到目标地址(如内存缓冲区),而无需CPU参与。DMA控制器使用DMA请求(DMAREQ)信号从外设获取数据传输请求,并使用DMA应答(DMAACK)信号通知外设传输完成。
# 2. DMA编程基础
### 2.1 DMA寄存器结构
STM32单片机的DMA控制器包含多个寄存器,用于配置和控制DMA传输。主要寄存器包括:
- **DMA_Channelx_CCR**:通道控制寄存器,用于配置DMA通道的传输模式、数据大小、中断使能等参数。
- **DMA_Channelx_CNDTR**:通道数据数量寄存器,用于指定要传输的数据量。
- **DMA_Channelx_CPAR**:通道外设地址寄存器,用于指定外设的地址。
- **DMA_Channelx_CMAR**:通道内存地址寄存器,用于指定内存的地址。
### 2.2 DMA配置和初始化
在使用DMA之前,需要进行配置和初始化。配置过程主要包括以下步骤:
1. **选择DMA通道:**根据外设和传输方向选择合适的DMA通道。
2. **配置DMA寄存器:**设置DMA通道控制寄存器(DMA_Channelx_CCR)、数据数量寄存器(DMA_Channelx_CNDTR)、外设地址寄存器(DMA_Channelx_CPAR)和内存地址寄存器(DMA_Channelx_CMAR)。
3. **使能DMA通道:**设置DMA通道控制寄存器(DMA_Channelx_CCR)中的使能位(EN)为1。
```c
// 配置DMA通道1,从外设传输数据到内存
DMA_Channel1->CCR = DMA_CCR_DIR | DMA_CCR_MINC | DMA_CCR_PSIZE_1 | DMA_CCR_MSIZE_1 | DMA_CCR_CIRC | DMA_CCR_TCIE;
DMA_Channel1->CNDTR = 100; // 要传输的数据量为100
DMA_Channel1->CPAR = (uint32_t)&USART1->DR; // 外设地址
DMA_Channel1->CMAR = (uint32_t)buffer; // 内存地址
DMA_Channel1->CCR |= DMA_CCR_EN; // 使能DMA通道
```
### 2.3 DMA传输模式
DMA支持多种传输模式,包括:
- **单次传输:**一次性传输指定数量的数据。
- **循环传输:**不断地传输数据,直到传输完成或发生错误。
- **内存到内存传输:**在两个内存区域之间传输数据。
- **外设到内存传输:**从外设传输数据到内存。
- **内存到外设传输:**从内存传输数据到外设。
### 2.4 DMA中断处理
DMA传输完成后或发生错误时,会产生中断。DMA控制器提供了以下中断源:
- **传输完成中断:**当DMA传输完成时触发。
- **半传输完成中断:**当DMA传输了一半数据时触发。
- **传输错误中断:**当DMA传输发生错误时触发。
中断处理程序需要读取DMA中断状态寄存器(DMA_ISR)并清除中断标志位。
```c
// DMA传输完成中断处理程序
void DMA1_Channel1_IRQHandler(void)
{
// 读取DMA中断状态寄存器
uint32_t isr = DMA1->ISR;
// 检查传输完成中断标志位
if (isr & DMA_ISR_TCIF1)
{
// 清除传输完成中断标志位
DMA1->IFCR |= DMA_IFCR_CTCIF1;
// 执行传输完成后的操作
}
}
```
# 3. DMA实战应用
DMA在实际项目中有着广泛的应用,本章节将通过10个实战案例,详细介绍DMA在不同场景下的应用方式,帮助读者深入理解DMA技术在STM32单片机中的实际应用。
### 3.1 数据传输:从外设到内存
**场景描述:**需要将ADC采集到的数据传输到内存中进行处理。
**DMA配置:**
```c
// 配置DMA通道1,从ADC1传输数据到内存
DMA_InitTypeDef DMA_InitStruct;
DMA_InitStruct.Channel = DMA_Channel_1;
DMA_InitStruct.Direction = DMA_DIR_PeripheralToMemory;
DMA_InitStruct.PeripheralBaseAddr = (uint32_t)&ADC1->DR;
DMA_InitStruct.MemoryBaseAddr = (uint32_t)data_buffer;
DMA_InitStruct.BufferSize = DATA_SIZE;
DMA_InitStruct.PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStruct.MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStruct.PeripheralDataSize = DMA_PeripheralDataSize_Word;
DMA_InitStruct.MemoryDataSize = DMA_MemoryDataSize_Word;
DMA_InitStruct.Mode = DMA_Mode_Circular;
DMA_InitStruct.Priority = DMA_Priority_High;
DMA_InitStruct.FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStruct.FIFOThreshold = DMA_FIFOThreshold_Full;
DMA_InitStruct.Mem2Mem = DMA_Mem2Mem_Disable;
DMA_Init(DMA1_Channel1, &DMA_InitStruct);
```
**逻辑分析:**
* DMA通道1配置为从外设(ADC1)到内存的数据传输模式。
* 数据从ADC1的数据寄存器(DR)传输到内存缓冲区(data_buffer)。
* 传输数据大小为DATA_SIZE个字(16位)。
* 外设地址不递增,内存地址递增。
* 数据传输模式为循环模式,传输完成后自动重新开始传输。
* DMA优先级设置为高,保证数据传输的及时性。
### 3.2 数据传输:从内存到外设
**场景描述:**需要将存储在内存中的数据发送到UART外设进行输出。
**DMA配置:**
```c
// 配置DMA通道2,从内存传输数据到UART1
DMA_InitTypeDef DMA_InitStruct;
DMA_InitStruct.Channel = DMA_Channel_2;
DMA_InitStruct.Direction = DMA_DIR_MemoryToPeripheral;
DMA_InitStruct.PeripheralBaseAddr = (uint32_t)&USART1->DR;
DMA_InitStruct.MemoryBaseAddr = (uint32_t)data_buffer;
DMA_InitStruct.BufferSize = DATA_SIZE;
DMA_InitStruct.PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStruct.MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStruct.PeripheralDataSize =
```
0
0