本文以STM32F103为例进行介绍:
- 什么是DMA(直接存储器访问)
- DMA是一种可以在不占用CPU资源(除了初始化和配置阶段)的情况下,实现数据在存储器(如内部Flash、SRAM)和外设(如ADC、SPI、USART等)之间直接传输的技术。就好像有一个专门的数据搬运工,它可以自动地把数据从一个地方搬到另一个地方,而不需要CPU亲力亲为,这样CPU就可以去做其他更重要的事情,比如数据处理、运算等。
- STM32F103中DMA的特点
- 多个通道:STM32F103有多个DMA通道。例如,它有7个DMA通道,可以支持多个外设同时进行DMA传输。这些通道可以灵活地分配给不同的外设,像ADC1可以使用DMA1的通道1来进行数据传输,SPI1可以使用DMA1的通道2等。
- 数据传输方向灵活:支持从外设到存储器、从存储器到外设以及存储器到存储器的数据传输。以从ADC采集数据存储到SRAM为例,这是外设到存储器的传输;而如果要将预先存储在SRAM中的数据发送到SPI外设进行传输,就是存储器到外设的传输;存储器到存储器传输可以用于数据在内部SRAM不同区域之间的快速搬移。
- 多种数据宽度:可以处理字节(8位)、半字(16位)和字(32位)的数据传输。在实际应用中,如果是传输8位的传感器数据(如温度传感器数据),就可以选择字节传输;如果是传输16位的音频数据,就可以采用半字传输;对于32位的图像像素数据等情况,则可以使用字传输。
- 可配置的传输模式 :
- 普通模式:在这种模式下,数据传输一次后就停止。例如,只是偶尔需要从一个外设读取少量的数据进行一次性处理时可以使用。
- 循环模式:数据传输完成后,会自动重新开始传输。在连续采集传感器数据的场景下非常有用,如对电机的电流进行实时监测,DMA可以不断地将ADC采集到的电流数据传输到内存缓冲区,供后续的控制算法使用。
- DMA的工作原理
- 初始化设置:首先需要对DMA控制器进行初始化。这包括配置通道优先级、数据传输方向、传输的数据宽度、传输模式等参数。例如,在使用DMA传输ADC采集的数据到SRAM时,要设置好数据传输方向为外设到存储器,数据宽度根据ADC的分辨率来设定(如果是12位ADC分辨率,可以设置为半字传输)。
- 触发源设置:每个DMA通道都有对应的触发源,通常是由外设事件来触发。以UART接收数据为例,当UART接收到一个字节的数据时,会产生一个接收完成中断,这个中断可以作为DMA的触发信号,启动DMA将接收到的数据传输到指定的内存区域。
- 数据传输过程:一旦触发条件满足,DMA就会开始自动传输数据。它会根据预先设置好的源地址(如外设的数据寄存器)和目标地址(如内存缓冲区),以及传输的数据长度,逐个将数据单元从源地址搬运到目标地址。在传输过程中,不需要CPU干预,只有在传输完成后(如果开启了传输完成中断),CPU才会收到中断通知,可以进行后续的处理,如数据处理或者开始下一轮的DMA传输配置。
- DMA在STM32F103中的应用场景
- 数据采集系统:比如在一个温度监测系统中,使用ADC采集多个温度传感器的数据。通过DMA,可以将ADC转换后的数据直接传输到内存缓冲区,这样可以高效地获取大量的温度数据,并且CPU可以同时进行温度数据的处理(如计算平均值、判断是否超出阈值等),提高系统的整体性能。
- 通信接口的数据传输:在SPI、I2C或USART等通信接口中,当需要接收或发送大量数据时,DMA可以用来自动传输数据。以SPI为例,当SPI从外部设备读取大量的数据(如读取外部Flash中的数据),DMA可以将接收到的数据直接存储到内存中,减少CPU的开销,加快数据传输速度。