RS485 双串口通信 + LCD 实时显示(DMA版)

目录

  • 一、前言
  • [二、DMA 通信核心原理简述](#二、DMA 通信核心原理简述)
  • [三、CubeMX 的 DMA 串口配置](#三、CubeMX 的 DMA 串口配置)
  • [四、FreeRTOS DMA 收发任务代码开发](#四、FreeRTOS DMA 收发任务代码开发)
  • 五、总结
  • 六、结尾

一、前言

前文我们已经完成了串口 RS485 通信的查询方式中断方式 开发,两种方式各有适配场景。本次笔记将在此基础上,讲解串口通信的第三种实现方案 ------DMA 方式。串口的收发数据始终依靠 TDR 发送寄存器、RDR 接收寄存器完成数据中转,无论数据量多少都需经这两个寄存器经手;而 DMA 相当于独立的「硬件搬运工」,可自主完成寄存器与内存之间的数据搬运,全程无需 CPU 参与,能最大化解放 CPU 资源,是串口大数量、高频次数据传输的最优方案,本次依旧基于 FreeRTOS 多任务完成功能开发,保持功能逻辑不变。

二、DMA 通信核心原理简述

DMA(直接存储器访问)的核心作用,是在外设寄存器内存地址之间建立独立的数据传输通道,无需 CPU 的指令干预,自主完成数据的读写搬运。

对于串口通信而言:发送时,DMA 将内存中的数据搬运至串口 TDR 发送寄存器;接收时,DMA 将串口 RDR 接收寄存器的数据搬运至内存,整个传输过程 CPU 可完全脱离,仅在传输完成 / 异常时触发少量响应逻辑,大幅降低 CPU 的资源占用率。

三、CubeMX 的 DMA 串口配置

CubeMX 中有 DMA 功能的专属配置页面,本次开发沿用之前的串口 2 作为发送端、串口 4 作为接收端,为两路串口分别配置独立的 DMA 通道,其余串口、中断、FreeRTOS 相关配置均与上一篇中断版保持一致,具体 DMA 配置如下:

  1. 配置Channel0 作为串口 2 的 DMA 通道,触发方式选择UART2_TX,数据传输方向为内存到外设,源地址设置为每次递增 1 字节。
  1. 配置Channel1 作为串口 4 的 DMA 通道,触发方式选择UART4_RX,数据传输方向为外设到内存,目的地址设置为每次递增 1 字节。

四、FreeRTOS DMA 收发任务代码开发

DMA 方式的串口开发,在代码层面的逻辑与中断方式几乎完全一致,核心改动仅为将中断收发启动函数替换为 DMA 收发启动函数,依旧沿用此前编写的完成等待函数做传输状态判断与超时控制;当接收出现超时异常时,调用专用函数停止对应串口的 DMA 传输,规避异常占用,完整的任务代码如下:

c 复制代码
// 串口2 DMA发送任务:周期发送自增字节数据
static void CH1_UART2_TxTaskFunction(void *pvParameters)
{
	uint8_t c = 0;
	while(1)
	{
		HAL_UART_Transmit_DMA(&huart2, &c, 1); // 启动串口2 DMA发送1字节
		wait_uart2_tx_cplt(100);                // 等待DMA发送完成,超时100ms
		vTaskDelay(1000);                       // 延时1秒,固定周期发送
		c++;                                    // 发送数据自增
	}
};

// 串口4 DMA接收任务:接收数据并实时显示至LCD
static void CH2_UART4_RxTaskFunction(void *pvParameters)
{
	uint8_t c = 0;
	int cnt = 0;
	char buf[100];
	HAL_StatusTypeDef err;
	while(1)
	{
		err = HAL_UART_Receive_DMA(&huart4, &c, 1); // 启动串口4 DMA接收1字节
		if(wait_uart4_rx_cplt(1000) == 0)           // 等待DMA接收完成,超时1000ms
		{
			// 接收成功,格式化数据并LCD显示
			sprintf(buf, "Recv Data : 0x%02x, Cnt : %d", c, cnt++);
			Draw_String(0, 0, buf, 0x0000ff00, 0);
		}
		else
		{
			HAL_UART_DMAStop(&huart4); // 接收超时,停止串口4的DMA传输
		}
	}
};

由此能清晰看出,串口的 DMA 传输与中断传输,在业务代码的实现逻辑上本质一致,只是底层的硬件数据传输方式不同。

五、总结

  1. 串口通信有查询、中断、DMA 三种实现方式,核心数据中转均依赖 TDR/RDR 寄存器;
  2. DMA 为硬件独立搬运数据,无需 CPU 参与,相比中断更能解放 CPU 资源,传输效率更高;
  3. DMA 版代码逻辑与中断版高度复用,仅替换收发启动函数,开发适配成本低;
  4. DMA 传输需做好超时异常处理,通过停止 DMA 规避硬件资源异常占用;
  5. 三种方式各有优势:查询简单、中断省资源、DMA 效率最优,按需选型即可。

六、结尾

本次完成了串口 RS485 通信三种实现方式的闭环学习,从查询到中断再到 DMA,是逐步优化 CPU 资源利用、提升传输效率的过程,也是嵌入式开发的核心优化思路。三种串口通信方式的开发逻辑可通用至各类外设,是嵌入式必备的基础能力。感谢各位的阅读,持续关注本系列,后续将带来更多项目实战的干货复盘与技术优化!

相关推荐
星期五不见面2 小时前
机器人学习!(二)ROS-基于Gazebo项目-YOLO(3)2026/01/13
人工智能·学习·机器人
im_AMBER2 小时前
Leetcode 103 反转链表 II
数据结构·c++·笔记·学习·算法·leetcode
羊村积极分子懒羊羊2 小时前
2024.11.9下午CSRA笔记
笔记
xiangshi_yan2 小时前
内核学习之路【3/100】-内存管理
学习
崇山峻岭之间2 小时前
Matlab学习记录34
学习
雾岛听风眠2 小时前
STM32HAL库学习笔记
笔记·stm32·学习
知南x2 小时前
【正点原子STM32MP157学习篇】A7和M4联合调试(通过STM32CubeIDE)
stm32·嵌入式硬件·学习
儒雅永缘2 小时前
Solidworks练习37-旋转、拉伸切、阵列
笔记·学习
丝斯20112 小时前
AI学习笔记整理(47)——大模型企业应用技术之提示工程
人工智能·笔记·学习