【STM32 CubeMX】串口编程DMA

news2025/1/17 15:42:07

文章目录

  • 前言
  • 一、DMA方式
    • 1.1 DMA是什么
    • 1.2 CubeMX配置DMA
    • 1.3 DMA方式函数使用
      • DMA的发送
      • 接收函数
  • 总结


前言

在嵌入式系统中,串口通信是一项至关重要的功能,它允许单片机与外部设备进行数据交换,如传感器、显示器或其他设备。然而,在高速数据传输的场景下,传统的串口通信方式可能会使CPU过于繁忙,从而影响系统的性能。为了解决这一问题,STM32系列微控制器提供了DMA(直接内存访问)技术,可以在不占用CPU资源的情况下实现高速的数据传输。本文将介绍如何利用STM32 CubeMX配置串口通信并使用DMA进行数据传输。


一、DMA方式

1.1 DMA是什么

想象一下你在单片机中需要把一堆数据从一个地方搬到另一个地方,比如从内存搬到外设(比如串口或者存储器)。传统的方式是由CPU来亲自操持每一个数据的传输,就像你亲自搬运每一件家具一样。

而DMA就像是单片机中的一支专业的搬家队伍。你可以告诉这支队伍从哪里搬到哪里,然后它们就可以自动完成这个任务,而不需要CPU一直牵头指挥。这样,CPU就可以专注于处理其他的事务,而不用为每个数据传输都忙碌起来。

所以,单片机中的DMA就是一种让数据在不需要CPU持续参与的情况下,在内存和外设之间自动传输的技术,使得单片机能更高效地完成一些数据搬运的任务。简而言之,就是让单片机变得更聪明、更省力。

比如下面这个图,如果我们使用普通的发送RAM里面的buf,那么cpu就要一位一位的取buf,放到串口发送寄存器中,那么就非常耗费时间,那么这时DMA就出现了,他可以直接让cpu把RAM里面的buf放到DMA,然后DMA自动把buf放到发送寄存器里,放到寄存器这个过程cpu是不参与的
在这里插入图片描述
他不仅可以发送,还可以把接收的寄存器放到DMA中,然后放到RAM中

1.2 CubeMX配置DMA

在这里插入图片描述
打开我们的串口,选择DMA设置,然后添加一个DMA,其中的DMA Request就是你为了什么而使用DMA,比如为了发送,为了接收都可以设置。

模式的设置:
在这里插入图片描述
模式有两种,一种是Normal,一种是circular
Normal:比如要传输1000字节,传输完了就ok了,不传输了
circular:比如要传输1000字节,传输完了,他会从开头,再传输一次

注意:这里不能打勾在这里插入图片描述
Memory需要打勾

1.3 DMA方式函数使用

DMA的发送

我们可以使用下面这个函数进行发送:

HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size);

他的参数为串口对象,要发送的data,要发送的大小。
比如说,我们可以这样:

HAL_UART_Transmit_DMA(&huart1,(uint8_t *)"Hello DMA",sizeof("Hello DMA"));

那么我们可以在串口里看到打印的数据:
在这里插入图片描述
上面这个函数的中断如下:

__weak void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart)
__weak void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)

当DMA发送完一半时,调用第一个回调函数
当DMA发送完时,调用第二个回调函数

接收函数

我们可以使用下面这个函数进行接收:

HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);

他的参数为串口对象,要接收的buf,要接收的大小。

上面这个函数的中断如下:

__weak void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);
__weak void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart);

对于纯DMA接收是没有意义的,比如你和外设通信,你调用DMA的接收,你还要去指定你要接收多少字节,可是,每次接收的都是不一样的啊,大小根本指定不了,所以DMA接收要和下节课的IDLE中断一起才有意义


总结

通过本文的介绍,我们学习了如何在STM32 CubeMX中配置串口通信并使用DMA进行数据传输。首先,我们利用CubeMX配置了串口通信的基本参数,包括波特率、数据位数和停止位数等。然后,我们配置了DMA通道,将串口接收和发送的数据直接传输到内存,而不需要CPU的干预。这样一来,系统的CPU资源就可以得到释放,提高了系统的性能和效率。最后,我们可以根据具体的应用场景,编写相应的串口通信代码,实现数据的接收和发送功能。通过合理地利用DMA技术,我们可以在嵌入式系统中实现高效可靠的串口通信功能,为各种应用场景提供了更好的支持。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1450126.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于GPT-4一键完成数据分析全流程的AI Agent: Streamline Analyst

大型语言模型(LLM)的兴起不仅为获取知识和解决问题开辟了新的可能性,而且催生了一些新型智能系统,例如旨在辅助用户完成特定任务的AI Copilot以及旨在自动化和自主执行复杂任务的AI Agent,使得编程、创作等任务变得高效…

每日OJ题_递归②_力扣21. 合并两个有序链表

目录 力扣21. 合并两个有序链表 解析代码 力扣21. 合并两个有序链表 21. 合并两个有序链表 难度 简单 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 1: 输入:l1 [1,2,4], l2 [1,3,4]…

Three.js学习9:Three.js 响应式设计

当浏览器窗口尺寸变化的时候,Three.js 渲染的场景,也就是 canvas 不会变化。 让 canvas 随着窗口的尺寸变化,可以利用 window 对象的 resize 事件实现响应式变化。 window.onresize function(){winH window.innerHeight;winW window.inn…

leetcode:343.整数拆分

解题思路: 拆分的越多越好(暂且认为),尽可能拆成m个近似相等的数,会使得乘积最大 dp含义:将i进行拆分得到最大的积为dp[i] 递推公式:j x dp[i-j](固定j,只通过凑dp[i-j]进而实现所…

C++ 动态规划 计数类DP 整数划分

一个正整数 n 可以表示成若干个正整数之和,形如:nn1n2…nk ,其中 n1≥n2≥…≥nk,k≥1 。 我们将这样的一种表示称为正整数 n 的一种划分。 现在给定一个正整数 n ,请你求出 n 共有多少种不同的划分方法。 输入格式 共一行&…

SpringCloud第二天

1.Nacos配置管理 Nacos除了可以做注册中心,同样可以做配置管理来使用。 1.1.统一配置管理 当微服务部署的实例越来越多,达到数十、数百时,逐个修改微服务配置就会让人抓狂,而且很容易出错。我们需要一种统一配置管理方案&#x…

【AIGC】Stable Diffusion之模型微调工具

推荐一款好用的模型微调工具,cybertron furnace 是一个lora训练整合包,提供训练 lora 模型的工具集或环境。集成环境包括必要的依赖项和配置文件、预训练脚本,支持人物、二次元、画风、自定义lora的训练,以简化用户训练 lora 模型…

Linux中sigaction函数和SIGCHLD信号的使用

sigaction函数: 函数说明:注册一个信号处理函数 函数原型:int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact); 函数参数: signum:捕捉的信号act:传入参数,…

【C++笔记】第一阶段:C++基础入门

C基础入门 1 C初识1.1 创建一个C程序1.1.1 创建项目1.1.2 创建文件1.1.3 编写代码1.1.4 运行程序 1.2 注释1.3 变量1.4 常量1.5 关键字1.6 标识符命名规则 2 数据类型2.1 整型2.2 sizeof关键字2.3 实型(浮点型)2.4 字符型2.5 转义字符2.6 字符串型2.7 布…

单源最短路建图方式例题整理

1129. 热浪(活动 - AcWing) 思路:题目只是加了一个背景,但实际上还是很裸的单源最短路问题。我们有四种写法,bellman_ford算法时间复杂度不如spfa,而且这里对边数没有限定,所以没必要使用bellma…

爱上JVM——常见问题:JVM组成(一)

1 JVM组成 1.1 JVM由那些部分组成,运行流程是什么? 难易程度:☆☆☆ 出现频率:☆☆☆☆ JVM是什么 Java Virtual Machine Java程序的运行环境(java二进制字节码的运行环境) 好处: 一次编写&…

【AIGC】Stable Diffusion的模型入门

下载好相关模型文件后,直接放入Stable Diffusion相关目录即可使用,Stable Diffusion 模型就是我们日常所说的大模型,下载后放入**\webui\models\Stable-diffusion**目录,界面上就会展示相应的模型选项,如下图所示。作者…

【JAVA-Day81】 线程休眠: Java 中暂停线程执行的方法 ⏸️

线程休眠: Java 中暂停线程执行的方法 ⏸️💤 线程休眠: Java 中暂停线程执行的方法 ⏸️💤摘要 📝引言 🚀正文 📚一、什么是线程休眠 ⏸️二、线程什么情况下会休眠 ❓三、模拟线程休眠 &#…

jenkins-maven环境的安装

jenkins-maven环境的安装

leetcode 160 相交链表

题目 给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。 图示两个链表在节点 c1 开始相交: 题目数据 保证 整个链式结构中不存在环。 注意,函数返回结…

Gemini 1.5 Pro揭秘:Google DeepMind新一代AI模型如何突破千万级别词汇限制?

Gemini 1.5 Pro 发布! 这款模型凭借其超长的上下文处理能力脱颖而出,支持10M tokens。 它的多模态特性意味着,无论面对多么庞大复杂的内容,Gemini 1.5 Pro都能游刃有余地应对。 在AI的世界里,上下文的理解如同记忆的…

【类与对象(1)】类的引入、访问及封装、定义、作用域、实例化、类大小的计算、this指针

1.类的引入 C兼容了C语言结构体的用法,但是同时又升级成了类。结构体中只能定义变量,类中不仅可以定义变量,还可以定义函数。 例如,数据结构中实现栈,结构体stack中只定义了变量,要实现的函数在结构体外定…

npm使用国内淘宝镜像(最新地址)

目录 前言 一、命令配置 二、使用cnpm安装 三、常见包地址 四、总结 往期回顾 前言 我们前端程序员在使用国外的镜像源速度很慢并且容易下载失败,有时候需要尝试多次才有可能下载成功,很麻烦,但是可以切换为国内镜像源,下…

Node.js开发-express框架

express框架 1) 介绍2) express 路由3) express 响应设置4) express 其他响应5) express中间件6) 静态资源中间件7) 获取请求体数据 body-parser8) Router 路由模块化9) EJS 模板引擎 1) 介绍 express 是一个基于 Node.js 平台的极简、灵活的 WEB 应用开发框架,官方…

MySQL学习记录——팔 函数

文章目录 1、日期函数2、字符串函数3、数学函数4、其它函数 1、日期函数 //获取日期 select current_date(); //获取时间 select current_time(); //获取时间戳, 格式为日期时间 select current_timestamp(); //获取当前时间, 格式为日期时间 select now(); //获取参数的日期部…