STM32H743性能解析:DMA与UART的高效数据传输实现
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功能的具体实现代码:
#include "main.h"
// UART和DMA句柄定义
UART_HandleTypeDef huart3;
DMA_HandleTypeDef hdma_usart3_tx;
DMA_HandleTypeDef hdma_usart3_rx;
// 发送和接收缓冲区
uint8_t tx_buffer[] = "Hello, DMA with UART!\r\n";
uint8_t rx_buffer;
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_USART3_UART_Init(void);
int main(void) {
HAL_Init();
SystemClock_Config();
// 初始化外设
MX_GPIO_Init();
MX_DMA_Init();
MX_USART3_UART_Init();
// 使用DMA发送数据
if (HAL_UART_Transmit_DMA(&huart3, tx_buffer, sizeof(tx_buffer) - 1) != HAL_OK) {
Error_Handler();
}
// 启动DMA接收
if (HAL_UART_Receive_DMA(&huart3, rx_buffer, sizeof(rx_buffer)) != HAL_OK) {
Error_Handler();
}
while (1) {
// 主循环中可以处理其他任务
}
}
// USART3初始化函数
static void MX_USART3_UART_Init(void) {
huart3.Instance = USART3;
huart3.Init.BaudRate = 115200;
huart3.Init.WordLength = UART_WORDLENGTH_8B;
huart3.Init.StopBits = UART_STOPBITS_1;
huart3.Init.Parity = UART_PARITY_NONE;
huart3.Init.Mode = UART_MODE_TX_RX;
huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart3.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart3) != HAL_OK) {
Error_Handler();
}
}
// DMA初始化函数
static void MX_DMA_Init(void) {
__HAL_RCC_DMA1_CLK_ENABLE();
// 初始化DMA1_Channel2用于USART3_TX
hdma_usart3_tx.Instance = DMA1_Channel2;
hdma_usart3_tx.Init.Request = DMA_REQUEST_USART3_TX;
hdma_usart3_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_usart3_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart3_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart3_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart3_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart3_tx.Init.Mode = DMA_NORMAL;
hdma_usart3_tx.Init.Priority = DMA_PRIORITY_LOW;
if (HAL_DMA_Init(&hdma_usart3_tx) != HAL_OK) {
Error_Handler();
}
__HAL_LINKDMA(&huart3, hdmatx, hdma_usart3_tx);
// 初始化DMA1_Channel3用于USART3_RX
hdma_usart3_rx.Instance = DMA1_Channel3;
hdma_usart3_rx.Init.Request = DMA_REQUEST_USART3_RX;
hdma_usart3_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_usart3_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart3_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart3_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart3_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart3_rx.Init.Mode = DMA_CIRCULAR;
hdma_usart3_rx.Init.Priority = DMA_PRIORITY_HIGH;
if (HAL_DMA_Init(&hdma_usart3_rx) != HAL_OK) {
Error_Handler();
}
__HAL_LINKDMA(&huart3, hdmarx, hdma_usart3_rx);
}
// GPIO初始化函数
static void MX_GPIO_Init(void) {
__HAL_RCC_GPIOB_CLK_ENABLE();
// 可添加额外的GPIO配置代码
}
测试与验证
[*]将开发板与PC通过USB转UART模块连接。
[*]使用串口调试助手查看数据发送情况,并通过串口发送测试数据。
[*]观察是否正确接收到数据,同时检查DMA是否成功释放CPU资源。
总结本文基于STM32H743实现了DMA与UART的高效协同工作。通过结合DMA的高速传输能力与UART的串口通信功能,我们可以显著降低CPU占用率,为复杂嵌入式应用提供更多资源。如果你有更复杂的通信需求,可以进一步优化DMA与UART的配置,比如使用FIFO模式或设置优先级。
哇,这篇文章让我瞬间明白DMA的优势,真不错! STM32H743性能真的强,这个代码能跑到别的STM32上吗? 大佬讲解的很细,我要赶紧试试这个示例! 我之前直接用HAL库写UART,没用DMA,效率确实差点。 Circular模式用在接收上很有用啊,学到了! 有没有可能支持多个串口同时用DMA传输?求代码! USART3的引脚能不能用其他的引脚复用?好像我用的板子没这个接口。 感觉STM32CubeMX生成代码方便多了,以前手写真的费劲。 如果数据量更大,比如几千字节,DMA还能保持高效吗?
		页: 
[1]