STM32使用串口空闲中断(IDLE)和 DMA接收一串数据流

news/2024/5/5 18:50:43/文章来源:https://blog.csdn.net/weixin_46251230/article/details/126729795

STM32使用串口空闲中断(IDLE)和 DMA接收不定长数据

方法一、使用宏定义判断IDLE标志位

空闲的定义是总线上在一个字节的时间内没有再接收到数据,USART_IT_IDLE空闲中断是检测到有数据被接收后,总线上在一个字节的时间内没有再接收到数据的时候发生的。

串口空闲中断(UART_IT_IDLE):STM32的IDLE的中断在串口无数据接收的情况下,是不会一直产生的,当清除IDLE标志位后,必须有接收到第一个数据后,才开始触发,一但接收的数据断流,没有接收到数据,即产生IDLE中断。IDLE位不会再次被置高直到RXNE位被置起(即又检测到一次空闲总线)。RXNE接收中断可以不用开启,减少进中断的次数。

IDLE置1之后它不会自动清0,也不会因为状态位是1而一直产生中断,它只有0跳变到1时才会产生,也可以理解为上升沿触发。所以,为确保下次空闲中断正常进行,需要在中断服务函数发送任意数据来清除标志位。

在这里插入图片描述

清除IDLE标志位是通过先读USART_SR,再读USART_DR寄存器来完成的,在HAL库中,提供了一个用于清除IDLE标志位的宏定义,该宏定义在stm32f1xx_hal_uart.h头文件中,__ HAL_UART_CLEAR_IDLEFLAG(__ HANDLE__ )是宏名,__ HAL_UART_CLEAR_PEFLAG(__ HANDLE__)是宏体

/** @brief  Clears the UART IDLE pending flag.* @param  __HANDLE__ specifies the UART Handle.*         UART Handle selects the USARTx or UARTy peripheral*         (USART,UART availability and x,y values depending on device).* @retval None*/
#define __HAL_UART_CLEAR_IDLEFLAG(__HANDLE__) __HAL_UART_CLEAR_PEFLAG(__HANDLE__)

而宏体又是一个宏定义,转到底层代码就可以看到先读SR再读DR寄存器的操作

/** @brief  Clears the UART PE pending flag.* @param  __HANDLE__ specifies the UART Handle.*         UART Handle selects the USARTx or UARTy peripheral*         (USART,UART availability and x,y values depending on device).* @retval None*/
#define __HAL_UART_CLEAR_PEFLAG(__HANDLE__)     \do{                                           \__IO uint32_t tmpreg = 0x00U;               \tmpreg = (__HANDLE__)->Instance->SR;        \tmpreg = (__HANDLE__)->Instance->DR;        \UNUSED(tmpreg);                             \} while(0U)

所以在用HAL库编写串口空闲中断相关代码时,可以用该宏定义来清除IDLE标志位

示例:用宏定义判断IDLE标志位是否置位

/*** @brief This function handles USART1 global interrupt.*/
void USART1_IRQHandler(void)
{/* USER CODE BEGIN USART1_IRQn 0 *///检测串口空闲中断if(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE) != 0x00u)	//判断IDLE标志位是否被置位{__HAL_UART_CLEAR_IDLEFLAG(&huart1);		//清除IDLE标志位HAL_UART_IdleCallback(&huart1);			//调用自己编写的空闲中断回调函数}/* USER CODE END USART1_IRQn 0 */HAL_UART_IRQHandler(&huart1);/* USER CODE BEGIN USART1_IRQn 1 *//* USER CODE END USART1_IRQn 1 */
}

当串口产生中断时,会进入USART1_IRQHandler这个函数,判断IDLE标志位是否被置位,是就先清除标志位,再调用自己写的空闲中断回调函数

USART_IT_IDLE和USART_IT_RXNE区别

当接收到1个字节,会产生USART_IT_RXNE中断

当接收到一帧数据,就会产生USART_IT_IDLE中断

DMA

直接存储器存取(DMA)用来提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。无须CPU干预,数据可以通过DMA快速地移动,这就节省了CPU的资源来做其他操作。 两个DMA控制器有12个通道(DMA1有7个通道,DMA2有5个通道),每个通道专门用来管理来自于一个或多个外设对存储器访问的请求。还有一个仲裁器来协调各个DMA请求的优先权。

在程序中就可以使用DMA搬运外设通过串口发送的数据,放到接收缓存中,在串口空闲中断的回调函数中先关闭DMA,再处理数据,待数据处理完后,再开启DMA搬运

处理数据之前关闭DMA是防止在处理过程中DMA又将新数据搬运到接收缓存,覆盖掉原来的数据

方法二、使用HAL库提供的库函数

使能DMA接收,并于接收完后进入空闲中断函数

函数作用:在DMA模式下接收一定数量的数据,直到接收到预期数量的数据或发生空闲事件。

参数Size:接收数据的长度,一般大于不定长数据长度,避免遗漏数据

HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)

空闲中断回调函数

__weak void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)

使用方法:

先在主函数中调用HAL_UARTEx_ReceiveToIdle_DMA函数初始化

/*
先调用HAL_UARTEx_ReceiveToIdle_DMA函数(比如说在main中调用),产生空闲中断后进入中断服务函数,中断服务函数会调用回调函数。
*/
int main(void)
{...HAL_UARTEx_ReceiveToIdle_DMA(&huart3,DATA_BUFF,BUFF_SIZE);...
}

再在空闲中断回调函数中处理数据

void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{if(huart->Instance == USART3){//这里的DMA为Normal模式//HAL_UART_DMAStop(huart)//如果DMA为Circular模式,回调函数加上stop函数USER_FNC();//用户自定义函数HAL_UARTEx_ReceiveToIdle_DMA(&huart3,DATA_BUFF,BUFF_SIZE);//继续接收数据}
}

参考:http://t.csdn.cn/DJmHQ

注意

看教程时别人使用的是HAL库是STM32Cube_FW_F1_V1.8.0,是1.8.0版本的,没有启动DMA和空闲中断的函数,也没有空闲中断回调函数,所以教程使用的是宏定义判断IDLE标志位的方法;而现在最新的HAL库是1.8.4版本,可在CubeMX中查看,在使用过程中发现是有DMA和空闲中断启动函数HAL_UARTEx_ReceiveToIdle_DMA的,也有空闲中断回调函数HAL_UARTEx_RxEventCallback

不知道从1.8.1到1.8.3哪个版本开始就有了,不过现在最新的有这些函数,也可以尝试着使用一下

在这里插入图片描述

STM32Cube_FW_F1_V1.8.0

在这里插入图片描述

STM32Cube_FW_F1_V1.8.4

在这里插入图片描述

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

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

相关文章

spring cloud alibaba (一)

Spring Cloud Alibaba官网:https://spring.io/projects/spring-cloud-alibaba gitHub:https://github.com/alibaba/spring-cloud-alibaba这节主要目标:掌握nacos使用 了解服务与服务之间调用1、简介 1.1、什么是分布式 将一套系统拆分成不同子系统部署在不同服务器上(这叫分…

flex常用布局

公共样式:<style>* {margin: 0;padding: 0;}.has-flex {display: flex;}</style> 垂直居中 子元素左右分布 css.father-one {width: 100%;height: 200px;background-color: #fffcef;align-items: center; /*纵轴)方向上的对齐方式。*/justify-content: space-bet…

5.2 创建个人中心页面-前端部分

&#x1f60a;如果写的可以帮到你&#xff0c;可以点个赞吗&#xff0c;你的支持就是我写下去的动力。&#x1f60a; 本文阅读大概 10 分钟, 自己写加思考大概 1 ~ 2 小时。建议&#xff1a;代码可以手抄&#xff0c; 但不要复制。 1. 整体框架 2. 前端页面布局 使用 bootstra…

达梦数据库图形化工具

图形化工具列表 (1)DM数据库配置助手 (2)DM服务查看器 (3)DM管理工具 (4)DM控制台工具 (5)DM数据库迁移工具 (6)DM性能监测工具图形化工具详解 界面展示DM数据库配置助手[dmdba@localhost tool]$ ./dbca.sh DM服务查看器DM管理工具DM控制台工具DM数据库迁移工具DM性能监测工具功…

马拉车算法

这篇博客写的非常清晰 https://zhuanlan.zhihu.com/p/549242325 给定一个字符串,问有多少个以 k,f,c 结尾的回文子串。#include<bits/stdc++.h> using namespace std; #define lowbit(x) x&(-x) #define ll long long const int maxn=1e6+5; int n,sum; ll len[maxn…

22-09-04 西安 谷粒商城(01)MySQL主从复制、MyCat读写分离、MyCat分库分表

人人尽说江南好&#xff0c;游人只合江南老。 春水碧于天&#xff0c;画船听雨眠。 MySQL主从复制 mysql主从复制&#xff1a;分摊读写压力&#xff08;cpu计算压力&#xff09; 写交给主库&#xff0c;读有主从分摊处理&#xff08;原因是写操作较少&#xff0c;读操作较多&…

面试官:单核 CPU 支持 Java 多线程吗?为什么?被问懵了!

由于现在大多计算机都是多核CPU,多线程往往会比单线程更快,更能够提高并发,但提高并发并不意味着启动更多的线程来执行。更多的线程意味着线程创建销毁开销加大、上下文非常频繁,你的程序反而不能支持更高的TPS。 时间片 多任务系统往往需要同时执行多道作业。作业数往往大…

ABAP-LP01和PDF打印机配置

事务代码SPAD1.LP01配置2.PDF配置

Netty+WebSocket整合STOMP协议

1.STOMP协议简介 常用的WebSocket协议定义了两种传输信息类型:文本信息和二进制信息。类型虽然被确定,但是他们的传输体是没有规定的,也就是说传输体可以自定义成什么样的数据格式都行,只要客户端和服务端约定好,得到数据后能够按照约定的语义解析数据就好。相较于Http协议…

猿创征文|我的后端成长之路(985科班两年,我发现了大学正确打开方式)

零.前言 当看到官方的这个活动的时候&#xff0c;我突然感到手指充满了力量&#xff0c;好像是我的键盘要向我尖端放电&#xff0c;谁还不是怀着满腔的热忱来写这篇文章帮助未来的学弟学妹们避坑呢&#xff1f;(其实是为了活动的奖励&#x1f917;)。不过不要在意这些细节&…

本地连接是干什么的?

当您创建家庭或小型办公网络时&#xff0c;运行 windows XP Professional 或 windows XP home edition 的计算机将连接到局域网 (Lan)。 安装 windows XP 时&#xff0c;将检测您的网络适配器&#xff0c;而且将创建本地连接。 像所有其他连接类型一样&#xff0c;它将出现在…

【深蓝学院】- Multiplane Images and Neural Rendering

01 view Synthesis problem Definition 02 View synthesis with multiplane Image(MPI) MPI的缺陷&#xff1a; 不是真正的三维表达不同视角观测的RGB是不变的 与MPI不一样的地方&#xff1a;不是手工设计的&#xff0c;而是整体输入 不同视角的RGB是不一样的 缺陷&#xff1…

Pytorch优化器全总结(一)SGD、ASGD、Rprop、Adagrad

目录 写在前面 一、 torch.optim.SGD 随机梯度下降 SGD代码 SGD算法解析 1.MBGD&#xff08;Mini-batch Gradient Descent&#xff09;小批量梯度下降法 2.Momentum动量 3.NAG(Nesterov accelerated gradient) SGD总结 二、torch.optim.ASGD随机平均梯度下降 三、torc…

【手把手】ios苹果打包——遇见项目实战|超详细的教程分享

六年代码两茫茫&#xff0c;不思量&#xff0c;自难忘 6年资深前端主管一枚&#xff0c;只分享技术干货&#xff0c;项目实战经验 关注博主不迷路~ 文章目录前言weex介绍eeui介绍一、安装CocoaPods1.CocoaPods介绍2.CocoaPods的安装二、登录开发者中心四、添加测试手机设备五、…

2022最新iOS证书(.p12)、描述文件(.mobileprovision)申请和HBuider打包及注意注意事项

制作p12证书1、在钥匙串界面中,选中安装好的开发者证书,【右键】选择导出在弹出的界面中3、在接下来的弹窗中填写p12文件的安装密码(后面他人安装该p12文件时需要输入这个密码,重要)4、继续上面的步骤,这里需要输入电脑的开机密码,p12开发者证书到这里即制作完成。以上就…

【芯片前端】根据数据有效选择输出的握手型FIFO结构探究

前言 之前要做一个一读多写的fifo&#xff0c;也就是master写入数据到fifo中&#xff0c;多个slave读取数据&#xff0c;结构如下图所示&#xff1a; 由于slave需要的数据一致&#xff0c;fifo内只需要例化一个ram以节约空间。这个fifo的具体结构下次博客中再来讨论。在这个fi…

Git 之 revert

转自: Git 之 revertrevert 可以撤销指定的提交内容,撤销后会生成一个新的commit。 1、两种commit: 当讨论 revert 时,需要分两种情况,因为 commit 分为两种:一种是常规的 commit,也就是使用 git commit 提交的 commit; 另一种是 merge commit,在使用 git merge 合并两…

mysql 主从备份原理

mysql 主从备份原理 1.1 用途及条件 mysql主从复制用途实时灾备,用于故障切换 读写分离,提供查询服务 备份,避免影响业务主从部署必要条件:主库开启binlog日志(设置log-bin参数) 主从server-id不同 从库服务器能连通主库2.1 主从原理在备库 B 上通过 change master 命令,…

服务端挂了,客户端的 TCP 连接还在吗?

作者:小林coding 计算机八股文网站:https://xiaolincoding.com大家好,我是小林。 如果「服务端挂掉」指的是「服务端进程崩溃」,服务端的进程在发生崩溃的时候,内核会发送 FIN 报文,与客户端进行四次挥手。 但是,如果「服务端挂掉」指的是「服务端主机宕机」,那么是不会…

[第二章 web进阶]XSS闯关-1

定义:跨站脚本(Cross_Site Scripting,简称为XSS或跨站脚本或跨站脚本攻击)是一种针对网站应用程序的安全漏洞攻击技术,是代码注入的一种。它允许恶意用户将代码注入网页,其他用户浏览网页时就会受到影响。恶意用户利用XSS代码攻击成功后,可能得到包括但不限于更高的权限、会…