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库的使用提高了代码的可读性和兼容性。
|