DMA,全称是 Direct Memory Access,中文意思为直接存储器访问。DMA 可用于实现外设与存储器之间或者存储器与存储器之间数据传输的高效性。之所以称为高效, 是因为 DMA 传输数据移动过程无需 CPU 直接操作, 这样节省的 CPU 资源就可供其它操作使用。从硬件层面来理解,DMA 就好像是 RAM 与 I/O 设备间数据传输的通路, 外设与存储器之间或者存储器与存储器之间可以直接在这条通路上进行数据传输。这里说的外设一般指外设的数据寄存器, 比如 ADC、SPI、I2C、DCMI等外设的数据寄存器, 存储器一般是指片内 SRAM、 外部存储器、 片内 Flash等。
我们知道CPU有转移数据、计算、控制程序转移等很多功能,系统运作的核心就是CPU,
CPU无时不刻的在处理着大量的事务,但有些事情却没有那么重要,比方说数据的复制和存储数据,如果我们把这部分的CPU资源拿出来,让CPU去处理其他的复杂计算事务,是不是能够更好的利用CPU的资源呢?
因此:转移数据(尤其是转移大量数据)是可以不需要CPU参与。比如希望外设A的数据拷贝到外设B,只要给两种外设提供一条数据通路,直接让数据由A拷贝到B 不经过CPU的处理。
关于DMA原理的详细解释请看这一篇文章
【STM32】 DMA原理,步骤超细详解,一文看懂DMA-CSDN博客
CUBEMX配置(这里以串口为例)
首先先将串口配置好,然后打开串口中断
DMA传输方式
方法1:DMA_Mode_Normal,正常模式,
当一次DMA数据传输完后,停止DMA传送 ,也就是只传输一次
方法2:DMA_Mode_Circular ,循环传输模式
当传输结束时,硬件自动会将传输数据量寄存器进行重装,进行下一轮的数据传输。 也就是多次传输模式
我们这里选择循环传输模式
代码部分
先定义两个数组,分别用来接受和传输
uint8_t aRxbuffer[1];
uint8_t aTxbuffer[]="ok";
打开两个DMA
HAL_UART_Receive_DMA(&huart1,aRxbuffer,1);
HAL_UART_Transmit_DMA(&huart1,aTxbuffer,sizeof(aTxbuffer));
打开串口中断回调
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)
{
HAL_UART_Transmit(&huart1 ,aRxbuffer,1,0);
}
这里就是电脑发送什么到芯片里面,然后芯片发送相同的数据到单片机