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[100];
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模式或设置优先级。
|