STM32空闲中断+DMA解决接收不定长数据问题

解决STM32G0B1 串口DMA 空闲中断接收数据中途失效问题 解决STM32G0B1 串口空闲中断DMA 串口失效问题 Overrun 阅读详情

串口的中断类型:

#define USART_IT_PE                          ((uint16_t)0x0028)
#define USART_IT_TXE                         ((uint16_t)0x0727)
#define USART_IT_TC                          ((uint16_t)0x0626)
#define USART_IT_RXNE                        ((uint16_t)0x0525)
#define USART_IT_IDLE                        ((uint16_t)0x0424)
#define USART_IT_LBD                         ((uint16_t)0x0846)
#define USART_IT_CTS                         ((uint16_t)0x096A)
#define USART_IT_ERR                         ((uint16_t)0x0060)
#define USART_IT_ORE                         ((uint16_t)0x0360)
#define USART_IT_NE                          ((uint16_t)0x0260)
#define USART_IT_FE                          ((uint16_t)0x0160)

USART_IT_PE 奇偶错误中断

USART_IT_TXE发送中断

USART_IT_TC 传输完成中断

USART_IT_RXNE 接收中断

USART_IT_IDLE 空闲总线中断

USART_IT_LBD LIN中断检测中断

USART_IT_CTS CTS中断

USART_IT_ERR 错误中断


该程序中用到的就是串口的空闲中断:当总线是一个字节周期内没有收到数据时触发

串口的配置如下:

void uart_init(u32 bound){
        GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);	
	NVIC_InitTypeDef NVIC_InitStructure;
	 //IO口相关配置
 	USART_DeInit(USART1);  
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//IO口速率
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; 
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
        GPIO_Init(GPIOA, &GPIO_InitStructure); 
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
        GPIO_Init(GPIOA, &GPIO_InitStructure);  
        //串口中断配置
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;		
        NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			
	NVIC_Init(&NVIC_InitStructure);	
	USART_InitStructure.USART_Parity = USART_Parity_No;//没有奇偶校验位
	USART_InitStructure.USART_BaudRate = bound;       //波特率设置
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;//8位数据位
	USART_InitStructure.USART_StopBits = USART_StopBits_1;//1位停止位
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流配置
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//串口收发模式
        USART_Init(USART1, &USART_InitStructure); 
        USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);
        USART_Cmd(USART1, ENABLE);  
}  

串口中断配置:
void USART1_IRQHandler(void)                 
{
      if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET) 
{
       DMA_Cmd(DMA1_Channel5,DISABLE);
       recok=1;
       lenth=USART1->DR;//软件清空空闲中断标志位
       lenth=USART1->SR;
       lenth=32-DMA_GetCurrDataCounter(DMA1_Channel5);//获取当前接收的数据量 
       USART_RX_BUF[lenth]=0;//在buff最后加入空字符
       DMA1_Channel5->CNDTR=32;//重新设置传输量为32 
       DMA_Cmd(DMA1_Channel5,ENABLE);
    } 
} 



DMA配置:

void MYDMA_Config(DMA_Channel_TypeDef* DMA_CHx,u32 cpar,u32 cmar,u16 cndtr)
{
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);//使能DMA时钟

      DMA_DeInit(DMA_CHx);
      DMA1_MEM_LEN=cndtr;
      DMA_InitStructure.DMA_PeripheralBaseAddr = cpar;//外设地址
      DMA_InitStructure.DMA_MemoryBaseAddr = cmar; //内存地址
      DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //传输方向外设到内存
      DMA_InitStructure.DMA_BufferSize = cndtr;  //传输量
      DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设地址不自增  
      DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址自增
      DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; 
      DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; 
      DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //普通模式
      DMA_InitStructure.DMA_Priority = DMA_Priority_High;//高优先级
      DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
      DMA_Init(DMA_CHx, &DMA_InitStructure);  
} 



主函数中需要进行的配置:

 MYDMA_Config(DMA1_Channel5,(u32)&USART1->DR,(u32)USART_RX_BUF,32);//传输方向设置为USART1->DR到USART_RX_BUF 传输大小为32字节
 USART_DMACmd(USART1,USART_DMAReq_Rx,ENABLE);//允许DMA请求
 DMA_Cmd(DMA1_Channel5,ENABLE);

当标志为recok位1时表示接受完成  在主函数中等待recok位1就可以了


STM32的HAL库DMA串口不定长度的读写操作(二) 上一次我们通过HAL库的串口中断回调函数,基本能够实现简单的不定长度读写收发的功能。这一次用DMA来实现,先了解一下DMA。 DMA直接存储器存取用来提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。无须CPU的干预,通过DMA数据可以快速地移动。这就节省了CPU的资源来做其他操作。 DMA详解传送门:https://blog.youkuaiyun.com/Cheatscat/artic... 阅读详情

相关推荐

STM32 HAL库串口空闲中断+DMA接收不定长数据实战解析

本文详细解析了STM32 HAL库中串口空闲中断与DMA接收的结合应用,有效解决嵌入式开发中不定长数据接收的难题。通过硬件自动检测空闲状态和DMA后台数据传输,大幅降低CPU占用率并提升系统效率,特别适合物联网和工业控制等实时性要求高的场景。

water的专栏 629

STM32F103,HAL,串口使用空闲中断时返回的数据不全,有丢失的情况的解决办法

在STM32F103中使用空闲中断的时候,经常会出现丢数据的情况,我猜测是因为连接环境中有延时,造成标志位误触发的情况。 解决思路,直接使用LL库代替HAL库,不用DMA也不用空闲中断,用最原始的办法就是直接接收中断触发的方式做。 使用定时器1,用于接收延时处理,达到不定长字符串接收的目的。 1,CUBEMX配置 不用DMA 中断勾选 定时器配置 2...

wfjdemmye的博客 5670

STM32H7串口DMA+空闲中断实战:蓝牙数据接收的HAL库调试技巧

本文详细介绍了在STM32H7平台上,结合串口DMA与空闲中断实现高效、稳定的蓝牙数据接收的实战技巧。重点解析了HAL库的配置要点、中断服务函数编写、以及H7系列特有的Cache一致性问题解决方案,并分享了蓝牙配对时序等关键调试经验,帮助开发者规避常见陷阱,构建可靠的通信框架。

transformer2023的博客 1044

关于STM32用DMA传输UART空闲中断中接收的数据时无法接收数据问题以及解决办法

关于STM32用DMA传输UART空闲中断中接收的数据时无法接收数据问题以及解决办法

qq_30993593的博客 1万+

GD32串口接收不定长数据:空闲中断+DMA高效方案详解

在嵌入式开发中,串口接收不定长数据是一项常见却容易引发性能瓶颈的任务。传统逐字节中断接收方式会造成频繁的CPU开销,尤其在高速率、多帧连续传输场景下更为明显。DMA(直接存储器访问)与空闲中断的结合提供了一种高效解法:由DMA负责数据搬运,串口空闲中断判定帧边界,CPU仅在完整一帧到达时才被唤醒。这一机制可以大幅降低中断频率、提升系统实时性,适用于高波特率、多任务并行的工程环境。对于从STM32生态迁移至GD32平台的开发者,还需留意寄存器命名、DMA通道映射以及空闲中断标志清除等外设差异。本文围绕GD32

weixin_29168393的博客 224

基于奥比中光Orbbec Astra Pro与ROS实现实时3D环境建模:orb_slam2实战指南

本文提供了一份详细的实战指南,介绍如何使用奥比中光Orbbec Astra Pro深度摄像头与ROS系统,部署并运行ORB-SLAM2算法,实现实时3D环境建模与定位。内容涵盖从驱动安装、环境配置、算法编译到摄像头标定与性能调优的全流程,旨在帮助开发者快速搭建一套高性价比的视觉SLAM系统。

weixin_29054399的博客 334

MM32F3277空闲中断+DMA接收不定长数据

摘要:在实际项目中经常用到串口接收一些不定长的数据,怎么判断这一帧数据接收完成了呢?通常使用UART非空中断配合简单的数据协议,在数据中加入帧头、帧尾,在程序中判断是否接收到帧尾来确定数据接收完毕,对每个字节数据都要进行判断,比较消耗系统资源,尤其是在一些实时性要求较高的场合。而串口空闲中断可以大大简化数据接收过程的判断,在这一块起到非常重要的作用。 关于这种方法,可以看以前STM32第五章-串口通讯详解。下面说一下空闲中断+DMA。 一、什么是空闲中断? 空闲中断(IDLE),俗称帧中断,即第一帧数据接收

果果小师弟的博客 3193

告别Quartus II的漫长等待:用VSCode+iverilog+GTKWave搭建你的轻量级Verilog仿真环境(2024保姆级教程)

本文详细介绍了如何利用VSCode、iverilog和GTKWave构建高效的Verilog/SystemVerilog开发环境,替代传统的Quartus II和ModelSim工具。通过2024年最新的保姆级教程,帮助开发者实现秒级启动、低资源消耗的轻量级仿真环境,显著提升数字电路设计的开发效率和调试体验。

weixin_33690963的博客 560

STM32 开启接收空闲中断后再开DMA,DMA不能接收到数据问题

一 问题描述 使用STM32F091CBT6时使用空闲中断加DMA方式实现接收不定长度的数据时,发现DMA不能正常接收数据,但接收到串口数据后能进入串口中断,但出现OVERRUN错误。 二 问题原因 1. 使用Cubemx生成的代码中初始化DMA是在初始化串口后面进行 /* Initialize all configured peripherals */ MX_GPIO_Init(); M...

zhaoem82的博客 6605

centos-stream-9上安装nvidia驱动和cuda-toolkit

centos-stream-9上安装nvidia驱动和cuda-toolkit

qq_19072921的博客 3020

《UDS协议从入门到精通》系列——图解0x27:安全访问

什么是安全访问服务?应用场景和基本原理是什么?全网最直观详细的图解UDS-0x27:安全访问服务!!

车载系统攻城狮 7231

STM32 HAL 之 UART:空闲中断结合DMA实现不定长数据收发

一、不定长数据接收的原理及其解决的问题 在 STM32 中,UART是最为常见的通信方式——它每次接收一个字节。我们可以使用轮询的方式,但是对于某些数据不固定时间发送的数据,轮询的方式有时候不够灵活。也可以使用中断的方式,如每一个字节都中断一次,当时比较消耗系统资源。特别是HAL库中,从中断到回调函数运行了不少的程序,频繁的中断很可能造成数据溢出。在本文使用F051单片机中,这种情更加明显。为了避免这个问题,我们使用指定接收一定长度的数据,再调用回调函数,这会让我们可以接收大数据,但是这种情况则造成了,要求

戈扬的博客 1万+

Unreal 从入门到精通之VR常用操作

本文总结了使用Unreal5开发VR项目时遇到的常见问题及其解决方案。首先,介绍了如何通过VRPawn的TryTeleport函数设置玩家视角位置,确保头显移动时安全区域的正确传送。其次,详细说明了如何在Unreal中播放视频,包括导入视频文件、创建媒体播放器和媒体纹理,并将其应用到3D物体上。接着,讲解了如何播放VR全景视频,建议使用MediaPlate媒体板并调整几何体为球体。最后,讨论了如何手动打开和关闭VR模式,以便在PC模式和头显模式之间切换。这些方法为VR开发提供了实用的技术指导。

TxNet 951

STM32G707HAL库配置串口DMA和IDEL空闲中断接收不定字长数据

STM32G070串口DMA&IDEL配置 0、概述 在配置STM32G070RBT6进行串口通信功能时,如果尝试开启空闲中断进行不定长数据接收时,串口一旦接收到数据,就会一直卡在串口中断,无法进行其他操作。配置空闲中断的方法是按照F系列的HAL库配置方法,本次使用的HAL版本是STM32Cube_FW_G0_V1.5.0。 1、解决方法 在查阅资料后,发现F4系列高版本的HAL库串口中断处理方法中,如果开启了串口空闲中断,中断回调函数里没有专门针对空闲中断处理的函数。按照HAL库给的方法,通过D

weixin_40421178的博客 3343

CVPR 2023 中的半监督学习: FixMatch 的升级版 UniMatch

我们首先回顾下发表在 NeurIPS 2020 上的 FixMatch: Simplifying Semi-Supervised Learning with Consistency and Confidence,FixMatch 是一种更轻量的半监督分类方法。如下图所示,FixMatch 首先使用模型(带标签数据训练后的)对弱增强的未标记图像进行预测,生成伪标签。对于给定的图像,只有在模型产生高置信度的预测时,伪标签才会被保留。然后,在输入同一图像的强增强版本时,训练模型预测伪标签。

NJU phd 在读。 2632

数据分析之AB测试基础知识

在 A/B 测试中,零假设是两组的指标是相同的,当假设检验推断出两组指标不同,但事实上两组指标相同时,就是第一类错误。

qq_45727498的博客 560

stm32双串口+DMA接收不定长数据,用于调试与ESP8266通信

本文为本人学习esp8266过程的学习笔记,源码在最后,接收不定长数据的方法也可以应用在其它地方 由于项目需求,购买了ESP8266作为STM32数据发送到云服务器的桥梁。调试esp8266过程中也遇到了问题。后面采用了串口空闲中断+DMA接收的方法解决了接收不定长数据的问题 esp8266的工作原理我就不赘述了,我看的下面大佬的博客: (29条消息) 基于STM32的ESP8266使用教程(一)_量化这个世界!-优快云博客 (29条消息) 【常用模块】ESP8266 WIFI串口通信模块使用详解

oldjohntangna的博客 2282

【大数据技术干货】(还不懂数仓,数据中心?看这一篇就够了!)在实际的开发生产中,让你了解企业级数据中心整体架构(DB+ETL+ODS+DW+DM)的各个层次的过程详解,数据联系及功能区分

一 企业级数据中心架构 数据仓库的整体架构,各个系统的元数据通过ETL同步到操作性数据仓库ODS中,对ODS数据进行面向主题域建模形成DW(数据仓库),DM是针对某一个业务领域建立模型,具体用户(决策层)查看DM生成的报表。 二 DB 三 ETL(Extract-Transform-Load) ETL是将业务系统的数据经过抽取、清洗转换之后加载到数据仓库的过程,目的是将企业中的分散、零乱、标准不统一的数据整合到一起,为企业的决策提供分析依据。 ETL是BI项目重要的一个环节。 通常情况下,在BI项目中ET

liuchunhang的博客 1288

STM32串口中断接收不定长字符串的三种方法(HAL库)

在三种方法中,方法一必须判断字符串指定的结束符,通用性不强;方法二通过单字节中断接收字符串,通过空闲中断判断字符串结束;方法三通过DMA中断接收字符串,通过空闲中断计算字符串长度,从而判断字符串结束位置。

qq_34695423的博客 1809

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

【亲测免费】 高效稳定:STM32H743串口DMA与空闲中断解决方案

高效稳定:STM32H743串口DMA与空闲中断解决方案 【下载地址】STM32H743串口DMA空闲中断资源文件介绍 本资源文件提供了基于STM32H743微控制器的串口DMA与空闲中断的实现代码。该代码能够接收不定长数据,并且在代码中对容易出问题的地方进行了完善处理,确保了代码的稳定性和可靠性 ...

gitblog_09733的博客 1091

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

STM32串口空闲中断加DMA传输不定长数据

决定开始在优快云上记录学习单片机的过程了 想讲讲我对串口空闲中断加DMA的理解 1.DMA传输的好处 一般的数据通过串口传输都会经过CPU的读取 当模块多起来(比如五六个激光测距模块读取再加上MPU的解算)CPU会负荷过重而致使程序卡顿造成干扰 而DMA可以当成传输数据的桥梁 (介于外设到存储器 /存储器到外设 /存储器到存储器) 桥梁的作用是自身开辟一个通道使数据传输无需经过CPU从而减少CPU消耗 2.串口空闲中断 串口空闲中断顾名思义 在串口空闲时(发完一帧数据)产生中断 3....

qq_52105802的博客 727

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

STM32 串口 DMA 接收任意长度数据

这里是转变了一个思路,单纯从 DMA 角度解决问题貌似找不到很好的答案,那就转换到串口上来。因为本身的工作是串口 DMA 接收任意长度数据。

lyndon 3263

【STM32】DMA+空闲中断 高效接收不定长数据实战指南

本文详细介绍了STM32如何利用DMA和空闲中断实现高效的不定长数据接收。通过分析传统定长接收方式的痛点,深入讲解空闲中断工作原理和DMA如何大幅降低CPU占用,并提供完整的配置流程、代码实现及实际应用中的优化技巧,如双缓冲和超时保护机制,帮助开发者解决串口通信中的常见问题。

yhn456789的博客 1003

hal库串口dma卡死_stm32 HAL库 串口DMA接收不定长度数据及粘包处理

1串口接收不定长度数据及数据粘包解析的实现1、如何让串口接收不定长度数据想让Stm32串口接收不定长度数据,这就需要我们开启串口空闲中断(IDLE)方式,所谓串口空闲中断指的是stm32的数据总线在接收数据的过程中,如果总线在接收一个字节所需要的时间内没有再接收到数据,单片机就会判定此时数据已经接收完成了,这时单片机会自动触发空闲中断IDLE标志位,引发空闲中断,我们只需要进入中断取数据就可以了。...

weixin_34792641的博客 1083

HAL库STM32串口开启DMA接收数据

此博客仅仅作为记录,这个像是有bug一样,有时候好使,有时候不好,所以趁现在好使赶紧记录一下,很多地方用到串口接收数据,DMA又是一种非常好的接收方式,可以节约CPU的时间,提高利用率,首先是在CubeMX的配置,这个很简单,首先配置成异步收发。最后需要在串口中断函数stm32f1xx_it.c操作一些东西,首先在此函数中引用usart.h文件,否则会报错。在while(1)中的代码操作,就是判断标志位,然后把接收到的数据打印出来。首先就是必须勾选,要不然打印不了数据,使用DMA发送数据的时候,可能。

m0_58832575的博客 1681
上一篇: 利用Python解决将黄金比例计算至100位
下一篇: STM32输入捕获加DMA传输的解决方案
shu_8708
博客等级 码龄10年 45粉丝 40原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值