STM32的DMA

DMA(Direct memory access)直接存储器存取,用来提供在外设和存储器之间或者存储
器和存储器之间的高速数据传输,无须CPU干预,数据可以通过DMA快速地移动,这就节
省了CPU的资源来做其他操作。
STM32有两个DMA控制器共12个通道(DMA1有7个通道,DMA2有5个通道),每个通
道专门用来管理来自于一个或多个外设对存储器访问的请求。还有一个仲裁器来协调各个
DMA请求的优先权。
3.1、DMA作用
DMA的作用就是实现数据的直接传输,而去掉了传统数据传输需要CPU寄存器参与的环
节, 主要涉及四种数据传输模式,其本质还是一样的,都是地址到地址的数据传
输。
外设到内存
内存到外设
内存到内存
外设到外设
3.2、 DMA传输相关参数
源地址
目标地址
数据传输量
...
3.3、DMA的主要特征
12个独立的可配置的通道(请求):DMA1有7个通道,DMA2有5个通道,每个通
道都直接连接专用的硬件DMA请求,每个通道都同样支持软件触发。这些功能通过
软件来配置:
同一个DMA模块上,多个请求间的优先权可以通过软件编程设置(共有四级:很
高、高、中等和低),优先权设置相等时由硬件决定(请求0优先于请求1,依此类推) 独立数据源和目标数据区的传输宽度包括字节、半字、全字,源地址和目标地址
必须按数据传输宽度对齐。
支持循环的缓冲器管理
每个通道都有3个事件标志(DMA半传输、DMA传输完成和DMA传输出错)
FLASH、SRAM、外设的SRAM、APB1、APB2和AHB外设均可作为访问的源和
目标
编程的数据传输数目:最大为65535

3.4、stm32DMA资源
3.4.1、DMA1控制器
从外设(TIMx[x=1、2、3、4]、ADC1、SPI1、SPI/I2S2、I2Cx[x=1、2]和USARTx[x=1、
2、3])产生的7个请求,通过逻辑或输入到DMA1控制器。
外设的DMA请求,可以通过设置相应外设寄存器中的控制位,被独立地开启或关闭
3.4.2、DMA2控制器
从外设(TIMx[5、6、7、8]、ADC3、SPI/I2S3、UART4、DAC通道1、2和SDIO)产生的5
个请
求,经逻辑或输入到DMA2控制器
外设的DMA请求,可以通过设置相应外设寄存器中的DMA控制位,被独立地开启或关闭
注意:DMA2控制器及相关请求仅存在于大容量产品和互联型产品中
3.5、stm32DMA相关固件库函数说明
3.5.1、初始化函数
1 void DMA_Init ( DMA_Channel_TypeDef * DMAy_Channelx , \
2 DMA_InitTypeDef * DMA_InitStruct )
参数:
@DMAy_Channelx:DMA通道
y:1或2,用于选择DMA1或DMA2
x:对于DMA1:1-7,对于DMA2:1-5
@DMA_InitStruct:DMA配置结构体指针
1 typedef struct
2 {
3 uint32_t DMA_PeripheralBaseAddr ; // 外设地址
4 uint32_t DMA_MemoryBaseAddr ; // 存储器地址
5 uint32_t DMA_DIR ; // 传输方向
6 uint32_t DMA_BufferSize ; // 输出大小
7 uint32_t DMA_PeripheralInc ; // 外设地址增量模式
8 uint32_t DMA_MemoryInc ; // 存储器地址增量模式 9 uint32_t DMA_PeripheralDataSize ; // 外设数据宽度
10 uint32_t DMA_MemoryDataSize ; // 存储器数据宽度
11 uint32_t DMA_Mode ; // 模式选择
12 uint32_t DMA_Priority ; // 通道优先级
13 uint32_t DMA_M2M ; // 存储器到存储器模式
14 } DMA_InitTypeDef ;
传输方向:
1 #define DMA_DIR_PeripheralDST (( uint32_t ) 0x00000010 )
2 #define DMA_DIR_PeripheralSRC (( uint32_t ) 0x00000000 )
DMA通道x配置寄存器(DMA_CCRx):
外设地址增量模式:
1 #define DMA_PeripheralInc_Enable (( uint32_t ) 0x00000040 )
2 #define DMA_PeripheralInc_Disable (( uint32_t ) 0x00000000 )
存储器地址增量模式:
1 #define DMA_MemoryInc_Enable (( uint32_t ) 0x00000080 )
2 #define DMA_MemoryInc_Disable (( uint32_t ) 0x00000000 )
外设数据宽度:
1 #define DMA_PeripheralDataSize_Byte (( uint32_t ) 0x00000000 )
2 #define DMA_PeripheralDataSize_HalfWord (( uint32_t ) 0x00000100 )
3 #define DMA_PeripheralDataSize_Word (( uint32_t ) 0x00000200 )
存储器数据宽度
1 #define DMA_MemoryDataSize_Byte (( uint32_t ) 0x00000000 )
2 #define DMA_MemoryDataSize_HalfWord (( uint32_t ) 0x00000400 )
3 #define DMA_MemoryDataSize_Word (( uint32_t ) 0x00000800 )
4
模式选择(DMA_Mode):
1 #define DMA_Mode_Circular (( uint32_t ) 0x00000020 ) // 循环模式
2 #define DMA_Mode_Normal (( uint32_t ) 0x00000000 ) // 正常模式
通道优先级:
1 #define DMA_Priority_VeryHigh (( uint32_t ) 0x00003000 )
2 #define DMA_Priority_High (( uint32_t ) 0x00002000 )
3 #define DMA_Priority_Medium (( uint32_t ) 0x00001000 )
4 #define DMA_Priority_Low (( uint32_t ) 0x00000000 )
存储器到存储器模式: 1 #define DMA_M2M_Enable (( uint32_t ) 0x00004000 )
2 #define DMA_M2M_Disable (( uint32_t ) 0x00000000 )
3.5.2、DMA通道使能
1 void DMA_Cmd ( DMA_Channel_TypeDef * DMAy_Channelx , \
2 FunctionalState NewState )
3.5.3、DMA中断配置
1 void DMA_ITConfig ( DMA_Channel_TypeDef * DMAy_Channelx , uint32_t DMA_IT , \
2 FunctionalState NewState )
3.5.4、其他辅助函数
DMA清除中断挂起
1 void DMA_ClearITPendingBit ( uint32_t DMAy_IT )
DMA获取中断状态
1 ITStatus DMA_GetITStatus ( uint32_t DMAy_IT )
获取传输剩余个数
1 uint16_t DMA_GetCurrDataCounter ( DMA_Channel_TypeDef * DMAy_Channelx )
3.6、memory to memory实例
使用DMA的M2M模式从内嵌flash拷贝数据到sram中:
1 //32 个 4 字节数据
2 0x01020304 , 0x05060708 , 0x090A0B0C , 0x0D0E0F10 ,
3 0x11121314 , 0x15161718 , 0x191A1B1C , 0x1D1E1F20 ,
4 0x21222324 , 0x25262728 , 0x292A2B2C , 0x2D2E2F30 ,
5 0x31323334 , 0x35363738 , 0x393A3B3C , 0x3D3E3F40 ,
6 0x41424344 , 0x45464748 , 0x494A4B4C , 0x4D4E4F50 ,
7 0x51525354 , 0x55565758 , 0x595A5B5C , 0x5D5E5F60 ,
8 0x61626364 , 0x65666768 , 0x696A6B6C , 0x6D6E6F70 ,
9 0x71727374 , 0x75767778 , 0x797A7B7C , 0x7D7E7F80
stm32的内嵌flash中存放的是code和const修饰的变量值
4.dma数据传输示例
1、User目录新建dma_mtom.h和dma_mtom.c文件,通过三色板文件添加按钮添加文件
2、编写dma_mtom.c代码
2.1在外设库定义文件找到RCC_AHBPeriphClockCmdASB总线的外部使能函数
3.编译

4.没有错误
5.下载程序到STM32单片机中进行调试

6.按下复位按键

7.黄灯和红灯亮了,代表p13的引脚写入成功

相关推荐
无垠的广袤34 分钟前
【工业树莓派 CM0 NANO 单板计算机】本地部署 EMQX
linux·python·嵌入式硬件·物联网·树莓派·emqx·工业物联网
雲烟3 小时前
嵌入式设备EMC安规检测参考
网络·单片机·嵌入式硬件
泽虞3 小时前
《STM32单片机开发》p7
笔记·stm32·单片机·嵌入式硬件
田甲3 小时前
【STM32】 数码管驱动
stm32·单片机·嵌入式硬件
up向上up4 小时前
基于51单片机垃圾箱自动分类加料机快递物流分拣器系统设计
单片机·嵌入式硬件·51单片机
纳祥科技13 小时前
Switch快充方案,内置GaN,集成了多个独立芯片
单片机
单片机日志14 小时前
【单片机毕业设计】【mcugc-mcu826】基于单片机的智能风扇系统设计
stm32·单片机·嵌入式硬件·毕业设计·智能家居·课程设计·电子信息
松涛和鸣15 小时前
从零开始理解 C 语言函数指针与回调机制
linux·c语言·开发语言·嵌入式硬件·排序算法
小曹要微笑21 小时前
STM32F7 时钟树简讲(快速入门)
c语言·stm32·单片机·嵌入式硬件·算法
XINVRY-FPGA1 天前
XCVP1802-2MSILSVC4072 AMD Xilinx Versal Premium Adaptive SoC FPGA
人工智能·嵌入式硬件·fpga开发·数据挖掘·云计算·硬件工程·fpga