跳到主要内容

STM32 UART DMA

介绍

在嵌入式系统中,串行通信(如 UART)是一种常见的数据传输方式。然而,当需要传输大量数据时,使用传统的轮询或中断方式可能会导致 CPU 资源的大量占用,从而影响系统的整体性能。为了解决这个问题,STM32 微控制器提供了 DMA(直接内存访问)功能,它可以在不占用 CPU 资源的情况下,自动完成数据的传输。

本文将详细介绍如何在 STM32 中使用 UART 和 DMA 进行高效的数据传输,并通过代码示例和实际应用场景帮助初学者理解这一概念。

什么是 DMA?

DMA(Direct Memory Access,直接内存访问)是一种硬件功能,允许外设直接与内存进行数据交换,而不需要 CPU 的干预。通过使用 DMA,CPU 可以专注于其他任务,从而提高系统的整体效率。

在 STM32 中,DMA 可以用于多种外设,如 UART、SPI、I2C 等。本文将重点介绍如何在 UART 通信中使用 DMA。

STM32 UART DMA 的基本原理

在 STM32 中,UART 通信通常需要发送和接收数据。使用 DMA 时,可以将 UART 的数据寄存器与内存缓冲区关联起来,DMA 控制器会自动将数据从内存传输到 UART 数据寄存器(发送),或者从 UART 数据寄存器传输到内存(接收)。

UART DMA 发送

当使用 DMA 发送数据时,DMA 控制器会从内存中读取数据,并将其写入 UART 的数据寄存器。这样,CPU 只需要初始化 DMA 传输,然后就可以继续执行其他任务,而不需要等待数据传输完成。

UART DMA 接收

当使用 DMA 接收数据时,DMA 控制器会从 UART 的数据寄存器中读取数据,并将其写入内存缓冲区。这样,CPU 可以在数据接收完成后,一次性处理接收到的数据,而不需要在每次接收到一个字节时都触发中断。

代码示例

以下是一个简单的代码示例,展示了如何在 STM32 中使用 UART 和 DMA 进行数据传输。

初始化 UART 和 DMA

c
#include "stm32f4xx_hal.h"

UART_HandleTypeDef huart2;
DMA_HandleTypeDef hdma_usart2_tx;
DMA_HandleTypeDef hdma_usart2_rx;

void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_USART2_UART_Init(void);

int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_DMA_Init();
MX_USART2_UART_Init();

uint8_t txData[] = "Hello, UART DMA!";
uint8_t rxData[20];

// 启动 DMA 接收
HAL_UART_Receive_DMA(&huart2, rxData, sizeof(rxData));

// 启动 DMA 发送
HAL_UART_Transmit_DMA(&huart2, txData, sizeof(txData));

while (1)
{
// 主循环
}
}

void SystemClock_Config(void)
{
// 系统时钟配置
}

static void MX_GPIO_Init(void)
{
// GPIO 初始化
}

static void MX_DMA_Init(void)
{
// DMA 初始化
}

static void MX_USART2_UART_Init(void)
{
// UART 初始化
}

解释

  1. 初始化 UART 和 DMA:在 MX_USART2_UART_Init()MX_DMA_Init() 函数中,我们分别初始化了 UART 和 DMA 控制器。
  2. 启动 DMA 接收:使用 HAL_UART_Receive_DMA() 函数启动 DMA 接收,DMA 控制器会自动将接收到的数据存储到 rxData 缓冲区中。
  3. 启动 DMA 发送:使用 HAL_UART_Transmit_DMA() 函数启动 DMA 发送,DMA 控制器会自动将 txData 缓冲区中的数据发送出去。

实际应用场景

数据传输

在需要传输大量数据的应用中,如传感器数据采集、无线通信模块的数据传输等,使用 UART DMA 可以显著提高系统的效率。例如,在一个传感器数据采集系统中,传感器可能会以较高的频率发送数据,使用 DMA 可以确保数据不会丢失,同时减少 CPU 的负担。

实时通信

在实时通信系统中,如工业控制、机器人控制等,使用 UART DMA 可以确保数据的实时性和可靠性。通过 DMA,系统可以在不中断 CPU 的情况下,快速处理接收到的数据,并及时发送响应。

总结

通过本文的介绍,我们了解了如何在 STM32 中使用 UART 和 DMA 进行高效的数据传输。DMA 可以显著减少 CPU 的负担,提高系统的整体性能。在实际应用中,UART DMA 可以用于数据传输、实时通信等多种场景。

附加资源

练习

  1. 修改代码示例,使其能够接收不定长度的数据,并在接收到特定字符(如换行符)时触发中断。
  2. 尝试在代码中添加错误处理机制,以应对 DMA 传输过程中可能出现的错误。
提示

在实际开发中,建议使用 STM32CubeMX 工具来生成初始化代码,这样可以减少手动配置的工作量,并避免配置错误。