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的引脚写入成功

相关推荐
启明云端wireless-tag2 小时前
ESP32无线WiFi蓝牙SOC,设备物联网通信方案,启明云端乐鑫代理商
嵌入式硬件·物联网·wifi·esp32·乐鑫·wifi模组
小狗爱吃黄桃罐头2 小时前
江协科技STM32学习- P14 示例程序(定时器定时中断和定时器外部时钟)
stm32·江科大stm32
@@庆3 小时前
stm32 PWR电源控制(修改主频&睡眠模式&停机模式&待机模式)
stm32·单片机·嵌入式硬件
JT灬新一3 小时前
STM32巡回研讨会总结(2024)
stm32·单片机·嵌入式硬件
爱桥代码的程序媛4 小时前
鸿蒙OpenHarmony【轻量系统芯片移植案例】标准系统方案之瑞芯微RK3568移植案例
嵌入式硬件·harmonyos·鸿蒙·鸿蒙系统·移植·openharmony·鸿蒙开发
Whappy0014 小时前
51单片机-DA(数字转模拟)
单片机·嵌入式硬件·51单片机
鸽子汤1974 小时前
想高效开发?从文件系统开始着手。。。
嵌入式硬件·物联网·硬件工程
Whappy0014 小时前
51单片机-AD(模拟信号转数字信号)-实验()
单片机·嵌入式硬件·51单片机
redcocal14 小时前
地平线秋招
python·嵌入式硬件·算法·fpga开发·求职招聘