STM32基于HAL库使用串口+DMA 不定长接收数据 学习记录

我这些博客都只是记录一下自己学习的内容,以及记录一些思考过的问题和疑惑的东西


这里的代码借鉴了一位博主的博客

地址:[]


这里cubemx串口基础配置部分参考这一篇博客
(只配置了串口中断接收和printf重定向)

这一篇博客我们需要开启串口DMA接收

首先先说说DMA是什么

DMA(Direct Memory Access)直接内存访问,是一种允许硬件子系统在不经过中央处理单元(CPU)的直接控制下,独立于CPU自行访问系统内存的技术。使用DMA,数据可以更高效地在内存和硬件之间传输,大大减轻了CPU的负担。

DMA主要用于处理大量的数据传输。在没有DMA的情况下,数据传输需要CPU介入,CPU必须从源读取数据,然后将其写入到目标位置,这个过程消耗了大量的CPU资源。DMA通过允许外设直接读写内存,使CPU能够在数据传输过程中执行其他任务或进入低功耗模式,从而提高了系统的效率。

为什么要使用串口DMA接收

 

串口通信经常涉及到连续的数据流传输。在没有使用DMA的情况下,CPU需要不断地检查接收缓冲区是否有数据,然后读取数据,或者检查发送缓冲区是否空闲,然后发送数据。这种方式称为轮询(Polling),它会占用大量的CPU资源,尤其是在高速率数据传输或大量数据传输的情况下。

使用DMA进行串口通信时,CPU初始化DMA传输后便可以执行其他任务,直到整批数据传输完成后,DMA控制器会通过中断通知CPU。这样,大大提高了CPU的使用效率,也提高了数据传输的速率。

什么情况下使用DMA更好
 

在以下几种情况下使用DMA进行串口通信通常会更好:

高速数据传输:当有大量数据需要快速传输时,DMA可以节省大量CPU资源。

多任务系统:在需要同时执行多个任务的系统中,使用DMA可以让CPU更好地管理和执行其他任务,提高系统的整体效率。

实时系统:对于需要快速响应的实时系统,使用DMA能够确保数据传输的同时,CPU可以及时处理其他更加紧急的任务。

举个栗子

假设您正在开发一个涉及图像处理的嵌入式系统,该系统需要通过串口接收来自外部相机模块的大量图像数据。如果不使用DMA,CPU需要不断地从串口接收缓冲区读取数据,并将其存储到内存中,这将极大地降低处理图像算法的效率。通过使用DMA,数据直接从串口传输到指定的内存区域,无需CPU参与数据的具体传输过程,CPU就可以专注于处理图像数据,提高了数据处理效率和系统响应速度。


打开cubemx,在之前配置串口中断接收重定向后


然后生成代码
这里我以使用多个串口为例(USART1 和 USART3)

usart.h中
 

/* USER CODE BEGIN Prototypes */#define RX_BUFFER_SIZE 256typedef struct {uint8_t RxBuffer[RX_BUFFER_SIZE];uint8_t RxData;uint16_t RxDataCnt;
}UART_RxTypeDef;extern UART_RxTypeDef Uart1Rx;   // 为UART1声明外部结构体变量
extern UART_RxTypeDef Uart3Rx;   // 为UART3声明外部结构体变量/* USER CODE END Prototypes */

usart.c中
 

/* USER CODE BEGIN 0 */UART_RxTypeDef Uart1Rx = {{0}, 0, 0};  // 为UART1初始化结构体
UART_RxTypeDef Uart3Rx = {{0}, 0, 0};  // 为UART3初始化结构体
// 重定向c库函数printf到huart1
int fputc(int ch, FILE *f) {HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);return ch;
}
int fgetc(FILE *f)
{uint8_t ch = 0;HAL_UART_Receive(&huart1, &ch, 1, 0xffff);return ch;
}
/* USER CODE END 0 */

main.h中
 

/* USER CODE BEGIN Includes */#include <stdio.h>
#include <string.h>#include "usart.h"
/* USER CODE END Includes */

usart.c末尾处
 

/* USER CODE BEGIN 1 */void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{if (huart->Instance == USART1){Uart1Rx.RxDataCnt = RX_BUFFER_SIZE - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);if(Uart1Rx.RxBuffer[Uart1Rx.RxDataCnt - 2] == '\r' && Uart1Rx.RxBuffer[Uart1Rx.RxDataCnt - 1] == '\n'){HAL_UART_Transmit(&huart1, Uart1Rx.RxBuffer, Uart1Rx.RxDataCnt,0xFFFF);}}if (huart->Instance == USART3){Uart3Rx.RxDataCnt = RX_BUFFER_SIZE - __HAL_DMA_GET_COUNTER(&hdma_usart3_rx);if(Uart3Rx.RxBuffer[Uart3Rx.RxDataCnt - 2] == '\r' && Uart3Rx.RxBuffer[Uart3Rx.RxDataCnt - 1] == '\n'){HAL_UART_Transmit(&huart3, Uart3Rx.RxBuffer, Uart3Rx.RxDataCnt,0xFFFF);}}
}/* USER CODE END 1 */

main.c 串口初始化后添加
 

HAL_UARTEx_ReceiveToIdle_DMA(&huart1,Uart1Rx.RxBuffer,RX_BUFFER_SIZE);
HAL_UARTEx_ReceiveToIdle_DMA(&huart3,Uart3Rx.RxBuffer,RX_BUFFER_SIZE);

在stm32f1xx_it.c中 

串口中断函数
usart1
添加
 

  /* USER CODE BEGIN USART1_IRQn 1 */
HAL_UARTEx_ReceiveToIdle_DMA(&huart1,Uart1Rx.RxBuffer,RX_BUFFER_SIZE);/* USER CODE END USART1_IRQn 1 */

usart3

添加

  /* USER CODE BEGIN USART3_IRQn 1 */
HAL_UARTEx_ReceiveToIdle_DMA(&huart3,Uart3Rx.RxBuffer,RX_BUFFER_SIZE);/* USER CODE END USART3_IRQn 1 */

如果还有其他的串口步骤与上面一致添加或者减少

烧录代码后测试成功:


实现接收不定长数据

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

分布式计算架构详解以及任务调度方式

信息技术领域重要分支—分布式计算。分布式计算通过将任务分配到多个物理的计算资源上进行处理&#xff0c;以来提高计算效率和资源利用率。今天主讲分布式计算架构的关键组成以及在云服务器背景下任务调度的不同方式&#xff0c;然后再综合来看这些调度策略是怎样适应云环境的…

C# 三种定时器的用法

目录 1.System.Timers.Timer 2.System.Windows.Forms.Timer 3.System.Threading.Timer 4.简单的封装 这里介绍三种常用的定时器&#xff0c;方便查阅资料或直接复制使用。 1.System.Timers.Timer System.Timers.Timer 类定义了一个计时器&#xff0c;该计时器按固定间隔触…

线性表之数组

数组&#xff08;Array&#xff09;是 C/C 中最基础和重要的数据结构之一&#xff0c;它提供了一种有效存储和访问固定大小元素集合的方式。关于数组的定义和使用相信大家都已经熟练掌握&#xff0c;本文将着重为大家剖析数组的物理结构和逻辑结构。 1. 数组的物理结构 数组的…

大语言模型-GPT3-Language Models are Few-Shot Learners

一、背景信息&#xff1a; GPT3是于2020 年由OpenAI 发布的预训练语言模型。 GPT3在自然语言处理&#xff08;NLP&#xff09;任务中表现出色&#xff0c;可以生成连贯的文本、回答问题、进行对话等。 GPT3的网络架构继续沿用GPT1、GPT2的是多层Transformer Decoder改的结构。…

MySQL的安装配置以及可视化工具的安装

一、MySQL 的安装配置 1、找到官网 MySQL :: Download MySQL Installer (Archived Versions)https://downloads.mysql.com/archives/installer/ 2、下载 3、安装 接下来只需要一直 next 下去就好 此时我们的MySQL就安装完成了&#xff0c;有些人的电脑在点击完这个finish以后…

Linux内核6.12新特性:panic之后扫码显示故障信息

Linux 内核 6.12 版本即将引入一项有趣的功能——在内核Panic时显示一个可选的二维码。这一功能将允许用户通过扫描二维码直接访问内核Panic信息的日志&#xff0c;从而更容易地诊断问题所在。 这不是 Linux 第一次尝试使用二维码。早在2014年&#xff0c;就有过关于在内核Pani…

HarmonyOS(52) 使用安全控件SaveButton保存图片

SaveButton使用简介 前言SaveButton简介约束与限制 实现点击事件全部源码 参考资料&#xff1a; 前言 在HarmonyOS(50) 截图保存功能实现一文中简单介绍了截图保存功能&#xff0c;本篇博文介绍一个更简单的保存图片控件SaveButton. SaveButton简介 SaveButton允许用户通过点…

EasyCVR中的H.265技术:助力实现大规模高效流畅的视频监控应用

随着视频监控技术的不断发展和用户对视频质量要求的不断提高&#xff0c;高效能、低延迟的视频编码技术成为视频监控系统中的重要支撑。TSINGSEE青犀视频旗下的EasyCVR视频汇聚平台凭借其强大的视频处理能力和对H.265技术的支持&#xff0c;在视频监控系统中展现出显著的应用优…

运用Premiere自学视频剪辑,这些岗位你能胜任!

随着短视频的兴起和火热&#xff0c;短视频后期制作越来越受到人们的重视&#xff0c;甚至衍生出很多岗位的高薪工作。如大家所了解的&#xff0c;Adobe premiere正是一款视频后期剪辑和制作工具&#xff0c;其功能强大&#xff0c;应用也十分广泛&#xff0c;是从事后期工作者…

Mysql常见问题汇总【持续更新】

文章目录 Invalid default value for CREATE_TIME 或则 启动时 sql_mode 报错1130错误码&#xff0c;MySQL不能通过ip连接第一种命令方式图形化界面 mysql给用户授管理员权限mysql 新建用户时&#xff0c;主机名选择区别Mysql常用命令大全 Invalid default value for CREATE_T…

四大消息队列:Kafka、ActiveMQ、RabbitMQ、RocketMQ对比

四大消息队列&#xff1a;Kafka、ActiveMQ、RabbitMQ、RocketMQ对比 1. 社区活跃度2. 持久化消息3. 技术实现4. 高并发性能5. RabbitMQ与Kafka对比 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 在软件开发中&#xff0c;消息队列&#xf…

基础算法(1)——双指针

1. 概念 常见的双指针有两种形式&#xff0c;一种是对撞指针&#xff0c;一种是快慢指针 1.1 对撞指针 一般用于顺序结构中&#xff0c;也称为左右指针 对撞指针从两端向中间移动&#xff0c;一个指针从最左端开始&#xff0c;另一个从最右端开始&#xff0c;逐渐往中间逼近…

.net dataexcel winform控件 更新 日志

增加 列宽度调整时动态显示列象素大小 更改列的宽度可以使用 column.Width属性进行修改

【持续更新】Mχ Plaayer Pro 1.86.0安卓知名播放器最新免费高级修改版

Mχ Plaayer Pro MOD 版本免费 APK&#xff0c;专为安卓手机和平板打造。这是一款功能强大的视频播放器&#xff0c;具备先进的硬件加速技术和字幕支持功能。 • 硬件加速 - 新增 HW 解码器帮助更多视频格式实现硬件加速。 • 多核心解码 - Mχ Plaayer 是首款支持多核心解码的…

基于STM32的RFID高速收费系统(论文+源码+实物)

1系统方案设计 本文基于STM32的RFID高速收费系统&#xff0c;其可以实现小车和货车两种车型收费&#xff0c;当车辆超过了规定的重量后&#xff0c;出现声光报警提示&#xff0c;并且启动杆不会抬起&#xff0c;只有当车辆重量低于设置值时&#xff0c;启动杆才会自动抬起&…

【Linux】在 bash shell 环境下,当一命令正在执行时,按下 control-Z 会?

目录 题目分析答案 题目 分析 ctrl-c&#xff1a; 发送 SIGINT 信号给前台进程组中的所有进程。常用于终止正在运行的程序&#xff1b;ctrl-z&#xff1a; 发送 SIGTSTP信号给前台进程组中的所有进程&#xff0c;常用于挂起一个进程&#xff1b;ctrl-d&#xff1a; 不是发送信…

揭秘排行榜系统:如何在高并发场景下实现高效更新!

大家好,我是你们的技术分享伙伴小米!今天我们来聊聊一个非常有趣的话题——如何设计一个排行榜。在这个互联网时代,无论是游戏、学习平台,还是各种社交应用,排行榜都是用户互动和竞争的核心功能之一。而如何设计一个高效、实时更新的排行榜,是一个充满挑战性的问题。今天…

win11,vscode上用docker环境跑项目

1.首先用dockerfile创建docker镜像 以下是dockerfile文件的内容&#xff1a; FROM pytorch/pytorch:1.11.0-cuda11.3-cudnn8-devel LABEL Service"SparseInstanceActivation"ENV TZEurope/Moscow ENV DETECTRON_TAGv0.6 ARG DEBIAN_FRONTENDnoninteractiveRUN apt-…

vim常用快捷键问答

vim的光标位置操作快捷键有哪些&#xff1f;怎样记忆它们&#xff1f; 在 Vim 中&#xff0c;光标位置的操作快捷键非常重要&#xff0c;可以帮助你更高效地编辑文本。下面是一些常用的光标位置操作快捷键&#xff1a; 基本移动 h&#xff1a;光标左移一个字符j&#xff1a;光…

使用安信可Ai-WB2-12F开启wifi与手机通信TCP-IP(AT指令)

当时在做两个单片机之间无线通信&#xff0c;或者单片机与手机无线通信&#xff0c;就像找一个蓝牙和wifi双模的无线模块&#xff0c;一开始看ESP8684&#xff08;ESP32-C2&#xff09;这个芯片模组是有wifi和蓝牙的&#xff0c;买回来后才发现他不可以在程序运行中更换蓝牙或者…