news 2026/6/9 22:12:48

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
RS485 双串口通信 + LCD 实时显示(DMA版)

目录

  • 一、前言
  • 二、DMA 通信核心原理简述
  • 三、CubeMX 的 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 传输,规避异常占用,完整的任务代码如下:

// 串口2 DMA发送任务:周期发送自增字节数据staticvoidCH1_UART2_TxTaskFunction(void*pvParameters){uint8_tc=0;while(1){HAL_UART_Transmit_DMA(&huart2,&c,1);// 启动串口2 DMA发送1字节wait_uart2_tx_cplt(100);// 等待DMA发送完成,超时100msvTaskDelay(1000);// 延时1秒,固定周期发送c++;// 发送数据自增}};// 串口4 DMA接收任务:接收数据并实时显示至LCDstaticvoidCH2_UART4_RxTaskFunction(void*pvParameters){uint8_tc=0;intcnt=0;charbuf[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 资源利用、提升传输效率的过程,也是嵌入式开发的核心优化思路。三种串口通信方式的开发逻辑可通用至各类外设,是嵌入式必备的基础能力。感谢各位的阅读,持续关注本系列,后续将带来更多项目实战的干货复盘与技术优化!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/5 9:20:18

Salesforce推出全新升级版Slackbot智能体

Salesforce公司今日正式发布了其大幅增强版的Slackbot人工智能助手,该助手内置于Slack平台中。该公司在去年10月举办的Dreamforce 2025大会上首次展示了这一升级版本。原版Slackbot主要专注于显示通知等相对简单的任务。新版本大幅扩展了该工具可以自动化的使用场景…

作者头像 李华
网站建设 2026/6/4 20:19:48

AI大模型30个核心术语详解,从小白到入门

文章按照AI产品的四层架构(基座层、模型层、应用层、用户层)详细解释了30个AI领域的重要术语。基座层涵盖算法、算力、数据相关概念;模型层介绍AI核心能力载体;应用层展示AI落地场景;用户层关注AI与用户交互。这些术语…

作者头像 李华
网站建设 2026/6/8 22:43:11

vrrp实例script和 real_server中的HTTP_GET健康检查区别,使用场景总结

Keepalived核心健康检查:VRRP Script & HTTP_GET 在Keepalived高可用集群部署中,健康检查是保障服务连续性的核心机制。其中VRRP实例的script脚本检查与real_server的HTTP_GET检查是最常用的两种方式。 一、核心差异:从检测对象到作用机制…

作者头像 李华
网站建设 2026/6/5 19:43:42

Vue3:泛型类型声明 vs 运行时选项声明 语法对比

Vue 3 提供了两种 props 声明方式&#xff1a;泛型类型声明和运行时选项声明。泛型类型声明&#xff08;defineProps<{prop:Type}>()&#xff09;在编译时进行类型检查&#xff0c;完全支持 TypeScript&#xff0c;适合新项目和追求类型安全的场景。运行时选项声明&#…

作者头像 李华