登录/注册

STM32DMA收发程序

STM32DMA收发程序

更多

以下是一个基于STM32的USART DMA收发程序示例(使用HAL库,以STM32F4为例):

硬件配置


程序代码

#include "stm32f4xx_hal.h"

UART_HandleTypeDef huart1;
DMA_HandleTypeDef hdma_usart1_tx;
DMA_HandleTypeDef hdma_usart1_rx;

uint8_t rx_buffer[64];  // 接收缓冲区
uint8_t tx_buffer[] = "Hello from STM32!\r\n";  // 发送数据

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

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

  // 启动DMA接收(循环模式)
  HAL_UART_Receive_DMA(&huart1, rx_buffer, sizeof(rx_buffer));

  while (1) {
    // 检测到回车符时回传数据
    for (int i = 0; i < sizeof(rx_buffer); i++) {
      if (rx_buffer[i] == '\r' || rx_buffer[i] == '\n') {
        HAL_UART_Transmit_DMA(&huart1, rx_buffer, i);  // DMA发送
        HAL_Delay(10);
        memset(rx_buffer, 0, sizeof(rx_buffer));  // 清空缓冲区
        break;
      }
    }
    HAL_Delay(10);
  }
}

// USART1初始化
void MX_USART1_UART_Init(void) {
  huart1.Instance = USART1;
  huart1.Init.BaudRate = 115200;
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  HAL_UART_Init(&huart1);
}

// DMA初始化
void MX_DMA_Init(void) {
  __HAL_RCC_DMA2_CLK_ENABLE();

  // TX DMA配置
  hdma_usart1_tx.Instance = DMA2_Stream7;
  hdma_usart1_tx.Init.Channel = DMA_CHANNEL_4;
  hdma_usart1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
  hdma_usart1_tx.Init.PeriphInc = DMA_PINC_DISABLE;
  hdma_usart1_tx.Init.MemInc = DMA_MINC_ENABLE;
  hdma_usart1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
  hdma_usart1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
  hdma_usart1_tx.Init.Mode = DMA_NORMAL;  // 非循环模式
  hdma_usart1_tx.Init.Priority = DMA_PRIORITY_LOW;
  hdma_usart1_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
  HAL_DMA_Init(&hdma_usart1_tx);
  __HAL_LINKDMA(&huart1, hdmatx, hdma_usart1_tx);

  // RX DMA配置
  hdma_usart1_rx.Instance = DMA2_Stream2;
  hdma_usart1_rx.Init.Channel = DMA_CHANNEL_4;
  hdma_usart1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
  hdma_usart1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
  hdma_usart1_rx.Init.MemInc = DMA_MINC_ENABLE;
  hdma_usart1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
  hdma_usart1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
  hdma_usart1_rx.Init.Mode = DMA_CIRCULAR;  // 循环模式
  hdma_usart1_rx.Init.Priority = DMA_PRIORITY_HIGH;
  hdma_usart1_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
  HAL_DMA_Init(&hdma_usart1_rx);
  __HAL_LINKDMA(&huart1, hdmarx, hdma_usart1_rx);
}

// DMA发送完成中断回调
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) {
  if (huart->Instance == USART1) {
    // 可在此添加发送完成后的操作
  }
}

// DMA接收半满/全满中断(需在stm32f4xx_it.c中实现中断服务函数)
void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart) { /* 半满处理 */ }
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { /* 全满处理 */ }

关键点说明

  1. DMA模式选择

    • TXDMA_NORMAL(发送完成后需重新启动)
    • RXDMA_CIRCULAR(自动循环填充接收缓冲区)
  2. 接收数据处理

    • 主循环检测接收缓冲区的回车符 \r\n
    • 检测到后通过DMA回传数据(非阻塞)
  3. 中断配置

    • stm32f4xx_it.c 中添加DMA和USART中断服务函数
    • 启用DMA流中断:HAL_DMA_Start_IT()
    • 启用USART空闲中断(可选,用于不定长数据)
  4. 优化建议

    • 使用 空闲中断(IDLE) + DMA接收 实现不定长数据接收
    • 添加环形缓冲区提高数据处理效率
    • 在DMA发送完成中断中启动下一次发送

⚠️ 注意:实际使用时需在CubeMX中配置时钟和引脚,并生成初始化代码。不同STM32系列的DMA配置可能有所差异(如F1/F7/H7等),请参考对应型号的参考手册。

STM32 DMA传输的问题分析

用户使用STM32G473RET6芯片,开发环境STM32CubeMX+Keil(LL库)。使用DMA1通道1,在半传输中断和完全传输中断里,拷

2023-12-01 09:19:48

STM32实例教程-DMA实验

在前面我们提到过 DMA,这一章我们就来学习 STM32F1 的DMA 使用。要实现的功能是:通过 K_UP 按键控制

2023-05-24 09:20:54

STM32CUBEMX开发GD32F303(9)----USART通过DMA收发

概述 本章STM32CUBEMX配置STM32F103,并且在GD32F303中进行开发,同时通过GD32303C_START开发板内进行验证。 本章主要配置串口进行

2022-11-29 11:15:15

stm32g030多路adc DMA采集程序

stm32g030_多路adc_DMA采集程序

资料下载 过往5 2023-06-19 09:43:09

stm32的串口DMA空闲中断接收不等长数据,stm32F1的usart1-DMA-IDLE收发

stm32的DMA收发原理,见另一篇:https://blog.csdn.net/Mark_md/article/details/1072430

资料下载 贾桂林 2021-12-28 19:35:45

STM32之串口DMA接收不定长数据

目录STM32之串口DMA接收不定长数据引言DMA简介什么是DMA在

资料下载 刘敏 2021-12-24 19:03:03

STM32——采用DMA的方式实现串口收发数据

STM32-----采用DMA的方式实现串口收发数据概述想必看到这篇博客的你已经知道了

资料下载 南风一号 2021-12-20 19:40:25

STM32F103ZET6实现LWIP网络通信和ADC采样及DMA串口收发的工程文件

本文档的主要内容详细介绍的是STM32F103ZET6实现LWIP网络通信和ADC采样及DMA串口收发的

资料下载 九月九_1989 2020-01-15 08:00:00

如何实现STM32串口DMA收发数据?

串口基本原理是什么?如何实现STM32串口DMA收发数据?

2022-02-18 06:18:22

如何采用DMA的方式实现串口收发数据

STM32-----采用DMA的方式实现串口收发数据概述想必看到这篇博客的你已经知道了

2022-02-17 07:38:20

STM32串口收发数据为什么要使用DMA

CPU处理。因此,大量数据拷贝时,使用DMA可以释放CPU资源,相关文章推荐:详解STM32中的DMA原理。

2022-02-12 13:22:10

FIFO是如何结合STM32DMA去实现串口数据的收发

FIFO是如何结合STM32的DMA去实现串口数据的收发呢?

2021-12-07 07:56:23

怎么实现STM32串口DMA收发

STM32 DMA具有哪些功能?怎么实现STM32串口DMA

2021-12-06 07:27:59

STM32F103 串口 +DMA中断实现数据收发 精选资料分享

01 STM32F103 串口DMA + 空闲中断 实现不定长数据收发02文章目录1. 代码讲解1.1 uart_

2021-08-13 08:39:31

STM32F0xx_ DMA收发USART数据配置详细过程

STM32F0xx_DMA收发USART数据配置详细过程

2020-04-08 09:02:51

7天热门专题 换一换
相关标签