DMA(直接存储器访问)
他的作用是增强系统性能并减轻CPU的负担. 但是想要正确的使用DMA,需要对DMA进行正确的配置.
而DMA配置中,有几点是十分重要的.
下面用雅特力的例程作为例子进行解释:
dma_reset(DMA1_CHANNEL5);
dma_init_struct.buffer_size = BUFFER_SIZE;
dma_init_struct.direction = DMA_DIR_MEMORY_TO_PERIPHERAL;
dma_init_struct.memory_base_addr = (uint32_t)src_buffer;
dma_init_struct.memory_data_width = DMA_MEMORY_DATA_WIDTH_HALFWORD;
dma_init_struct.memory_inc_enable = TRUE;
dma_init_struct.peripheral_base_addr = (uint32_t)&GPIOB->odt;
dma_init_struct.peripheral_data_width = DMA_PERIPHERAL_DATA_WIDTH_HALFWORD;
dma_init_struct.peripheral_inc_enable = FALSE;
dma_init_struct.priority = DMA_PRIORITY_MEDIUM;
dma_init_struct.loop_mode_enable = FALSE;
dma_init(DMA1_CHANNEL5, &dma_init_struct);
这是at32f421的例程.
首先是确认DMA的通道
DMA通道
dma通道数的选择,只和一个有关,那就是触发dma请求的外设.
这是DMA各通道的外设请求映射表.
假设是通过ADC触发的dma请求,则通道就需要选择1或者2. 至于到底选择什么,则需要根据表后所说
1:SCFG_CFG1中相应的remap位为0时,相应DMA请求映射到此通道
2:SCFG_CFG1中相应的remap位为1时,相应DMA请求映射到此通道
和dma进行传输的内存地址和外设地址无关.
DMA寄存器
例程的后面则是对dma有关寄存器的配置.
其中比较容易出问题的就是传输数据宽度的配置. 当外设数据宽度和内存数据宽度一致的时候,没有任何问题,根据配置的数据宽度进行传输.
但是当两个数据宽度不一致的时候,则会需要进行数据对齐.
1. PWIDTH: byte, MWIDTH: half-word
如图,当4个byte的数据进行传输的时候,四个数据会进行对齐,每个byte的数据都会和一个空的byte结合,成为一个半字的数据,再进行传输
2. PWIDTH: half-word, MWIDTH: word
和第一种类似,半字的数据和半字的空数据结合成为一个新的字.然后再进行传输
3. PWIDTH: word, MWIDTH: byte
如图,先将四个字的数据进行对齐,然后选择每个字的第一个byte的数据进行传输,而不是想象中的,将一个字的数据分成4个byte分别传输.