DMA简介
直接存储器存取(DMA)用来提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。无须CPU干预,数据可以通过DMA快速地移动,这就节省了CPU的资源来做其他操作。
两个DMA控制器有12个通道(DMA1有7个通道,DMA2有5个通道),每个通道专门用来管理来自于一个或多个外设对存储器访问的请求。还有一个仲裁器来协调各个DMA请求的优先权。
-
DMA与CPU共享数据总线
-当两者同时对同一目标访问时,总线仲裁器会执行仲裁,DMA与CPU循环调度访问,各占一半带宽。
-
DMA优先权
-高等级优先权优先于低等级优先权先行传输
-同等优先级下低编号等级优先与高编号等级先行传输(通道2>通道4)00
-同等优先级同等编号下DMA1优先于DMA2传输 -
数据传输宽度|对齐方式
-
传输错误时会触发中断
-
DMA的中断请求
DMA控制器
- DMA1各通道请求
- DMA2各通道请求
程序编写
- 使能时钟
以往外设是挂载在APB1和APB2时钟总线下
DMA是直接挂载在AHB时钟总线下
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
- 配置DMA参数
DMA_InitTypeDef DMA_InitStruct; //创建结构体
Data_Lenth=SizeOfBuffer;
DMA_InitStruct.DMA_BufferSize=Data_Lenth; //设置缓冲数据大小
DMA_InitStruct.DMA_DIR=DMA_DIR_PeripheralDST; //数据传输方向 DST(从存储器到外设 SRC从存储器到存储器)
DMA_InitStruct.DMA_M2M=DMA_M2M_Disable; //是否是存储器到存储器模式
DMA_InitStruct.DMA_MemoryBaseAddr=MemoryAdd; //存储器基地址
DMA_InitStruct.DMA_MemoryDataSize=DMA_PeripheralDataSize_Byte; //存储器数据宽度
DMA_InitStruct.DMA_MemoryInc=DMA_MemoryInc_Enable; //存储器地址是否递增
DMA_InitStruct.DMA_Mode=DMA_Mode_Normal; //DMA工作模式 单次或循环
DMA_InitStruct.DMA_PeripheralBaseAddr=PeripheralAdd; //外设的基地址
DMA_InitStruct.DMA_PeripheralDataSize=DMA_PeripheralDataSize_Byte; //外设数据宽度
DMA_InitStruct.DMA_PeripheralInc=DMA_PeripheralInc_Disable; //外设地址是否递增
DMA_InitStruct.DMA_Priority=DMA_Priority_Medium; //通道优先级设置 (非常高 高 中等 低)
DMA_DeInit(DMAy_Channelx); //将通道设置为缺省值
DMA_Init(DMAy_Channelx,&DMA_InitStruct); //初始化通道
- 使能DMA
使用DMA外设的时候必须要先初始化相应的外设
同时使能相应的外设的DMA
DMA_Cmd(DMAy_Channelx,DISABLE);
DMA_SetCurrDataCounter(DMAy_Channelx,Data_Lenth);
DMA_Cmd(DMAy_Channelx,ENABLE);
注:传输数据量大时使用循环传输模式
还没用到 不写