系列文章目录
前言
DMA,全称为:Direct Memory Access,即直接存储器访问。DMA 传输方式无需 CPU 直接 控制传输,也没有中断处理方式那样保留现场和恢复现场的过程,通过硬件为 RAM 与 I/O 设备 开辟一条直接传送数据的通路,能使 CPU 的效率大为提高。
一、配置步骤
1)使能 DMA 时钟
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //使能 DMA 时钟
2)初始化 DMA 通道 4 参数
void DMA_Init(DMA_Channel_TypeDef* DMAy_Channelx, DMA_InitTypeDef* DMA_InitStruct)
DMA_InitTypeDef DMA_InitStructure; DMA_InitStructure.DMA_PeripheralBaseAddr = &USART1->DR; //DMA 外设 ADC 基地址 DMA_InitStructure.DMA_MemoryBaseAddr = cmar; //DMA 内存基地址 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; //从内存读取发送到外设 DMA_InitStructure.DMA_BufferSize = 64; //DMA 通道的 DMA 缓存的大小 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设地址不变 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址递增 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //8 位 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; // 8 位 DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //工作在正常缓存模式 DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //DMA 通道 x 拥有中优先级 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //非内存到内存传输 DMA_Init(DMA_CHx, &DMA_InitStructure); //根据指定的参数初始化
3)使能串口 DMA 发送
USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE);
4)使能 DMA1 通道 4,启动传输
DMA_Cmd(DMA_CHx, ENABLE);
5)查询 DMA 传输状态
在 DMA 传输过程中,我们要查询 DMA 传输通道的状态:
FlagStatus DMA_GetFlagStatus(uint32_t DMAy_FLAG)
比如我们要查询 DMA 通道 4 传输是否完成:
DMA_GetFlagStatus(DMA2_FLAG_TC4);
获取当前剩余数据量大小的函数:
uint16_t DMA_GetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx)
比如我们要获取 DMA 通道 4 还有多少个数据没有传输:
DMA_GetCurrDataCounter(DMA1_Channel4);
二、代码实例
我们需要创建dma.c 文件和其头文件 dma.h, 同时我们要引入 DMA 相关的库函数文件 stm32f10x_dma.c 和 stm32f10x_dma.h。
——dma.c 文件
#include "dma.h"
DMA_InitTypeDef DMA_InitStructure;
u16 DMA1_MEM_LEN;
void MYDMA_Config(DMA_Channel_TypeDef* DMA_CHx,u32 cpar,u32 cmar,u16 cndtr)
{
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
DMA_DeInit(DMA_CHx);
DMA1_MEM_LEN=cndtr;
DMA_InitStructure.DMA_PeripheralBaseAddr = cpar;
DMA_InitStructure.DMA_MemoryBaseAddr = cmar;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_BufferSize = cndtr;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA_CHx, &DMA_InitStructure);
}
void MYDMA_Enable(DMA_Channel_TypeDef*DMA_CHx)
{
DMA_Cmd(DMA_CHx, DISABLE );
DMA_SetCurrDataCounter(DMA1_Channel4,DMA1_MEM_LEN);
DMA_Cmd(DMA_CHx, ENABLE);
}
|