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

作者:ycjunhua

物联沃分享整理
物联沃-IOTWORD物联网 » 深入理解STM32中的DMA技术

发表评论