自己做的网页怎么上传到网站吗,高明网站开发公司,h5网站制作视频,三合一 网站 前端STM32的DMA#xff08;Direct Memory Access#xff0c;直接存储器存取#xff09;是一种在单片机中用于高效实现数据传输的技术。它允许外设设备直接访问RAM#xff0c;不需要CPU的干预#xff0c;从而释放CPU资源#xff0c;提高CPU工作效率#xff0c;本文基于STM32F…STM32的DMADirect Memory Access直接存储器存取是一种在单片机中用于高效实现数据传输的技术。它允许外设设备直接访问RAM不需要CPU的干预从而释放CPU资源提高CPU工作效率本文基于STM32F429、Hal库详细分析DMA的特性与使用。
1.DMA的特性
1STM32F429拥有两个DMA控制器DMA1和DMA2DMA1 控制器 AHB 外设端口不连接到总线矩阵因此只有 DMA2 数据流能够执行存储器到存储器的传输外设包括片内外设和片外外设。
片内外设例如GPIO通用输入输出端口、USART通用同步/异步收发器、I2CInter-Integrated Circuit一种串行通信总线、SPISerial Peripheral Interface串行外设接口等。这些外设通过DMA控制器可以直接与内存如SRAM、Flash等进行数据传输。
片外外设这是指通过外部接口连接到STM32芯片的设备例如DHT11温度传感器、MQ2烟雾传感器等。这些设备通过相应的接口如ADC、SPI等与STM32连接然后通过DMA控制器进行数据传输要确保片外外设支持DMA功能才可以用DMA传输数据。 存储器到存储器的传输意味着DMA控制器可以直接从一个内存区域如RAM的一个数组或缓冲区读取数据并将这些数据写入到另一个内存区域同样是RAM的另一个数组或缓冲区。这种传输模式在多种应用中都非常有用比如 数据移动如果你需要将一段数据从一个位置移动到另一个位置使用DMA可以节省CPU时间因为CPU不需要参与数据的传输过程。 数据处理在图像处理、音频处理或任何需要处理大量数据的应用中你可能需要将数据从一个缓冲区读取出来进行一些处理如滤波、FFT等然后将结果写回另一个缓冲区。使用DMA可以并行地进行数据的读取和写入从而加速整个处理过程。 数据桥接在某些应用中你可能需要从一个硬件接口读取数据然后将其写入到另一个硬件接口。使用DMA可以确保这两个接口之间的数据传输是高效的不会受到CPU中断或其他任务的影响。 循环缓冲区在处理实时数据流时循环缓冲区是一种常见的解决方案。使用DMA可以自动地将新数据写入循环缓冲区的末尾并将旧数据从缓冲区的开头移出从而实现无缝的数据传输和处理。 2每个DMA控制器有8个数据流每个数据流拥有8个通道每次传输的数据最大为65535如果数据单位为字则一次可以传输256KB每个通道具体是什么数据接口如下图所示
DMA1通道 DMA2通道 3DMA传输具有FIFO先进先出模式和直接模式。FIFO用于在源数据传输到目标地址之前临时存放这些数据每个数据流都有一个独立的 4 字 FIFO阈值级别可由软件配置为 1/4、1/2、3/4 或满。而直接模式在每个外设请求都立即启动对存储器传输。 4数据流与数据流之间的传输优先级通过软件和硬件两个方面决定。软件上可以通过DMA_SxCR寄存器配置数据流的优先级总共有四个等级非常高、高、中、低。硬件上若两个请求的软件优先级相同时仲裁器根据DMA通道的编号来决定响应顺序序号较小的数据流优先级更高另外DMA1拥有比DMA2更高的优先级。 5DMA支持源地址和目标地址的数据宽度可以不同如源数据是源源不断的字节数据而目标地址要求输出字宽度的数据。源传输和目标传输在整个 4 GB 区域地址在 0x0000 0000 和 0xFFFF FFFF 之间都可以寻址外设和存储器。 6DMA拥有5个中断分别是半传输、传输完成、传输错误、FIFO 上溢/下溢、直接模式错误。 2.DMA的使用
下面我们将一些数据通过DMA2的UART1输出出来
1使能DMA时钟 __HAL_RCC_DMA2_CLK_ENABLE();//DMA2时钟使能
(2) 初始化DMA通道配置通道外设和内存地址传输数据量等
__HAL_LINKDMA(UART1_Handler,hdmatx,UART1TxDMA_Handler); //将DMA与USART1联系起来(发送DMA)//Tx DMA配置UART1TxDMA_Handler.InstanceDMA2_Stream7; //数据流选择DMA2控制器的数据流7UART1TxDMA_Handler.Init.ChannelDMA_CHANNEL_4; //通道选择4UART1TxDMA_Handler.Init.DirectionDMA_MEMORY_TO_PERIPH; //存储器到外设UART1TxDMA_Handler.Init.PeriphIncDMA_PINC_DISABLE; //外设非增量模式UART1TxDMA_Handler.Init.MemIncDMA_MINC_ENABLE; //存储器增量模式UART1TxDMA_Handler.Init.PeriphDataAlignmentDMA_PDATAALIGN_BYTE; //外设数据长度:8位UART1TxDMA_Handler.Init.MemDataAlignmentDMA_MDATAALIGN_BYTE; //存储器数据长度:8位UART1TxDMA_Handler.Init.ModeDMA_NORMAL; //外设普通模式UART1TxDMA_Handler.Init.PriorityDMA_PRIORITY_MEDIUM; //中等优先级UART1TxDMA_Handler.Init.FIFOModeDMA_FIFOMODE_DISABLE; UART1TxDMA_Handler.Init.FIFOThresholdDMA_FIFO_THRESHOLD_FULL; UART1TxDMA_Handler.Init.MemBurstDMA_MBURST_SINGLE; //存储器突发单次传输UART1TxDMA_Handler.Init.PeriphBurstDMA_PBURST_SINGLE; //外设突发单次传输HAL_DMA_DeInit(UART1TxDMA_Handler); HAL_DMA_Init(UART1TxDMA_Handler);
3开启DMA通道传输 MYDMA_USART_Transmit(UART1_Handler,(u8*)SendBuff,SEND_BUF_SIZE); //启动传输 4 查询DMA通道状态,传输结束后关闭串口DMA
while(1){if(__HAL_DMA_GET_FLAG(UART1TxDMA_Handler,DMA_FLAG_TCIF3_7))//等待DMA2_Steam7传输完成{__HAL_DMA_CLEAR_FLAG(UART1TxDMA_Handler,DMA_FLAG_TCIF3_7);//清除DMA2_Steam7传输完成标志HAL_UART_DMAStop(UART1_Handler); //传输完成以后关闭串口DMAbreak; }delayms(10);
}