[STM32 HAL库]串口中断编程思路
一、前言
最近在准备蓝桥杯比赛(嵌入式赛道),研究了以下串口空闲中断+DMA接收不定长的数据,感觉这个方法的接收效率很高,十分好用。方法配置都成功了,但是有一个点需要进行考虑,就是一般我们需要对串口接收的数据进行处理,这个数据处理是在中断的回调函数里面处理还是在主函数里面处理好呢?以下就这两个方法进行分析:
二、方法分析
目前我想到的有两种方法:
方法一
在回调函数里直接处理数据
优点:
- 实时性强:数据接收完成后立即处理,减少了数据处理的延迟。
- 代码简洁:数据接收和处理逻辑在同一个地方,代码易于理解和维护。
缺点:
- 占用中断处理时间:如果数据处理逻辑复杂或耗时,会影响中断的响应速度,进而影响系统其他功能的实时性。
- 可维护性差:如果数据处理逻辑复杂,中断处理函数会变得冗长,难以维护。
方法二
在回调函数中设置标志位,在主函数里读取标志位再进行数据处理
优点:
- 保护中断响应速度:中断处理函数只负责设置标志位,数据处理在主循环中进行,保证了中断的响应速度。
- 代码结构清晰:中断处理函数和数据处理逻辑分离,代码结构更清晰,易于维护和扩展。
- 资源利用率高:可以在主循环中根据系统状态灵活调度数据处理,避免在中断中处理复杂逻辑造成的资源浪费。
缺点:
- 增加了一定的复杂性:需要额外管理标志位,以及同步数据接收和处理的逻辑。
- 可能引入延迟:数据处理被推迟到主循环中进行,可能会引入一定的处理延迟。
总结
- 数据处理的复杂度:如果数据处理逻辑复杂或耗时,建议采用方法二,以保护中断响应速度。
- 系统的实时性要求:如果系统对实时性要求较高,且数据处理不是非常耗时,方法一可能更合适。但如果数据处理可能影响到系统的其他实时功能,方法二则更为稳妥。
- 代码的可维护性和扩展性:如果希望代码结构更清晰,易于维护和扩展,方法二通常是更好的选择。
三、实际操作
配置的方法可以看之前写的文章
链接: [STM32 HAL库]串口空闲中断+DMA接收不定长数据
实验现象:将电脑发来的数据,原封不到的发送回去。特别注意
BUFF_SIZE的大小,太小会造成接收数据的丢失。
方法一
在这个方法中,在中断的回调函数里直接发送回去数据,并手动开启下一次的中断。
#define BUFF_SIZE 128
uint8_t rx_buffer[BUFF_SIZE]; // 创建接收缓存,大小为BUF_SIZE
int main(void)
{HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_DMA_Init();MX_USART1_UART_Init();HAL_UARTEx_ReceiveToIdle_DMA(&huart1,rx_buffer,BUFF_SIZE);//手动开启串口DMA模式接收数据__HAL_DMA_DISABLE_IT(&hdma_usart1_rx, DMA_IT_HT); //手动关闭DMA_IT_HT中断 while (1){}
}
void SystemClock_Config(void)
{//...
}
/* 串口接收完成回调函数 */
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{if (huart->Instance == USART1){HAL_UART_Transmit(&huart1, rx_buffer, Size, 0xffff);// 将接收到的数据再发出HAL_UARTEx_ReceiveToIdle_DMA(&huart1, rx_buffer, BUFF_SIZE); // 接收完毕后重启串口DMA模式接收数据__HAL_DMA_DISABLE_IT(&hdma_usart1_rx, DMA_IT_HT);// 手动关闭DMA_IT_HT中断memset(rx_buffer, 0, BUFF_SIZE);// 清除接收缓存 }
}
/* 串口错误回调函数 */
void HAL_UART_ErrorCallback(UART_HandleTypeDef * huart)
{if(huart->Instance == USART1){HAL_UARTEx_ReceiveToIdle_DMA(&huart1, rx_buffer, BUFF_SIZE); // 接收完毕后重启串口DMA模式接收数据__HAL_DMA_DISABLE_IT(&hdma_usart1_rx, DMA_IT_HT);// 手动关闭DMA_IT_HT中断memset(rx_buffer, 0, BUFF_SIZE);// 清除接收缓存}
}
方法二
在这个方法中,在串口接收完成的回调函数置接收完成的标志位,然后在主函数中进行判断。判断成立则进行数据的发送,并手动开启下一次的中断和清除标志位。
需要注意的是,不要在
回调函数里面手动开启下一次的中断,因为有可能会出现主函数数据还未处理完成,下一个串口数据就到来而覆盖上一次的串口数据。
所以,这里程序的处理方法是:程序处理完本次数据,则开启下一次中断接收;程序未处理完本次数据,则不开启下一次中断接收。
#define BUFF_SIZE 128
uint8_t rx_buffer[BUFF_SIZE]; // 创建接收缓存,大小为BUF_SIZE
_Bool u1_rx_end_flag = 0; //USART1接收数据完成标志位 1:接收完成
uint16_t u1_rx_size; //USART1接收数据实际长度
int main(void)
{HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_DMA_Init();MX_USART1_UART_Init();HAL_UARTEx_ReceiveToIdle_DMA(&huart1,rx_buffer,BUFF_SIZE);//手动开启串口DMA模式接收数据__HAL_DMA_DISABLE_IT(&hdma_usart1_rx, DMA_IT_HT); //手动关闭DMA_IT_HT中断 while (1){/* 判断接收是否完成 */if(u1_rx_end_flag == 1){/* 对接收的数据进行处理 */HAL_UART_Transmit(&huart1, rx_buffer, u1_rx_size, 0xffff);// 将接收到的数据再发出memset(rx_buffer, 0, BUFF_SIZE); // 清除接收缓存/* 开启下一次中断 */HAL_UARTEx_ReceiveToIdle_DMA(&huart1,rx_buffer,BUFF_SIZE);//手动开启串口DMA模式接收数据__HAL_DMA_DISABLE_IT(&hdma_usart1_rx, DMA_IT_HT);//手动关闭DMA_IT_HT中断 /* 清除标志位 */u1_rx_end_flag = 0;}}
void SystemClock_Config(void)
{//...
}
/* 串口接收完成回调函数 */
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{if (huart->Instance == USART1){u1_rx_end_flag = 1; //置标志位u1_rx_size = Size; //获取接收数据长度}
}
/* 串口错误回调函数 */
void HAL_UART_ErrorCallback(UART_HandleTypeDef * huart)
{if(huart->Instance == USART1){HAL_UARTEx_ReceiveToIdle_DMA(&huart1, rx_buffer, BUFF_SIZE);//手动开启串口DMA模式接收数据__HAL_DMA_DISABLE_IT(&hdma_usart1_rx, DMA_IT_HT);// 手动关闭DMA_IT_HT中断memset(rx_buffer, 0, BUFF_SIZE);// 清除接收缓存}
}
值得一提的是,若是没有手动开启
串口空闲中断,那么串口错误中断也不会被开启,也就无法进入串口错误回调函数。
四、实验现象
两个方法实现现象一致

应该还有更好的串口接收模式,现在来说,这个方法应该够用了。
相关文章:
[STM32 HAL库]串口中断编程思路
一、前言 最近在准备蓝桥杯比赛(嵌入式赛道),研究了以下串口空闲中断DMA接收不定长的数据,感觉这个方法的接收效率很高,十分好用。方法配置都成功了,但是有一个点需要进行考虑,就是一般我们需要…...
C++入门 详细版
欢迎来到干货小仓库!! 一分耕耘一分收获,离自己的目标越来越近。 passion!passion!!passion!!! 1.命名空间 由于C语言无法避免名字或者函数重复等问题,当有多…...
MIAOYUN信创云原生项目亮相西部“中试”生态对接活动
近日,以“构建‘中试’生态,赋能科技成果转化”为主题的“科创天府智汇蓉城”西部“中试”生态对接活动在成都高新区菁蓉汇隆重开幕。活动分为成果展览、“中试”生态主场以及成果路演洽谈对接三大板块。在成果展览环节,成都元来云志科技有限…...
网络编程 | UDP组播通信
1、什么是组播 在上一篇博客中,对UDP的广播通信进行了由浅入深的总结梳理,本文继续对UDP的知识体系进行探讨,旨在将UDP的组播通信由浅入深的讲解清楚。 组播是介于单播与广播之间,在一个局域网内,将某些主机添加到组中…...
T-SQL语言的语法
T-SQL深度解析与应用 T-SQL(Transact-SQL)是微软SQL Server使用的一种扩展SQL(结构化查询语言)。它不仅支持标准SQL的所有功能,而且增加了许多实用的扩展和特性,使得数据库的操作更加灵活和强大。本文将对…...
Java开发提效秘籍:巧用Apache Commons IO工具库
一、引言 在 Java 开发的广袤领域中,输入输出(I/O)操作宛如一座桥梁,连接着程序与外部世界,从文件的读取与写入,到网络数据的传输,I/O 操作无处不在,其重要性不言而喻。然而…...
第1章:Python TDD基础与乘法功能测试
写在前面 这本书是我们老板推荐过的,我在《价值心法》的推荐书单里也看到了它。用了一段时间 Cursor 软件后,我突然思考,对于测试开发工程师来说,什么才更有价值呢?如何让 AI 工具更好地辅助自己写代码,或许…...
web前端1--基础
(时隔数月我又来写笔记啦~) 1、下载vscode 1、官网下载:Visual Studio Code - Code Editing. Redefined 2、步骤: 1、点击同意 一直下一步 勾一个创建桌面快捷方式 在一直下一步 2、在桌面新建文件夹 拖到vscode图标上 打开v…...
.Net Core微服务入门全纪录(五)——Ocelot-API网关(下)
系列文章目录 1、.Net Core微服务入门系列(一)——项目搭建 2、.Net Core微服务入门全纪录(二)——Consul-服务注册与发现(上) 3、.Net Core微服务入门全纪录(三)——Consul-服务注…...
2024嵌入式系统的未来发展与技术洞察分享
时间如白驹过隙,不知不觉又是一年,这一年收获满满。接下来,将本年度对技术的感悟和洞察分析如下,希望对大家有所帮助。 在过去几十年里,嵌入式系统技术迅速发展,成为现代电子设备和智能硬件的核心组成部分。…...
python-44-嵌入式数据库SQLite和DuckDB
文章目录 1 SQLite1.1 世界上最流行的数据库1.1 SQLite简介1.2 插入语句1.3 查询数据1.4 更新数据1.5 删除数据2 DuckDB2.1 DuckDB简介2.2 DuckDB与Python结合使用2.2.1 创建表2.2.2 分析语句2.2.3 导出为parquet文件2.3 Windows中使用DuckDB3 参考附录1 SQLite Python的一个特…...
1.2.神经网络基础
目录 1.2.神经网络基础 1.2.1.Logistic回归 1.2.2 梯度下降算法 1.2.3 导数 1.2.4 向量化编程 1.2.5 正向传播与反向传播 1.2.6.练习 1.2.神经网络基础 1.2.1.Logistic回归 1.2.1.1.Logistic回归 逻辑回归是一个主要用于二分分类类的算法。那么逻辑回归是给定一个x ,…...
算法题目总结-双指针
文章目录 1.滑动窗口类型1.长度最小的子数组1.答案2.思路 2.无重复字符的最长子串1.答案2.思路 2.双指针类型1.盛最多水的容器1.答案2.思路 2.三数之和1.答案2.思路 1.滑动窗口类型 1.长度最小的子数组 1.答案 package com.sunxiansheng.arithmetic.day10;/*** Description:…...
人形机器人将制造iPhone!
前言 优必选机器人和富士康通过一项突破性的合作伙伴关系,正在将先进的人形机器人(如Walker S1及其升级版Walker S2)整合到制造流程中,以改变iPhone的生产方式。这一合作旨在通过提升机器人能力、优化工作流程以及实现更智能的自动…...
redis 各个模式的安装
一、Redis单机安装 1、安装gcc依赖 Redis是C语言编写的,编译需要GCC。 Redis6.x.x版本支持了多线程,需要gcc的版本大于4.9,但是CentOS7的默认版本是4.8.5。 升级gcc版本: yum -y install centos-release-scl yum -y install d…...
《王者荣耀》皮肤爬虫源码
1.爬取网页 https://pvp.qq.com/web201605/herolist.shtml 2.python代码 import requests from bs4 import BeautifulSoup import os import threading from queue import Queuedef mul(x):if not os.path.exists(x):os.mkdir(x)print("目录创建成功")else:pass h…...
学习ASP.NET Core的身份认证(基于JwtBearer的身份认证8)
为进一步测试通过请求头传递token进行身份验证,在main.htm中增加layui的数据表格组件,并调用后台服务分页显示数据,后台分页查询数据接口如下所示(测试时,直接将数据写死到代码中,没有查询数据库࿰…...
PyTorch使用教程(6)一文讲清楚torch.nn和torch.nn.functional的区别
torch.nn 和 torch.nn.functional 在 PyTorch 中都是用于构建神经网络的重要组件,但它们在设计理念、使用方式和功能上存在一些显著的区别。以下是关于这两个模块的详细区别: 1. 继承方式与结构 torch.nn torch.nn 中的模块大多数是通过继承 torch.nn…...
React的应用级框架推荐——Next、Modern、Blitz等,快速搭建React项目
在 React 企业级应用开发中,Next.js、Modern.js 和 Blitz 是三个常见的框架,它们提供了不同的特性和功能,旨在简化开发流程并提高应用的性能和扩展性。以下是它们的详解与比较: Next、Modern、Blitz 1. Next.js Next.js 是由 Ve…...
基于GRU实现股价多变量时间序列预测(PyTorch版)
前言 系列专栏:【深度学习:算法项目实战】✨︎ 涉及医疗健康、财经金融、商业零售、食品饮料、运动健身、交通运输、环境科学、社交媒体以及文本和图像处理等诸多领域,讨论了各种复杂的深度神经网络思想,如卷积神经网络、循环神经网络、生成对抗网络、门控循环单元、长短期记…...
Spring Cloud AWS 实战教程:构建高可用 SQS 消息队列应用 [特殊字符]
Spring Cloud AWS 实战教程:构建高可用 SQS 消息队列应用 🚀 【免费下载链接】spring-cloud-aws The New Home for Spring Cloud AWS 项目地址: https://gitcode.com/gh_mirrors/sp/spring-cloud-aws Spring Cloud AWS 是一个强大的开源框架&…...
为什么软件开发偏爱 Linux?深度剖析 Linux 相较于 Windows 的核心优势
引言 在软件开发的世界里,一个有趣的现象是:无论是大型互联网公司的服务器集群,还是资深程序员的个人开发机,Linux 操作系统的身影无处不在。与之形成鲜明对比的是,尽管 Windows 在个人消费市场占据绝对主导地位&…...
如何快速集成 react-native-bottom-sheet-behavior:5 分钟搞定 Android 底部弹窗
如何快速集成 react-native-bottom-sheet-behavior:5 分钟搞定 Android 底部弹窗 【免费下载链接】react-native-bottom-sheet-behavior react-native wrapper for android BottomSheetBehavior 项目地址: https://gitcode.com/gh_mirrors/re/react-native-bottom…...
独立开发者如何利用Taotoken Token Plan,以更低成本启动AI项目
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 独立开发者如何利用Taotoken Token Plan,以更低成本启动AI项目 对于独立开发者或小型团队而言,启动一个集成…...
3分钟开启PC游戏分屏派对:NucleusCoop让单机游戏秒变多人同屏神器
3分钟开启PC游戏分屏派对:NucleusCoop让单机游戏秒变多人同屏神器 【免费下载链接】nucleuscoop Starts multiple instances of a game for split-screen multiplayer gaming! 项目地址: https://gitcode.com/gh_mirrors/nu/nucleuscoop 还在为热门PC游戏不支…...
正视孩童情绪波动,耐心陪伴平稳疏导
孩子的情绪就像夏天的天气,前一秒还晴空万里,后一秒可能就乌云密布。面对突如其来的哭闹、发脾气或者闷闷不乐,很多家长会急着“灭火”——要么讲道理,要么直接制止。但其实,情绪波动本身不是问题,它是孩子…...
Claude Code用户告别封号与Token焦虑,无缝切换至Taotoken平台
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 Claude Code用户告别封号与Token焦虑,无缝切换至Taotoken平台 对于依赖Claude Code进行编程辅助的开发者而言ÿ…...
揭秘Midjourney云雾渲染失效真相:3大隐性提示词冲突、2类SDXL迁移兼容漏洞及实时雾浓度校准公式
更多请点击: https://intelliparadigm.com 第一章:揭秘Midjourney云雾渲染失效真相:3大隐性提示词冲突、2类SDXL迁移兼容漏洞及实时雾浓度校准公式 Midjourney V6 在启用云雾(mist/fog/haze)类视觉效果时,…...
全方位梳理 OpenClaw 部署与使用干货
OpenClaw 一键安装包|可视化部署,简化环境配置流程 ✨适配系统:Windows10/11 64 位 当前版本:v2.7.5(虾壳云版) ✨核心优势:全程可视化操作,不用命令行、不用手动配置 Python/Node…...
模拟调音台数字化改造:基于STM32与MOTU音频接口的智能控制方案
1. 项目概述:为老旧模拟调音台注入数字灵魂在不少社区广播电台、校园电台或是小型制作室里,你依然能看到那些服役了十几年甚至几十年的模拟调音台。它们皮实耐用,推子手感扎实,旋钮的阻尼感让人安心,但面对如今以数字文…...
