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