1.0 DMA的简介stm32 如何用DMA搬运数据 1) DMA:直接存储器存取(direct memory access)。作用:主要是实现数据的高速搬运,为CPU完成简单性重复性数据搬运工作。这个过程无需CPU干预。当数据搬运完成后,会有相应的状态标识位来告知CPU。1090492304想要更多干货加 2) 特性: 双AHB 主总线架构,一个用于存储器访问,另一个用于外设访问; STM32F4共有两个DMA,两个DMA 控制器总共有16 个数据流(每个控制器8 个); 每个数据流有单独的四级32 位先进先出存储器缓冲区(FIFO); DMA 流控制器:要传输的数据项的数目是1 到65535,可用软件编程; DMA数据搬运方向可以灵活设置,可以实现三种数据搬运: 从芯片内部搬运到→芯片外部 从芯片外部搬运到→芯片内部 从芯片内部搬到芯片内部 注意:芯片内部:指STM32内部存储器. 芯片外部:指STM32片上外设,如串口。 3) 弊端:如果需要接收大量的数据时,需要频繁触发中断,而且这个过程需要CPU参与。 1.1 DMA框图
1.2 DMA请求通道映射表1.3 DMA数据流的配置编程步骤1) 使能外设的DMA功能。举例:使能串口1的DMA发送或者DMA接收。 2) 使能DMA时钟 3) DMA_SxCR 寄存器中的 EN 位清零,禁止DMA数据流 4) 阻塞判断EN位是否置0了。 5) 在 DMA_SxPAR 寄存器中设置外设寄存器地址 6) 在 DMA_SxM0AR 寄存器中设置存储器地址。 7) 在 DMA_SxNDTR 寄存器中配置要传输的数据个数的总数 8) 使用 DMA_SxCR 寄存器中的 CHSEL[2:0] 选择 DMA 通道 9) 使用 DMA_SxCR 寄存器中的 PL[1:0] 位配置数据流优先级 10) 禁止FIFO 11) 配置数据流传输方向 12) 设置外设地址是增量模式还是固定模式 13) 设置存储器地址是增量模式还是固定模式 14) 设置外设数据宽度 15) 设置存储器数据宽度 16) 通过将 DMA_SxCR 寄存器中的 EN 位置 1 激活数据流。 注意:只有“禁止了数据流”,才可以更改寄存器的配置。 1.4 源和目标的地址设置1.5 DMA控制器相关寄存器1.5.0 DMA 数据流 x 配置寄存器 (DMA_SxCR) (x = 0..7)每个数据流都有一个自己的“配置寄存器”,举例: 1) DMA1的数据流0的“配置寄存器”在写代码是应该写:DMA1_Stream0->CR 2) DMA2的数据流5的“配置寄存器”在写代码是应该写:DMA2_Stream5->CR 3) DMA1的数据流3的“配置寄存器”在写代码是应该写:DMA1_Stream3->CR 4) DMA2的数据流6的“配置寄存器”在写代码是应该写:DMA2_Stream6->CR [url=] [/url]
位 27:25 CHSEL[2:0]:通道选择 (Channel selection)这些位将由软件置 1 和清零。 000:选择通道 0 001:选择通道 1 010:选择通道 2 011:选择通道 3 100:选择通道 4 101:选择通道 5 110:选择通道 6 111:选择通道 7提问:数据流7的请求通道选择为通道4,即USART1_TX功能,对应代码:DMA2_Stream7->CR |= 4<<25;[url=] [/url]
[url=] [/url]
位 17:16 PL[1:0]:优先级 (Priority level)设置数据流的优先级这些位将由软件置 1 和清零。 00:低 01:中 10:高 11:非常高举例:数据流7的请求通道选择为通道4,即USART1_TX功能,数据流7的优先级设置为“中”,对应代码:DMA2_Stream7->CR |= 1<<16;[url=] [/url]
[url=] [/url]
位 14:13 MSIZE[1:0]:存储器数据大小 (Memory data size) 00:字节(8 位) 01:半字(16 位) 10:字(32 位) 11:保留举例:如果存储器是自定的一个数组,自定的数组是:u8 dataBuf1[2] = {1,2};那么存储器的数据大小是8位如果存储器是自定的一个数组,自定的数组是:u16 dataBuf2[2] = {1,2};那么存储器的数据大小是16位如果存储器是自定的一个数组,自定的数组是:u32 dataBuf2[2] = {1,2};那么存储器的数据大小是32位举例:数据流7的请求通道选择为通道4,即USART1_TX功能,如果想实现串口1发送自定的一个数组,
自定的数组是:u8 dataBuf1[2] = {1,2}; ,那么存储器的数据大小要设置为“8位”,DMA2_Stream7->CR &=~(3<<13);[url=] [/url]
[url=] [/url]
位 12:11 PSIZE[1:0]:外设数据大小 (Peripheral data size) 00:字节(8 位) 01:半字(16 位) 10:字(32 位) 11:保留举例:如果外设是USART1_DR寄存器,由于USART1_DR寄存器是8位有效的,所以外设大小需要设置为"8位"举例:数据流7的请求通道选择为通道4,即USART1_TX功能,如果想实现串口1发送自定的一个数组,自定义的数组是:u8 dataBuf1[2] = {1,2}; ,
那么外设的数据大小要设置为“8位”,DMA2_Stream7->CR &=~(3<<11);[url=] [/url]
[url=] [/url]
位 10 MINC:存储器递增模式 (Memory increment mode) 0:存储器地址是固定的 1:每次传输完一个数据,存储器地址递增(增量为 MSIZE 值)举例:数据流7的请求通道选择为通道4,即USART1_TX功能,如果想实现串口1发送自定的一个数组,自定的数组是:u8 dataBuf1[2] = {1,2};
需要告诉DMA控制器,每发送一个数据后,需要进行地址偏移(地址递增),对应代码:DMA2_Stream7->CR |=1<<10;类比:串口发送数据u8 dataBuf1[2] = {1,2};for(i=0;i<2;i++){ USART1->DR = dataBuf1; // 数组下标偏移→地址偏移}[url=] [/url]
[url=] [/url]
位 9 PINC:外设递增模式 (Peripheral increment mode) 0:外设地址固定 1:每次传输完一个数据,外设地址递增(增量为 PSIZE 值)举例:数据流7的请求通道选择为通道4,即USART1_TX功能,如果想实现串口1发送自定的一个数组,自定的数组是:u8 dataBuf1[2] = {1,2};
由于一个芯片设置定型后,外设的地址都是固定的,所以一般都将外设地址设置为固定的。对应的代码:DMA2_Stream7->CR &=~(1<<9);[url=] [/url]
[url=] [/url]
位 7:6 DIR[1:0]:数据传输方向 (Data transfer direction)这些位将由软件置 1 和清零。 00:外设到存储器 01:存储器到外设 10:存储器到存储器 11:保留举例:数据流7的请求通道选择为通道4,即USART1_TX功能,如果想实现串口1DMA发送数据,数据传输方向需要配置为“存储器到外设”。 对应代码:DMA2_Stream7->CR |= 1<<6;[url=] [/url]
位 4 TCIE:传输完成中断使能 (Transfer complete interrupt enable) DMA搬运完成后,可以触发DMA中断,前提是将该位置1 0:禁止 TC 中断 1:使能 TC 中断
[url=] [/url]
位 0 EN:数据流使能/读作低电平时数据流就绪标志 (Stream enable / flag stream ready when read low) 功能1:用于使能数据流 0:禁止数据流 1:使能数据流 功能2:用于指示状态 读取该位,如果为0,则允许"对器寄存器进行配置" 读取该位,如果为1,则不允许"对器寄存器进行配置"注意:只有“禁止了数据流”,才可以更改寄存器的配置。[url=] [/url]
1.5.1 DMA 数据流 x 数据项数寄存器 (DMA_SxNDTR) (x = 0..7) [/backcolo |