STM32F446RE是一款高性能的Cortex-M4核心微控制器,具有丰富的外设资源和较高的运行频率。在嵌入式开发中,UART通信是一个非常常见的需求,而DMA的引入可以显著提高数据传输的效率和性能。本文将介绍如何在STM32F446RE上结合UART和DMA,实现一个高效的数据收发机制。
项目需求- 使用UART接口发送和接收数据,通过DMA实现无CPU干预的数据传输。
- 设定固定的数据缓冲区大小,用于存储接收到的数据。
- 实现数据接收回调函数,在接收完成后触发处理逻辑。
- 在主循环中模拟数据发送。
硬件环境- MCU型号:STM32F446RE
- 开发工具:STM32CubeIDE
- 外设配置:USART2与DMA通道结合使用。
代码实现以下是完整代码:
#include "main.h"
#include <string.h>
/* UART句柄和DMA缓冲区 */
UART_HandleTypeDef huart2;
DMA_HandleTypeDef hdma_usart2_rx;
uint8_t rx_buffer[64]; // 接收缓冲区
uint8_t tx_buffer[] = "Hello from STM32F446RE via UART DMA!\r\n";
/* UART初始化函数 */
void MX_USART2_UART_Init(void) {
huart2.Instance = USART2;
huart2.Init.BaudRate = 115200;
huart2.Init.WordLength = UART_WORDLENGTH_8B;
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Parity = UART_PARITY_NONE;
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart2) != HAL_OK) {
Error_Handler();
}
}
/* DMA初始化函数 */
void MX_DMA_Init(void) {
__HAL_RCC_DMA1_CLK_ENABLE();
/* 配置DMA RX通道 */
hdma_usart2_rx.Instance = DMA1_Stream5;
hdma_usart2_rx.Init.Channel = DMA_CHANNEL_4;
hdma_usart2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_usart2_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart2_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart2_rx.Init.Mode = DMA_CIRCULAR;
hdma_usart2_rx.Init.Priority = DMA_PRIORITY_LOW;
hdma_usart2_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma_usart2_rx) != HAL_OK) {
Error_Handler();
}
/* 将DMA与UART关联 */
__HAL_LINKDMA(&huart2, hdmarx, hdma_usart2_rx);
}
/* 主函数 */
int main(void) {
HAL_Init();
SystemClock_Config();
MX_DMA_Init();
MX_USART2_UART_Init();
/* 启动DMA接收 */
HAL_UART_Receive_DMA(&huart2, rx_buffer, sizeof(rx_buffer));
while (1) {
/* 模拟周期性发送数据 */
HAL_UART_Transmit(&huart2, tx_buffer, strlen((char *)tx_buffer), HAL_MAX_DELAY);
HAL_Delay(1000);
}
}
/* 接收完成回调函数 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
if (huart->Instance == USART2) {
/* 数据处理逻辑:这里简单打印接收到的数据 */
HAL_UART_Transmit(&huart2, rx_buffer, sizeof(rx_buffer), HAL_MAX_DELAY);
}
}
/* 错误处理函数 */
void Error_Handler(void) {
while (1) {
// 错误循环
}
}
代码说明- UART初始化:USART2配置为115200波特率,无校验位,使用全双工模式。
- DMA初始化:DMA通道与UART接收器关联,配置为循环模式,用于持续接收数据。
- 回调函数:当接收到数据时触发HAL_UART_RxCpltCallback回调函数,模拟数据的回显逻辑。
- 数据发送:主循环中定时发送字符串,以验证UART发送功能。
项目特点- 使用DMA减少了CPU的负载,使得数据传输更加高效。
- 循环模式使UART接收端能够持续处理数据,无需频繁重新配置。
- HAL库的使用提高了代码的可读性和兼容性。
|