【STM32】关于DMA的那些事_哔哩哔哩_bilibili
在stm32f103系列芯片中,DMA1控制器分管七条DMA通道。
DMA2分管5条DMA通道。(大容量芯片专属)
每一个DMA通道都有其对应的外设寄存器地址与存储器地址寄存器,一些其他设置信息,例如:地址自增、数据宽度、传输方向、循环模式、优先级等存储在其他寄存器上。
回顾一下上一讲提到的STM32内部4GB的内存地址,
我们在使用DMA时就像是在发送快递一样,将外设地址填入外设地址寄存器,内存地址填入储存器地址寄存器中。如果数据流向是peripheral to memory,那么就相当于发货地址是外设地址,收货地址是内存地址,左右两个地址寄存器相当于快递单。
举例说明:
①进入串口配置界面,打开异步串口,给TX添加一条DMA通道。
②可以看到,这时DMA1的通道4被打开了,因为是transmit所以方向是内存->外设。
在串口通信的过程中,每一字节数据需要先搬运到发送数据寄存器,再由发送数据寄存器放入发送移位寄存器进行发送。所以此时我们的"收货地址"外设地址寄存器就是发送数据寄存器,“发货地址”是待发送数据的指针。
在串口依次发送数据时,DMA每次都是搬运一字节数据到发送数据寄存器中,因此CubeMX配置
DMA的默认选项里面数据宽度是单字节,即每次DMA都搬运1byte(8位)。不过可以看到在其它应用场景下,
不过在其他应用场景下,也可以将数据宽度修改为半字(16位)与一个字节(32位)。
当DMA将数据内容由内存地址向外设搬运的这个过程中,每次搬运都是将数据搬运到发送数据寄存器,因此外设地址无需开启自增(勾选Increment Addrsss),但搬运的数据在内存中依次排列,搬运完一个数据之后,下一次搬运的地址就要后移一字节,所以存储器地址的地址自增需要开启。DMA的每次数据搬运都需要触发信号,比如串口会在发送完一字节数据之后,给DMA通道一个触发信号,让其将下一位数据搬来,不过这一触发信号是与通道绑定的,所以这也是为什么USART1_TX的DMA通道固定为DMA1_Channel4的原因。
注意,1个DMA通道只能被一个外设所使用,例如我们使用了USART2_TX的DMA通道7之后,那么I2C1_RX就无法使用了。此外,虽然一个DMA拥有多个通道,但是同一时刻DMA仅能对一个通道进行搬运,因此可以设置CubeMX选项卡中的Priority这个选项进行修改优先级。