提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
目录
前言
为了节省CPU的资源。实现外设→存储器、存储器→存储器、存储器→外设之间的高速数据传输,因此产生了——DAM
一、DAM是什么?
DMA:Data Memory Access,直接存储器访问。无须CPU干预,数据可以通过DMA快速地移动,这就节省了CPU的资源来做其他操作。 两个DMA控制器有12个通道(DMA1有7个通道,DMA2有5个通道),每个通道专门用来管理来自 于一个或多个外设对存储器访问的请求。还有一个仲裁器来协调各个DMA请求的优先权。
二、使用步骤
1.找到固件库DMA的.h文件
2.找到DAM初始化结构体
大意为:
3.解析结构体
1.数据地址及传输方向配置
uint32_t DMA_PeripheralBaseAddr; //外设地址
uint32_t DMA_MemoryBaseAddr; //存储器地址
uint32_t DMA_DIR; //传输方向
外设地址说明 :取值为外设的地址。
存储器地址说明:取值为存储器地址,值得注意的是,外设和存储器地址数据类型必须相同。
传输方向说明:传输方向取值为以下2个参数,Peripheral(外设),DST(destination:目的地)、SRC(source:源、信息源、源点),所以,当外设为目的地时:传输方向就是内存到外设。当外设是源时:传输方向就是外设到内存。
2.数据传输大小及单位配置
uint32_t DMA_BufferSize; //数据传输数目
uint32_t DMA_PeripheralInc; // 外设地址增量模式
uint32_t DMA_MemoryInc; // 存储器地址增量模式
uint32_t DMA_PeripheralDataSize; //外设数据宽度
uint32_t DMA_MemoryDataSize; //存储器数据宽度
数据传输数目说明:取值为数据的多少,例如A为一个32个元素的数组且32个,当A传输给B时,传输的数据数目即为32,本质是32个地址。
外设地址\存储器增量模式: 取值为以下两个参数,需要说明的是增量模式就是说地址是逐个增加的,例如当数组A为非增量模式时其32个数据,那么传输时只能传输首位地址的数据。
外设/存储器数据宽度说明:计算机进行数据处理时,一次性存取、加工和传输的数据长度为字(word)。可理解为外设及存储器的数据的类型,例如在C语言中short型为16位,Int型为32位。当外设宽度=存储器宽度时,数据完整传输;外设≠存储器时,数据只保留宽度较短的。数据宽度可分别配置为8位、16位、32位
具体可参考下表:
3.数据结束配置
uint32_t DMA_Mode; //模式选择
模式选择说明:具体是指两个端点间的数据传输模式 ,其共有两个参数,可在寄存器DMA_CCRx:CIRC中进行配置,其中一个是Circular模式:循环操作发送模式,也就是说当A向B传输数据,总是循环进行传输。 另一个是Normal模式:标准模式,这是指A向B传输数据只传输一次。值得注意的是: 数据传输过程中可根据DMA_ISR寄存器配置中断触发方式分别为:传输过半、传输完成、传输出错。
4.其他配置
uint32_t DMA_Priority; //通道优先级
uint32_t DMA_M2M; //存储器到存储器
通道优先级说明:此时是软件配置其通道优先级,可在寄存器DMA_CCRx:PL配置。
其参数分别对应上图
当软件优先级相同时,则执行硬件优先级:编号越小优先级越高:例如:通道一>通道二、DMA1>DMA2。
注意: 通道表如下
上图说明,每个外设所在通道不同,所以就可以知道:外设传存储器、存储器传外设需要确定其通道。更要说明的是: 存储器传存储器每个通道都可以用
总结
提示:这里对文章进行总结,初始化DMA步骤如下:
1. 编写DMA初始化函数
2. 打开DAM1时钟,根据系统架构图,可知DAM1在总线AHB上,故用函数RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1);
3. 配置结构体DMA_InitTypeDef参数
4. 调用初始化函数DMA_Init(DMA_Channel_TypeDef* DMAy_Channelx, DMA_InitTypeDef* DMA_InitStruct),时结构体参数初始化
5. 调用函数DMA_ClearFlag(uint32_t DMAy_FLAG);来清除DMA数据流传输完成标志位
6. 调用函数DMA_Cmd(DMA_Channel_TypeDef* DMAy_Channelx, FunctionalState NewState),使能DMA