当前位置: 首页 > news >正文

STM32平台上实现串口接收不定长数据-实际项目中应用

文章目录

  • 一、中断+串口监听方式
  • 初始化
    • 中断处理
    • 串口监听
  • 二、空闲中断方式
  • 三、空闲中断+DMA方式
  • 四、总结

本文将详细介绍在STM32平台上实现串口接收不定长数据的几种方法

一、中断+串口监听方式

这种方式也是我早期使用的方式,直接使用寄存器来操作,这种方式效率低,开销大,还要额外开定时器监听

初始化

temp=(float)(uart_config.pclk1000000)/(uart_config.bound16);//得到USARTDIV
mantissa=temp; //得到整数部分
fraction=(temp-mantissa)*16; //得到小数部分
mantissa<<=4;
mantissa+=fraction;
//初始化IO
Uart_MSP_Init(Uart_Type[uart_config.uart_num]);
//初始化clk
Uart_Clk_Init(Uart_Type[uart_config.uart_num]);
//波特率设置
Uart_Type[uart_config.uart_num]->BRR=mantissa; // 波特率设置
Uart_Type[uart_config.uart_num]->CR1|=0X200C; //1位停止,无校验位.

中断处理

有数据就缓存到数组里
void USART3_IRQHandler(void)
{
uint8_t res;
if(USART3->SR&(1<<5)) //接收到数据
{
uart_lock[uart3] = 1;
res=USART3->DR;
if(Uart_RX_Data[uart3].RX_CNT<sizeof(Uart_RX_Data[uart3].RX_BUF))
{
Uart_RX_Data[uart3].RX_BUF[Uart_RX_Data[uart3].RX_CNT] = res;//缓存数据
Uart_RX_Data[uart3].RX_CNT++;//字节
}
}
}

串口监听

主要作用是监听中断是否有数据更新,超过Nms认为没有数据更新,认为这是一帧数据,Uart3RxMonitor程序需要跑在1ms更新定时器中
static void Uart3RxMonitor(uint8_t ms) //串口接收监控
{
if(uart_callback_handler[uart3] != NULL)
{
if(Uart_RX_Data[uart3].RX_CNT>0)//接收计数器大于零时,监控总线空闲时间
{
if(Uart_RX_Data[uart3].RX_BKP!=Uart_RX_Data[uart3].RX_CNT) //接收计数器改变,即刚接收到数据时,清零空闲计时
{
//uart_lock[uart3] = 1;
Uart_RX_Data[uart3].RX_BKP=Uart_RX_Data[uart3].RX_CNT; //赋值操作,将实际长度给USART1_RX_BKP
Uart_RX_Data[uart3].idletmr=0; //将监控时间清零
}
else 接收计数器未改变,即总线空闲时,累计空闲时间
{
//如果在一帧数据完成之前有超过2个字节时间的停顿,接收设备将刷新当前的消息并假定下一个字节是一个新的数据帧的开始
if(Uart_RX_Data[uart3].idletmr<2) //空闲时间小于1ms时,持续累加
{
Uart_RX_Data[uart3].idletmr +=ms;
if(Uart_RX_Data[uart3].idletmr>=2) //空闲时间达到1ms时,即判定为1帧接收完毕
{
len[uart3] = UartRead(uart3,buf[uart3],sizeof(buf[uart3]));
Uart_Buf_Def u_data;
u_data.data= buf[uart3];
u_data.len = len[uart3];
uart_callback_handleruart3;//得到一帧数据
uart_lock[uart3] = 0;
}
}
}
}
else
{
Uart_RX_Data[uart3].RX_BKP=0;
}
}
}

二、空闲中断方式

// USART1 中断服务程序 void USART1_IRQHandler(void) {
HAL_UART_IRQHandler(&huart1);
if (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_RXNE) != RESET)
{
// 处理接收中断
uint8_t res;
HAL_UART_Receive(&huart1, &res, 1, 1000);
// 将接收到的数据添加到缓冲区,
Uart_RX_Data[uart1].RX_BUF[Uart_RX_Data[uart1].RX_CNT] = res;//缓存数据
Uart_RX_Data[uart1].RX_CNT++;//字节
}
if (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE) != RESET)
{
// 处理空闲中断
// 表示一帧数据接收完成,可以处理缓冲区中的数据
// 清除空闲中断标志位
__HAL_UART_CLEAR_IDLEFLAG(&huart1);
// 处理接收到的数据,例如发送出去或进行其他处理
}
}

三、空闲中断+DMA方式

目前主要使用的是这种方式,这种方式的好处是高效,不会频繁进入 RXNE中断进行缓存减小CPU开销,DMA回自动把数据搬运到你指定的缓存区,整个数据帧传送完毕后才会产生一个idle中断
void USART1_IRQHandler(void)
{
uint32_t temp;
if((__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE)) != RESET)//获取IDLE标志位,检查idle标志是否被置位
{
__HAL_UART_CLEAR_IDLEFLAG(&huart1);//清除标志位
HAL_UART_DMAStop(&huart1); //
temp = __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);// 获取DMA中未传输的数据个数
temp = Usart1ReceiveLEN - temp; //总计数减去未传输的数据个数,得到已经接收的数据个数

uart_callback_handleruart1;//一帧数据获取完成去做其他处理
HAL_UART_Receive_DMA(&huart1,Usart1_RX_Buffer,Usart1ReceiveLEN);//打开DMA接收,数据存入rx_buffer数组中。(数组重新复位)
}

四、总结

在STM32平台上实现串口接收不定长数据,可以通过不使用DMA的方式和使用DMA的方式来实现。不使用DMA的方式依赖于中断和缓冲区处理,适用于数据量不大或实时性要求不高的场景。而使用DMA的方式可以显著提高数据传输的效率,减少CPU的干预,适用于大数据量传输或需要高效率数据处理的场景。 在实际应用中,可以根据具体的需求和场景选择合适的实现方式。无论采用哪种方式,都需要对串口通信的原理和STM32的HAL库有深入的理解,才能编写出高效、稳定的代码。

相关文章:

STM32平台上实现串口接收不定长数据-实际项目中应用

文章目录 一、中断串口监听方式初始化中断处理串口监听 二、空闲中断方式三、空闲中断DMA方式四、总结 本文将详细介绍在STM32平台上实现串口接收不定长数据的几种方法 一、中断串口监听方式 这种方式也是我早期使用的方式&#xff0c;直接使用寄存器来操作&#xff0c;这种方…...

AWD入门

一、简介 AWD(Attack With Defense&#xff0c;攻防兼备)模式。你需要在一场比赛里要扮演攻击方和防守方&#xff0c;攻者得分&#xff0c;失守者会被扣分。也就是说攻击别人的靶机可以获取 Flag 分数时&#xff0c;别人会被扣分&#xff0c;同时你也要保护自己的主机不被别人…...

T3矩阵看功率

每个像素的T3矩阵&#xff0c;功率等于特征值的和。 不同的像素的T3矩阵相加&#xff0c;可不能用特征分解的相加&#xff0c;因为两个T矩阵的特征向量不同...

VLMEvalKit多模态大模型评测工具源码解析

vlmeval/api和vlmeval/vlm文件夹下分别是api接口和本地运行的大模型的代码 基类都是base vlmeval/dataset是数据集处理代码 vlmeval/inference.py是推理代码 run.py的整个流程 1 vlmeval/api/base.py 主要为需要与外部API交互的系统提供了一个通用的框架 类属性 allowed_type…...

将 Docker 安装到指定目录

将 Docker 安装到指定目录 将 Docker 安装到指定目录 Docker 默认安装在 C:\Program Files\Docker\Docker&#xff0c;这可能会占用大量 C 盘空间。你可以按以下步骤将 Docker 安装到其他盘&#xff08;例如 E 盘&#xff09;&#xff1a; 创建安装目录&#xff1a;在 E 盘创…...

哪些企业需要部署SD-WAN?

首先&#xff0c;让我们先明确SD-WAN的定义。SD-WAN&#xff0c;中文全称为软件定义广域网&#xff08;Software-Defined Wide Area Network&#xff09;&#xff0c;通过集中化管理与流量控制&#xff0c;帮助企业优化网络性能&#xff0c;提升用户体验。与传统广域网&#xf…...

通信基站类型、频段与网络标准

【1】通信基站类型 移动通信基站根据覆盖面积和功率大小主要可以分为以下几种类型&#xff1a; 宏基站&#xff08;宏站&#xff09;&#xff1a;这是最常见的基站类型&#xff0c;具有较大的发射功率和较广的覆盖范围&#xff0c;通常覆盖半径从1到25公里不等。宏基站主要用于…...

Java IO教程之Java 文件一口气讲完!( *︾▽︾)

Java 文件 Java IO教程 - Java文件 File类的对象是文件或目录的路径名的抽象表示。 创建文件 我们可以从中创建一个 File 对象 路径名父路径名和子路径名URI&#xff08;统一资源标识符&#xff09; 我们可以使用File类的以下构造函数之一创建一个文件&#xff1a; File(…...

如何在 Ubuntu 24 上安装 Vmware Tools

原文 Vmware Tools作用 增强图形显示性能 分辨率适配 可使虚拟机的分辨率能够自动适应窗口大小的变化。当您调整 VMware 软件窗口的大小时&#xff0c;Ubuntu 24 虚拟机的屏幕分辨率会随之自动调整&#xff0c;为用户提供更好的视觉体验&#xff0c;方便在不同的使用场景下进…...

内网穿透:如何借助Cloudflare连接没有公网的电脑的远程桌面(RDP)

内网穿透&#xff1a;如何借助Cloudflare连接没有公网的电脑的远程桌面(RDP)-含详细原理配置说明介绍 前言 远程桌面协议(RDP, Remote Desktop Protocol)可用于远程桌面连接&#xff0c;Windows系统&#xff08;家庭版除外&#xff09;也是支持这种协议的&#xff0c;无需安装…...

明星作家都在使用的电子书制作工具,现在向大家介绍

​在数字化时代&#xff0c;电子书已经成为了广大读者和作家的新宠。越来越多的作家开始尝试将手中的文字作品转化为电子书&#xff0c;以便在更广泛的平台上推广和传播。那么&#xff0c;如何高效、便捷地制作电子书呢&#xff1f;今天&#xff0c;我们就来为大家揭秘一款明星…...

简单认识Maven 3-认识pop.Xml配置文件中的代码

pom.xml是 Maven 项目的核心配置文件&#xff0c;它包含了项目的各种配置信息&#xff0c;以下是对其主要内容含义的认识&#xff1a; 一、项目基本信息 <groupId>&#xff1a; 定义项目的组织或团体的唯一标识符&#xff0c;通常采用反向域名的格式。例如&#xff0c;“…...

LangChain4j系列—OpenAI开发实例

一、引入Maven依赖 1、纯Java <dependency><groupId>dev.langchain4j</groupId><artifactId>langchain4j-open-ai</artifactId><version>0.35.0</version> </dependency> 2、Spring boot <dependency><groupId&g…...

Java 中简化操作集合的方法

在日常 Java 开发中&#xff0c;我们经常需要操作集合&#xff0c;如 List、Set 和 Map。虽然 Java 提供了丰富的集合框架供开发者使用&#xff0c;但在实际编写业务逻辑时&#xff0c;如何简化集合操作、提高代码可读性和效率&#xff0c;依然是一个经常遇到的问题。特别是随着…...

ArcGIS Pro SDK (十七)宗地结构

ArcGIS Pro SDK (十七)宗地结构 环境:Visual Studio 2022 + .NET6 + ArcGIS Pro SDK 3.0 宗地结构 1 获取活动记录 string errorMessage = await QueuedTask.Run(() => {...

D. Co-growing Sequence

传送门&#xff1a;Problem - 1547D - Codeforces 题意&#xff1a;给定一个 数组 a , 构造一个数组 b &#xff0c;使得 ( a[i] ^ b[i] ) & ( a[i 1] ^ b[ i 1] ) a[i] ^ b[i] 思路&#xff1a;&#xff08;二进制题目&#xff09; 设 a[i] ^ b[i] t 我们要让…...

docker配置加速器

阿里云 控制台》容器镜像服务》镜像工具》镜像加速器 复制地址&#xff1a;https://ywtoq7bz.mirror.aliyuncs.com 到&#xff1a;etc/docker下&#xff1a;vi daemon.json 格式&#xff1a; { "registry-mirrors": ["加速器地址"] } 注&#xff1…...

JS事件和DOM

1. DOM 1.1 基本概念 DOM&#xff0c;全称 Document Object Model&#xff0c;即文档对象模型。它是 Web 上最常用的 API 之一&#xff0c;是加载在浏览器中的文档模型&#xff0c;可以将文档表示为节点树&#xff08;或称 DOM 树&#xff09;&#xff0c;其中每个节点代表文…...

CAS 详解

目录 Java 中 CAS 是如何实现的? CAS 算法存在哪些问题? ABA 问题 循环时间长开销大 只能保证一个共享变量的原子操作 Java 中 CAS 是如何实现的? 在 Java 中&#xff0c;实现 CAS&#xff08;Compare-And-Swap, 比较并交换&#xff09;操作的一个关键类是Unsafe。 Un…...

AI大模型那么火,教你一键Modelarts玩转开源LlaMA(羊驼)大模型

近日&#xff0c; LlaMA(羊驼) 这个大模型再次冲上热搜&#xff01; LLaMA&#xff08;Large Language Model Meta AI&#xff09;&#xff0c;由 Meta AI 发布的一个开放且高效的大型基础语言模型&#xff0c;共有 7B、13B、33B、65B&#xff08;650 亿&#xff09;四种版本。…...

后进先出(LIFO)详解

LIFO 是 Last In, First Out 的缩写&#xff0c;中文译为后进先出。这是一种数据结构的工作原则&#xff0c;类似于一摞盘子或一叠书本&#xff1a; 最后放进去的元素最先出来 -想象往筒状容器里放盘子&#xff1a; &#xff08;1&#xff09;你放进的最后一个盘子&#xff08…...

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…...

Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)

目录 1.TCP的连接管理机制&#xff08;1&#xff09;三次握手①握手过程②对握手过程的理解 &#xff08;2&#xff09;四次挥手&#xff08;3&#xff09;握手和挥手的触发&#xff08;4&#xff09;状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...

家政维修平台实战20:权限设计

目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系&#xff0c;主要是分成几个表&#xff0c;用户表我们是记录用户的基础信息&#xff0c;包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题&#xff0c;不同的角色&#xf…...

最新SpringBoot+SpringCloud+Nacos微服务框架分享

文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的&#xff0c;根据Excel列的需求预估的工时直接打骨折&#xff0c;不要问我为什么&#xff0c;主要…...

JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作

一、上下文切换 即使单核CPU也可以进行多线程执行代码&#xff0c;CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短&#xff0c;所以CPU会不断地切换线程执行&#xff0c;从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...

智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制

在数字化浪潮席卷全球的今天&#xff0c;数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具&#xff0c;在大规模数据获取中发挥着关键作用。然而&#xff0c;传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时&#xff0c;常出现数据质…...

基于TurtleBot3在Gazebo地图实现机器人远程控制

1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...

前端工具库lodash与lodash-es区别详解

lodash 和 lodash-es 是同一工具库的两个不同版本&#xff0c;核心功能完全一致&#xff0c;主要区别在于模块化格式和优化方式&#xff0c;适合不同的开发环境。以下是详细对比&#xff1a; 1. 模块化格式 lodash 使用 CommonJS 模块格式&#xff08;require/module.exports&a…...

工厂方法模式和抽象工厂方法模式的battle

1.案例直接上手 在这个案例里面&#xff0c;我们会实现这个普通的工厂方法&#xff0c;并且对比这个普通工厂方法和我们直接创建对象的差别在哪里&#xff0c;为什么需要一个工厂&#xff1a; 下面的这个是我们的这个案例里面涉及到的接口和对应的实现类&#xff1a; 两个发…...