DMA
DMA 有2个一个在HCPU,一个在LCPU, 分别都支持内存-内存,内存-外设,外设-内存,外设-外设之间的传输.
主要特性
8个独立的可配置通道
每个通道的DMA请求可在16个硬件请求中选择1个,或由软件请求
每个通道支持4档优先级配置,优先级相同时依照通道编号大小判决
支持内存-内存,内存-外设,外设-内存,外设-外设传输
源地址和目标地址均独立支持单字节/双字节/4字节访问,并都可以独立选择地址是否自动递增
支持循环缓冲模式,单次传输完成后自动重新启动
每个通道支持3种事件标志-传输完成,过半传输,传输出错,并能各自独立产生中断请求
单次配置最大传输单元数为65536,每单元根据不同配置分别为单字节/双字节/4字节传输
单次配置传输地址范围限制在1M字节以内,即传输过程中源地址和目标地址均不可越过1M字节边界(地址的bit31-bit20不可改变)
DMAC对应的外设request id
req_sel |
55x DMAC1 |
55x DMAC2 |
58x DMAC1 |
58x DMAC2 |
58x DMAC3 |
56x DMAC1 |
56x DMAC2 |
54x DMAC1 |
54x DMAC2 |
---|---|---|---|---|---|---|---|---|---|
0 |
qspi1 |
usart3_tx |
mpi1 |
i2s1_tx |
usart4_tx |
mpi1 |
usart4_tx |
mpi1 |
usart4_tx |
1 |
qspi2 |
usart3_rx |
mpi2/i2c4 |
i2s1_rx |
usart4_rx |
mpi2 |
usart4_rx |
mpi2 |
usart4_rx |
2 |
qspi3 |
usart4_tx |
mpi3 |
i2s2_tx |
usart5_tx |
mpi3 |
usart5_tx |
/ |
usart5_tx |
3 |
/ |
usart4_rx |
mpi4 |
i2s2_rx |
usart5_rx |
i2c4 |
usart5_rx |
i2c4 |
usart5_rx |
4 |
usart1_tx |
usart5_tx |
usart1_tx |
pdm1_rx_l |
usart6_tx |
usart1_tx |
usart6_tx |
usart1_tx |
/ |
5 |
usart1_rx |
usart5_rx |
usart1_rx |
pdm1_rx_r |
usart6_rx |
usart1_rx |
usart6_rx |
usart1_rx |
/ |
6 |
usart2_tx |
btim3 |
usart2_tx |
pdm2_rx_l |
btim3 |
usart2_tx |
btim3 |
usart2_tx |
btim3 |
7 |
usart2_rx |
btim4 |
usart2_rx |
pdm2_rx_r |
btim4 |
usart2_rx |
btim4 |
usart2_rx |
btim4 |
8 |
gptim1_update |
gptim3_update |
gptim1_update |
/ |
gptim3_update |
gptim1_update |
gptim3_update |
gptim1_update |
/ |
9 |
gptim1_trigger |
gptim3_trigger |
gptim1_trigger |
dac0 |
gptim3_trigger |
gptim1_trigger |
gptim3_trigger |
gptim1_trigger |
/ |
10 |
gptim1_cc1 |
gptim3_cc1 |
gptim1_cc1 |
dac1 |
gptim3_cc1 |
gptim1_cc1 |
gptim3_cc1 |
gptim1_cc1 |
/ |
11 |
gptim1_cc2 |
gptim3_cc2 |
gptim1_cc2 |
gptim2_update |
gptim3_cc2 |
gptim1_cc2 |
gptim3_cc2 |
gptim1_cc2 |
/ |
12 |
gptim1_cc3 |
gptim3_cc3 |
gptim1_cc3 |
gptim2_trigger |
gptim3_cc3 |
gptim1_cc3 |
gptim3_cc3 |
gptim1_cc3 |
/ |
13 |
gptim1_cc4 |
gptim3_cc4 |
gptim1_cc4 |
gptim2_cc1 |
gptim3_cc4 |
gptim1_cc4 |
gptim3_cc4 |
gptim1_cc4 |
/ |
14 |
btim1 |
gptim5_update |
btim1 |
audprc_tx_out_ch1 |
gptim5_update |
btim1 |
gptim5_update |
btim1 |
/ |
15 |
btim2 |
gptim5_trigger |
btim2 |
audprc_tx_out_ch0 |
gptim5_trigger |
btim2 |
gptim5_trigger |
btim2 |
/ |
16 |
/ |
spi3_tx |
atim1_update |
audprc_tx_ch3 |
spi3_tx |
atim1_update |
spi3_tx |
atim1_update |
/ |
17 |
i2c3 |
spi3_rx |
atim1_trigger |
audprc_tx_ch2 |
spi3_rx |
atim1_trigger |
spi3_rx |
atim1_trigger |
/ |
18 |
i2s1_tx/pdm1_l |
spi4_tx |
atim1_cc1 |
audprc_tx_ch1 |
spi4_tx |
atim1_cc1 |
spi4_tx |
atim1_cc1 |
/ |
19 |
i2s1_rx/pdm1_r |
spi4_rx |
atim1_cc2 |
audprc_tx_ch0 |
spi4_rx |
atim1_cc2 |
spi4_rx |
atim1_cc2 |
/ |
20 |
i2s2_tx/pdm2_l |
qspi4 |
atim1_cc3 |
audprc_rx_ch1 |
mpi5 |
atim1_cc3 |
mpi5 |
atim1_cc3 |
/ |
21 |
i2s2_rx/pdm2_r |
i2c4 |
atim1_cc4 |
audprc_rx_ch0 |
i2c5 |
atim1_cc4 |
i2c5 |
atim1_cc4 |
/ |
22 |
i2c1 |
i2c5 |
i2c1 |
gptim2_cc2 |
i2c6 |
i2c1 |
i2c6 |
i2c1 |
/ |
23 |
i2c2 |
i2c6 |
i2c2 |
gptim2_cc3 |
i2c7 |
i2c2 |
i2c7 |
i2c2 |
/ |
24 |
gptim2_update |
gptim4_update |
i2c3 |
gptim2_cc4 |
gptim4_update |
i2c3 |
gptim4_update |
i2c3 |
/ |
25 |
gptim2_trigger |
gptim4_trigger |
atim1_com |
atim2_update |
gptim4_trigger |
atim1_com |
gptim4_trigger |
atim1_com |
/ |
26 |
gptim2_cc1 |
gptim4_cc1 |
usart3_tx |
atim2_trigger |
i2s3_rx/gptim4_cc1 |
usart3_tx |
gptim4_cc1 |
usart3_tx |
/ |
27 |
gptim2_cc2 |
gptim4_cc2 |
usart3_rx |
atim2_cc1 |
i2s3_tx/gptim4_cc2 |
usart3_rx |
gptim4_cc2 |
usart3_rx |
/ |
28 |
spi1_tx |
gptim4_cc3 |
spi1_tx |
atim2_cc2 |
audadc_ch0/gptim4_cc3 |
spi1_tx |
audadc_ch0/gptim4_cc3 |
spi1_tx |
/ |
29 |
spi1_rx |
gptim4_cc4 |
spi1_rx |
atim2_cc3 |
audadc_ch1/gptim4_cc4 |
spi1_rx |
audadc_ch1/gptim4_cc4 |
spi1_rx |
/ |
30 |
spi2_tx |
gpadc |
spi2_tx |
atim2_cc4 |
gpadc |
spi2_tx |
gpadc |
spi2_tx |
/ |
31 |
spi2_rx |
sdadc |
spi2_rx |
atim2_com |
sdadc |
spi2_rx |
/ |
spi2_rx |
/ |
32 |
/ |
/ |
/ |
/ |
/ |
i2s1_tx |
/ |
i2s1_tx |
/ |
33 |
/ |
/ |
/ |
/ |
/ |
i2s1_rx |
/ |
i2s1_rx |
/ |
34 |
/ |
/ |
/ |
/ |
/ |
sci_tx |
/ |
/ |
/ |
35 |
/ |
/ |
/ |
/ |
/ |
sci_rx |
/ |
/ |
/ |
36 |
/ |
/ |
/ |
/ |
/ |
pdm1_rx_l |
/ |
pdm1_rx_l |
/ |
37 |
/ |
/ |
/ |
/ |
/ |
pdm1_rx_r |
/ |
pdm1_rx_r |
/ |
38 |
/ |
/ |
/ |
/ |
/ |
pdm2_rx_l |
/ |
gpadc |
/ |
39 |
/ |
/ |
/ |
/ |
/ |
pdm2_rx_r |
/ |
adc0 |
/ |
40 |
/ |
/ |
/ |
/ |
/ |
/ |
/ |
adc1 |
/ |
41 |
/ |
/ |
/ |
/ |
/ |
dac0 |
/ |
dac0 |
/ |
42 |
/ |
/ |
/ |
/ |
/ |
dac1 |
/ |
dac1 |
/ |
43 |
/ |
/ |
/ |
/ |
/ |
gptim2_update |
/ |
gptim2_update |
/ |
44 |
/ |
/ |
/ |
/ |
/ |
gptim2_trigger |
/ |
gptim2_trigger |
/ |
45 |
/ |
/ |
/ |
/ |
/ |
gptim2_cc1 |
/ |
gptim2_cc1 |
/ |
46 |
/ |
/ |
/ |
/ |
/ |
audprc_tx_out_ch1 |
/ |
audprc_tx_out_ch1 |
/ |
47 |
/ |
/ |
/ |
/ |
/ |
audprc_tx_out_ch0 |
/ |
audprc_tx_out_ch0 |
/ |
48 |
/ |
/ |
/ |
/ |
/ |
audprc_tx_ch3 |
/ |
audprc_tx_ch3 |
/ |
49 |
/ |
/ |
/ |
/ |
/ |
audprc_tx_ch2 |
/ |
audprc_tx_ch2 |
/ |
50 |
/ |
/ |
/ |
/ |
/ |
audprc_tx_ch1 |
/ |
audprc_tx_ch1 |
/ |
51 |
/ |
/ |
/ |
/ |
/ |
audprc_tx_ch0 |
/ |
audprc_tx_ch0 |
/ |
52 |
/ |
/ |
/ |
/ |
/ |
audprc_rx_ch1 |
/ |
audprc_rx_ch1 |
/ |
53 |
/ |
/ |
/ |
/ |
/ |
audprc_rx_ch0 |
/ |
audprc_rx_ch0 |
/ |
54 |
/ |
/ |
/ |
/ |
/ |
gptim2_cc2 |
/ |
gptim2_cc2 |
/ |
55 |
/ |
/ |
/ |
/ |
/ |
gptim2_cc3 |
/ |
gptim2_cc3 |
/ |
56 |
/ |
/ |
/ |
/ |
/ |
gptim2_cc4 |
/ |
gptim2_cc4 |
/ |
57 |
/ |
/ |
/ |
/ |
/ |
sdmmc2 |
/ |
sdmmc1 |
/ |
58 |
/ |
/ |
/ |
/ |
/ |
/ |
/ |
/ |
/ |
59 |
/ |
/ |
/ |
/ |
/ |
/ |
/ |
/ |
/ |
60 |
/ |
/ |
/ |
/ |
/ |
/ |
/ |
/ |
/ |
61 |
/ |
/ |
/ |
/ |
/ |
/ |
/ |
/ |
/ |
62 |
/ |
/ |
/ |
/ |
/ |
/ |
/ |
/ |
/ |
63 |
/ |
/ |
/ |
/ |
/ |
/ |
/ |
/ |
/ |
使用 DMA示例1
内存-内存 4字节传输 4096字节.
DMA_HandleTypeDef hdma;
HAL_StatusTypeDef err;
uint32_t SrcAddress = 0x10000000;
uint32_t DstAddress = 0x20000000;
uint32_t Counts = 1024; //Transfer unit is word, so Counts= 4096 / 4
/* Init DMA configure*/
hdma.Instance = DMA1_Channel6;
hdma.Init.Request = 0; //Request id is useless while memory to memory, just set to 0
hdma.Init.Direction = DMA_MEMORY_TO_MEMORY;
hdma.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
hdma.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
hdma.Init.PeriphInc = DMA_PINC_ENABLE;
hdma.Init.MemInc = DMA_MINC_ENABLE;
hdma.Init.Mode = DMA_NORMAL;
hdma.Init.Priority = DMA_PRIORITY_MEDIUM;
hdma.XferHalfCpltCallback = DMA_Xfer_Half_Callback_Func;
hdma.XferCpltCallback = DMA_Xfer_Complete_Callback_Func;
hdma.XferErrorCallback = DMA_Xfer_Error_Callback_Func;
err = HAL_DMA_Init(&hdma);
if (err != HAL_OK)
return err;
err = HAL_DMA_Start_IT(hadc->DMA_Handle, SrcAddress, DstAddress, Counts);
if (err != HAL_OK)
return err;
使用 DMA示例2
ADC模块-内存 4字节传输 4096字节.
DMA_HandleTypeDef hdma;
HAL_StatusTypeDef err;
uint32_t SrcAddress = 0x10000000;
uint32_t DstAddress = 0x20000000;
uint32_t Counts = 1024; //Transfer unit is word, so Counts= 4096 / 4
/* Init DMA configure*/
hdma.Instance = DMA1_Channel6;
hdma.Init.Request = DMA_REQUEST_12;
hdma.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
hdma.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
hdma.Init.PeriphInc = DMA_PINC_DISABLE; //Periphral address NOT auto-increment
hdma.Init.MemInc = DMA_MINC_ENABLE;
hdma.Init.Mode = DMA_NORMAL;
hdma.Init.Priority = DMA_PRIORITY_MEDIUM;
hdma.XferHalfCpltCallback = DMA_Xfer_Half_Callback_Func;
hdma.XferCpltCallback = DMA_Xfer_Complete_Callback_Func;
hdma.XferErrorCallback = DMA_Xfer_Error_Callback_Func;
err = HAL_DMA_Init(&hdma);
if (err != HAL_OK)
return err;
err = HAL_DMA_Start_IT(hadc->DMA_Handle, SrcAddress, DstAddress, Counts);
if (err != HAL_OK)
return err;
使用 DMA示例3
内存->FLASH1模块 1字节传输 4096字节.
DMA_HandleTypeDef hdma;
HAL_StatusTypeDef err;
uint32_t SrcAddress = 0x20000000;
uint32_t DstAddress = hflash->Instance->DR;
uint32_t Counts = 4096; //Transfer unit is byte, so Counts= 4096 / 1
/* Init DMA configure*/
hdma.Instance = DMA1_Channel6;
hdma.Init.Request = DMA_REQUEST_0;
hdma.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma.Init.PeriphInc = DMA_PINC_DISABLE; //Periphral address NOT auto-increment
hdma.Init.MemInc = DMA_MINC_ENABLE;
hdma.Init.Mode = DMA_NORMAL;
hdma.Init.Priority = DMA_PRIORITY_MEDIUM;
hdma.XferHalfCpltCallback = DMA_Xfer_Half_Callback_Func;
hdma.XferCpltCallback = DMA_Xfer_Complete_Callback_Func;
hdma.XferErrorCallback = DMA_Xfer_Error_Callback_Func;
err = HAL_DMA_Init(&hdma);
if (err != HAL_OK)
return err;
err = HAL_DMA_Start_IT(hadc->DMA_Handle, SrcAddress, DstAddress, Counts);
if (err != HAL_OK)
return err;