STM32 cubemx配置USART DMA传输

简介: STM32 cubemx配置USART DMA传输

前言

本篇文章来讲解DMA的概念,并使用DMA来进行串口的数据收发。

一、DMA概念

DMA(Direct Memory Access,直接内存访问)是一种计算机系统的技术,允许外部设备(如硬盘驱动器、网络适配器或图形卡)直接与计算机内存进行数据传输,而不需要CPU的直接参与。这种直接的内存访问可以提高数据传输的效率,并减轻CPU的负担。

在没有DMA的情况下,数据传输通常需要通过CPU来完成,这涉及到CPU的中断处理程序从设备读取数据,然后将数据写入内存,或者从内存读取数据,然后将数据发送到设备。这种方式会消耗CPU的时间和计算资源,限制了系统的性能和吞吐量。

通过DMA技术,外部设备可以直接与系统内存进行数据传输,而不需要CPU的干预。在DMA传输开始之前,系统配置好DMA控制器,并提供一个DMA缓冲区,外部设备可以将数据直接写入到该缓冲区或者从该缓冲区读取数据。当DMA传输完成后,DMA控制器会发出一个中断信号,以通知CPU。

使用DMA的好处包括:

1.提高数据传输速度:由于数据传输不需要CPU的介入,DMA可以以更高的速度进行数据传输,从而提高系统性能和吞吐量。

2.减轻CPU负担:传统的数据传输需要CPU的参与,消耗CPU的时间和计算资源。而使用DMA进行数据传输时,CPU可以专注于其他的计算任务,减轻了CPU的负担。

3.支持大规模数据传输:DMA技术可以支持大规模的数据传输,例如高清视频流、大型文件和网络数据包的处理。

总之,DMA是一种能够提高系统性能和数据传输效率的技术,通过允许外部设备直接与内存进行数据传输,减少了CPU的介入。这在需要高速、大量或连续数据传输的场景中特别有用,如高性能计算、网络通信和存储系统等。

二、STM32 DMA数据手册分析

从DMA的描述来看在STM32 F103这款芯片中有DMA1和DMA2,DMA1有7个通道,DMA2有5个通道。

DMA架构图:

DMA支持直接和SRMA进行数据的传输,不需要经过CPU,这样就可以让CPU去做其他的事情,提高系统的运行效率。

使用DMA(Direct Memory Access)进行数据传输时,通常需要经过以下步骤:

1.设置DMA控制器:首先,需要在系统中配置和设置DMA控制器。这包括设置DMA的源地址和目标地址,传输长度,传输方向(从内存到设备或从设备到内存),以及其他相关参数。

2.发送DMA请求:在数据传输之前,需要向DMA控制器发送DMA请求。该请求通常由CPU或设备发起,用于指示DMA控制器执行特定的数据传输操作。

3.DMA传输:一旦DMA请求被接收和识别,DMA控制器将启动数据传输。它将直接从源地址读取数据,并将数据传输到目标地址。在传输过程中,DMA控制器绕过CPU,直接控制内存和设备之间的数据传输,以提高数据传输效率并减轻CPU的负担。

4.中断或完成通知:一旦DMA传输完成,DMA控制器通常会生成一个中断信号或发送一个完成通知,以通知CPU或相关设备传输已经完成。

正常进行数据的发送:

不使用DMA进行串口的数据发送时,CPU需要从SRMA中读取出存储的数据,然后再发送给串口,发送少量数据是不会影响CPU执行其他事情的,假如我想发送10000个数据,那么这个时候就会让CPU处于一直在发送数据的状态,这样就会影响到其他程序的执行。

根据手册描述DMA和CPU共享总线来执行直接的内存传输。

DMA可以直接访问到外设和SRMA,那么这样就不需要CPU来进行数据的读取交换了,直接使用DMA就可以解决这个问题,那么这样的话就可以提高系统的运行效率了。

3.DMA模式介绍

下面我们来看到DMA的两种模式,一种是循环模式,一种是内存到内存的模式。

DMA的循环模式(Circular Mode):

在循环模式下,DMA传输的数据可以在源和目的地之间循环传输,以连续地进行数据传输操作。这种模式下,一旦DMA传输完成,它会自动重新开始下一轮传输,而无需软件干预。

循环模式对于需要在连续数据块之间进行重复传输的应用非常有用,如音频、视频流等。它可以在不中断DMA传输的情况下循环传输数据,大大提高了数据传输效率和系统性能。

DMA的内存到内存模式(Memory-to-memory Mode):

内存到内存模式允许DMA直接在两个内存区域之间进行数据传输,而无需外设的参与。在这种模式下,DMA通道可以从一个内存位置读取数据,并将数据直接写入另一个内存位置,而不需要CPU的介入。

内存到内存模式非常适用于需要在内存之间快速传输数据的应用场景,例如内存拷贝、内存填充等。通过使用这种模式,DMA可以独立地执行数据传输,减轻CPU的负担,提高传输效率。

总结:DMA的循环模式允许数据在源和目的地之间循环传输,连续进行数据传输操作,并在每次传输完成后自动重新开始下一轮传输。而DMA的内存到内存模式允许DMA直接在两个内存区域之间传输数据,而不需要外设的触发请求,并且能够快速、高效地在内存之间传输数据。这两种模式都有助于提高数据传输效率并减轻CPU的负担,适用于不同的应用场景。

4.cubemx配置

配置一个LED灯观察实验现象:

配置串口1:

开启串口中断:

这里不开启串口中断的话无法判断串口是否发送完成一次数据,这样串口就一直处于忙状态导致完成进行下一次的发送。

DMA通道设置:

TX设置为从内存到外设,因为串口的发送就是把内存中的数据取出来再发给外设,RX设置为从外设到内存,串口发送过来的数据将会保存在内存中。

模式选择Normal,循环模式的话只需要调用一次发送函数就会一直进行数据的发送了。

具体代码:

这里发送一个非常长的数据,同时让这个LED闪烁,看看串口的发送会不会影响到LED的闪烁,结果是不会的。

uint8_t msg[1024] = "hellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohello";
  while (1)
  {
    /* USER CODE END WHILE */
    /* USER CODE BEGIN 3 */
    HAL_UART_Transmit_DMA(&huart1, msg, strlen(msg) + 1);
    HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_5);
    HAL_Delay(100);
  }

总结

本篇文章就讲解到这里,下篇文章我们讲解DMA的具体配置和DMA串口接收不定长数据。


相关文章
|
5月前
stm32f407探索者开发板(十七)——串口寄存器库函数配置方法
stm32f407探索者开发板(十七)——串口寄存器库函数配置方法
786 0
|
1月前
|
存储 数据管理 数据处理
处理STM32 DMA方式下的HAL_UART_ERROR_ORE错误
通过正确配置UART和DMA、实现有效的错误处理回调函数以及优化数据处理和缓冲区管理,可以有效处理STM32中DMA方式下的 `HAL_UART_ERROR_ORE`错误。这些方法确保了数据的高效传输和处理,避免了因数据溢出导致的通信中断和数据丢失。希望这些解决方案能够帮助您在实际应用中更好地应对和解决此类问题。
212 0
|
7月前
|
传感器
STM32标准库ADC和DMA知识点总结-1
STM32标准库ADC和DMA知识点总结
|
6月前
|
传感器
【经典案例】STM32F407使用HAL库配置I2C详解
STM32F407是一个强大的微控制器,广泛应用于嵌入式系统中。在许多应用中,我们需要使用I2C总线来与传感器、EEPROM、显示屏等外设进行通信。本文将详细介绍如何使用STM32 HAL库来配置和使用I2C接口。
799 2
|
6月前
|
开发者
【经典案例】使用HAL库配置STM32F407的SPI外设
在嵌入式系统开发中,STM32F407是一款广泛应用的微控制器,而SPI(Serial Peripheral Interface)是一种常用的通信接口。本文将详细介绍如何使用STM32的硬件抽象层(HAL)库配置STM32F407的SPI外设,并提供完整的代码示例。
647 1
|
5月前
|
传感器 编解码 API
【STM32开发入门】温湿度监测系统实战:SPI LCD显示、HAL库应用、GPIO配置、UART中断接收、ADC采集与串口通信全解析
SPI(Serial Peripheral Interface)是一种同步串行通信接口,常用于微控制器与外围设备间的数据传输。SPI LCD是指使用SPI接口与微控制器通信的液晶显示屏。这类LCD通常具有较少的引脚(通常4个:MISO、MOSI、SCK和SS),因此在引脚资源有限的系统中非常有用。通过SPI协议,微控制器可以向LCD发送命令和数据,控制显示内容和模式。
207 0
|
5月前
|
数据安全/隐私保护
STM32F103C8T6实现简易密码锁(CubeMax配置)(一),Oled显示。
项目功能:实现设置密码,登陆密码,后期还可以通过E2PROM实现掉电不丢失数据。通过Oled的显示去判断我们是否设置或者登陆成功。
111 0
|
6月前
|
芯片
【STM32】详解RTC实时时钟的概念和配置&示例代码
【STM32】详解RTC实时时钟的概念和配置&示例代码