简介
DMA:Direct Memory Access 直接存储器存取
能够直接访问单片机内部存储器:运行内存SRAM,程序存储器Flash和寄存器
DMA==>数据转移小助手,主要用来协助cpu,完成数据转运的工作
DMA可以提供外设和存储器或者存储器与存储器之间的高速数据传输,无需CPU干预,节省CPU资源
外设:外设寄存器(外设数据寄存器DR,Data Register)
存储器 :运行内存SRAM和程序存储器Flash(存储变量数组、程序代码 )
12个独立可配置通道:DMA1(7个 通道),DMA2(5个通道)
数据转运占用 一个通道,转运之间互不干扰
每个通道都支持软件触发和特定的硬件触发
存储器到存储器软件触发,外设到存储器硬件触发,每个DMA通道的硬件触发源不一样
STM32F103C8T6DMA资源:DMA1(7个通道 )
存储器映像
rom:只读存储器 ,是一种非易失性、掉电不丢失的存储器
ram:随机存储器,是一种易失性,掉电丢失的存储器
DMA框图
cpu+存储器
Flash是主闪存,SRAM是运行内存
外设==>寄存器(sram存储器 )
软件与硬件桥梁–>寄存器
软件读写寄存器控制硬件执行
cpu对寄存器进行读写,读写运行内存,寄存器后面连接导线,导线用于控制外设状态(置引脚高低电平、导通与断开开关、切换数据选择器)
主动单元 | 总线矩阵 | 被动单元 |
---|---|---|
存储器访问权 | 总线矩阵 | 被主动单元读写 |
Dcode | 访问 | Flash |
系统总线 | 访问 | 其他外设 |
分时复用dma总线,如果产生冲突由仲裁器根据通道优先级决定使用顺序
AHB从设备:用于配置DMA参数
DMA基本结构
存储器,外设,站点,转运
传输计数器==>自减
自动重装–>将特定数值装载到传输计数器
M2M位置1软件触发–>存储器到存储器,尽快完成任务
M2M位置0硬件触发–>触发源:ADC,串口,定时器
开关控制:DMA使能条件
1.DMA_Cmd使能
2.传输计数器>0
3.触发源必须有触发信号–>触发一次,转运一次,传输计数器自减一次
tip:写传输计数器时,必须先关闭DMA,在进行
DMA请求
不同硬件触发源对应的DMA通道,硬件触发源==>通道
软件触发,无所谓都是一样的
en:控制位使能失能
m2m:哪一路(软件触发、硬件触发)
数据宽度
等长与短宽度到长宽度直接写或者前面直接补零
长宽度到短宽度,只保留后面的 数据,前面的丢失
相关代码
//1.RCC开启 DMA时钟
//2.调用 DMA_Init初始化参数
//3.开关控制DMA_cmd
//4.外设xxxDMA_cmd开启 触发信号输出
//if(DMA中断,调用DMA_ITConfig开启中断,nvic配置相应中断通道 ,中断函数)
//如果转运完成 ,传输 计数器清零,if还想给计数器赋值,DMA失能,写传输计数器,DMA使能
//void DMA_DeInit(DMA_Channel_TypeDef* DMAy_Channelx);
//恢复缺省配置
//void DMA_Init(DMA_Channel_TypeDef* DMAy_Channelx, DMA_InitTypeDef* DMA_InitStruct);
//初始化
//void DMA_StructInit(DMA_InitTypeDef* DMA_InitStruct);
//结构体初始化
//void DMA_Cmd(DMA_Channel_TypeDef* DMAy_Channelx, FunctionalState NewState);
//DMA使能
//void DMA_ITConfig(DMA_Channel_TypeDef* DMAy_Channelx, uint32_t DMA_IT, FunctionalState NewState);
//中断输出使能
//void DMA_SetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx, uint16_t DataNumber);
//给传输计数器写数据
//uint16_t DMA_GetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx);
//返回 传输计数器值
//FlagStatus DMA_GetFlagStatus(uint32_t DMAy_FLAG);
//获取标志位状态
//void DMA_ClearFlag(uint32_t DMAy_FLAG);
//清除标志位
//ITStatus DMA_GetITStatus(uint32_t DMAy_IT);
//获取中断状态
//void DMA_ClearITPendingBit(uint32_t DMAy_IT);
//清除中断 挂起位