[STM32H7] STM32H743性能解析:DMA与UART的高效数据传输实现

[复制链接]
 楼主| Clyde011 发表于 2024-11-24 07:46 | 显示全部楼层 |阅读模式
STM32H743是STMicroelectronics推出的一款高性能微控制器,采用Cortex-M7内核,主频高达480MHz,内置丰富的外设,适合高性能嵌入式应用。在本篇文章中,我们将使用STM32H743探索如何结合DMA(直接存储器访问)和UART实现高效的数据传输。

使用DMA与UART的优势通常情况下,UART数据传输需要由CPU处理发送和接收的数据,这会占用大量CPU资源。而DMA可以独立于CPU,将数据直接传输到指定存储器,极大提高传输效率。STM32H743提供多通道DMA控制器,可以支持多外设同时工作。

实验内容我们将通过以下步骤实现UART和DMA的结合:
  • 配置UART用于数据发送与接收;
  • 配置DMA,用于高效传输数据;
  • 编写代码实现UART与DMA的协同工作。

硬件与软件环境
  • 硬件

    • STM32H743 Nucleo开发板
    • USB转UART模块
    • PC,用于串口调试
  • 软件

    • STM32CubeMX:生成代码框架
    • STM32CubeIDE:编写和调试代码

DMA与UART代码实现以下是DMA和UART功能的具体实现代码:
  1. #include "main.h"

  2. // UART和DMA句柄定义
  3. UART_HandleTypeDef huart3;
  4. DMA_HandleTypeDef hdma_usart3_tx;
  5. DMA_HandleTypeDef hdma_usart3_rx;

  6. // 发送和接收缓冲区
  7. uint8_t tx_buffer[] = "Hello, DMA with UART!\r\n";
  8. uint8_t rx_buffer[100];

  9. void SystemClock_Config(void);
  10. static void MX_GPIO_Init(void);
  11. static void MX_DMA_Init(void);
  12. static void MX_USART3_UART_Init(void);

  13. int main(void) {
  14.     HAL_Init();
  15.     SystemClock_Config();

  16.     // 初始化外设
  17.     MX_GPIO_Init();
  18.     MX_DMA_Init();
  19.     MX_USART3_UART_Init();

  20.     // 使用DMA发送数据
  21.     if (HAL_UART_Transmit_DMA(&huart3, tx_buffer, sizeof(tx_buffer) - 1) != HAL_OK) {
  22.         Error_Handler();
  23.     }

  24.     // 启动DMA接收
  25.     if (HAL_UART_Receive_DMA(&huart3, rx_buffer, sizeof(rx_buffer)) != HAL_OK) {
  26.         Error_Handler();
  27.     }

  28.     while (1) {
  29.         // 主循环中可以处理其他任务
  30.     }
  31. }

  32. // USART3初始化函数
  33. static void MX_USART3_UART_Init(void) {
  34.     huart3.Instance = USART3;
  35.     huart3.Init.BaudRate = 115200;
  36.     huart3.Init.WordLength = UART_WORDLENGTH_8B;
  37.     huart3.Init.StopBits = UART_STOPBITS_1;
  38.     huart3.Init.Parity = UART_PARITY_NONE;
  39.     huart3.Init.Mode = UART_MODE_TX_RX;
  40.     huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  41.     huart3.Init.OverSampling = UART_OVERSAMPLING_16;
  42.     if (HAL_UART_Init(&huart3) != HAL_OK) {
  43.         Error_Handler();
  44.     }
  45. }

  46. // DMA初始化函数
  47. static void MX_DMA_Init(void) {
  48.     __HAL_RCC_DMA1_CLK_ENABLE();

  49.     // 初始化DMA1_Channel2用于USART3_TX
  50.     hdma_usart3_tx.Instance = DMA1_Channel2;
  51.     hdma_usart3_tx.Init.Request = DMA_REQUEST_USART3_TX;
  52.     hdma_usart3_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
  53.     hdma_usart3_tx.Init.PeriphInc = DMA_PINC_DISABLE;
  54.     hdma_usart3_tx.Init.MemInc = DMA_MINC_ENABLE;
  55.     hdma_usart3_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
  56.     hdma_usart3_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
  57.     hdma_usart3_tx.Init.Mode = DMA_NORMAL;
  58.     hdma_usart3_tx.Init.Priority = DMA_PRIORITY_LOW;
  59.     if (HAL_DMA_Init(&hdma_usart3_tx) != HAL_OK) {
  60.         Error_Handler();
  61.     }
  62.     __HAL_LINKDMA(&huart3, hdmatx, hdma_usart3_tx);

  63.     // 初始化DMA1_Channel3用于USART3_RX
  64.     hdma_usart3_rx.Instance = DMA1_Channel3;
  65.     hdma_usart3_rx.Init.Request = DMA_REQUEST_USART3_RX;
  66.     hdma_usart3_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
  67.     hdma_usart3_rx.Init.PeriphInc = DMA_PINC_DISABLE;
  68.     hdma_usart3_rx.Init.MemInc = DMA_MINC_ENABLE;
  69.     hdma_usart3_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
  70.     hdma_usart3_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
  71.     hdma_usart3_rx.Init.Mode = DMA_CIRCULAR;
  72.     hdma_usart3_rx.Init.Priority = DMA_PRIORITY_HIGH;
  73.     if (HAL_DMA_Init(&hdma_usart3_rx) != HAL_OK) {
  74.         Error_Handler();
  75.     }
  76.     __HAL_LINKDMA(&huart3, hdmarx, hdma_usart3_rx);
  77. }

  78. // GPIO初始化函数
  79. static void MX_GPIO_Init(void) {
  80.     __HAL_RCC_GPIOB_CLK_ENABLE();
  81.     // 可添加额外的GPIO配置代码
  82. }
测试与验证
  • 将开发板与PC通过USB转UART模块连接。
  • 使用串口调试助手查看数据发送情况,并通过串口发送测试数据。
  • 观察是否正确接收到数据,同时检查DMA是否成功释放CPU资源。

总结本文基于STM32H743实现了DMA与UART的高效协同工作。通过结合DMA的高速传输能力与UART的串口通信功能,我们可以显著降低CPU占用率,为复杂嵌入式应用提供更多资源。如果你有更复杂的通信需求,可以进一步优化DMA与UART的配置,比如使用FIFO模式或设置优先级。

公羊子丹 发表于 2024-11-24 07:47 来自手机 | 显示全部楼层
哇,这篇文章让我瞬间明白DMA的优势,真不错!
周半梅 发表于 2024-11-24 07:47 来自手机 | 显示全部楼层
STM32H743性能真的强,这个代码能跑到别的STM32上吗?
帛灿灿 发表于 2024-11-24 07:47 来自手机 | 显示全部楼层
大佬讲解的很细,我要赶紧试试这个示例!
童雨竹 发表于 2024-11-24 07:48 来自手机 | 显示全部楼层
我之前直接用HAL库写UART,没用DMA,效率确实差点。
万图 发表于 2024-11-24 07:48 来自手机 | 显示全部楼层
Circular模式用在接收上很有用啊,学到了!
Wordsworth 发表于 2024-11-24 07:48 来自手机 | 显示全部楼层
有没有可能支持多个串口同时用DMA传输?求代码!
Bblythe 发表于 2024-11-24 07:48 来自手机 | 显示全部楼层
USART3的引脚能不能用其他的引脚复用?好像我用的板子没这个接口。
Pulitzer 发表于 2024-11-24 07:49 来自手机 | 显示全部楼层
感觉STM32CubeMX生成代码方便多了,以前手写真的费劲。
Uriah 发表于 2024-11-24 07:49 来自手机 | 显示全部楼层
如果数据量更大,比如几千字节,DMA还能保持高效吗?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

139

主题

5528

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部