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

article/2025/8/15 23:07:45

STM32G070串口DMA&IDEL配置

0、概述

在配置STM32G070RBT6进行串口通信功能时,如果尝试开启空闲中断进行不定长数据接收时,串口一旦接收到数据,就会一直卡在串口中断,无法进行其他操作。配置空闲中断的方法是按照F系列的HAL库配置方法,本次使用的HAL版本是STM32Cube_FW_G0_V1.5.0。

1、解决方法

在查阅资料后,发现F4系列高版本的HAL库串口中断处理方法中,如果开启了串口空闲中断,中断回调函数里没有专门针对空闲中断处理的函数。按照HAL库给的方法,通过DMA接收数据并判断是否有空闲中断事件发生。其中,HAL库的中断函数代码参考如下:
void HAL_UART_IRQHandler(UART_HandleTypeDef *huart)
{uint32_t isrflags   = READ_REG(huart->Instance->ISR);uint32_t cr1its     = READ_REG(huart->Instance->CR1);uint32_t cr3its     = READ_REG(huart->Instance->CR3);uint32_t errorflags;uint32_t errorcode;···············省略一部分···············
/* Check current reception Mode :If Reception till IDLE event has been selected : */
//检查是否产生空闲中断事件if ((huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)&& ((isrflags & USART_ISR_IDLE) != 0U)&& ((cr1its & USART_ISR_IDLE) != 0U)){//清除空闲中断标志位__HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF);/* Check if DMA mode is enabled in UART *///检查是否使用了串口DMA接收中断if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)){/* DMA mode enabled *//* Check received length : If all expected data are received, do nothing,(DMA cplt callback will be called).Otherwise, if at least one data has already been received, IDLE event is to be notified to user */uint16_t nb_remaining_rx_data = (uint16_t) __HAL_DMA_GET_COUNTER(huart->hdmarx);if ((nb_remaining_rx_data > 0U)&& (nb_remaining_rx_data < huart->RxXferSize)){/* Reception is not complete */huart->RxXferCount = nb_remaining_rx_data;/* In Normal mode, end DMA xfer and HAL UART Rx process*/if (HAL_IS_BIT_CLR(huart->hdmarx->Instance->CCR, DMA_CCR_CIRC)){/* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE);ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);/* Disable the DMA transfer for the receiver request by resetting the DMAR bitin the UART CR3 register */ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);/* At end of Rx process, restore huart->RxState to Ready */huart->RxState = HAL_UART_STATE_READY;huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);/* Last bytes received, so no need as the abort is immediate */(void)HAL_DMA_Abort(huart->hdmarx);}
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)/*Call registered Rx Event callback*/huart->RxEventCallback(huart, (huart->RxXferSize - huart->RxXferCount));
#else/*Call legacy weak Rx Event callback*///即使串口DMA没有接收完,产生空闲中断时,也会触发HAL_UARTEx_RxEventCallback回调函数HAL_UARTEx_RxEventCallback(huart, (huart->RxXferSize - huart->RxXferCount));
#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */}return;}
···············省略一部分···············

以上代码可以看出,新版本的HAL库将DMA接收中断和IDEL空闲中断结合起来用于接收不定长数据,当产生空闲中断时,HAL_UART_IRQHandler函数会检查是否使能了DMA接收中断:

Check received length : If all expected data are received, do nothing,
(DMA cplt callback will be called).
Otherwise, if at least one data has already been received, IDLE event is to be notified to user

从上面的解释可以看出,如果产生了空闲中断,检查DMA设定的数据长度是否接收满了,如果数据长度满了则会产生DMA中断,如果还没有接收满,但是已经有至少一字节数据被接收了,则会通过RxEventCallback回调函数通知用户来处理数据。

2、实验验证

2.1 STM32CubeMX配置
–>时钟配置:特别注意一定要对串口的时钟单独配置
在这里插入图片描述

–>串口DMA配置:Normal模式,其他默认即可
在这里插入图片描述

2.2 主要部分代码展示
main函数部分

  MX_GPIO_Init();MX_DMA_Init();MX_USART2_UART_Init();/* USER CODE BEGIN 2 */HAL_UARTEx_ReceiveToIdle_DMA(&huart2, RxBuf, RxBuf_SIZE);//_HAL_DMA_DISABLE_IT(&hdma_usart2_rx, DMA_IT_HT);//__HAL_UART_ENABLE_IT(&huart2, UART_IT_RXNE);//__HAL_UART_ENABLE_IT(&huart2, UART_IT_IDLE);//不在主函数里使能空闲中断,程序也正常运行,建议不用添加/* USER CODE END 2 */

红色部分为使能串口接收中断和DMA&&空闲中断,HAL_UARTEx_ReceiveToIdle_DMA函数参数为串口句柄、数据缓存数组、DMA接收的最大长度
usart部分代码

void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{if (huart->Instance == USART2){oldPos = newPos;  // Update the last position before copying new data/* If the data in large and it is about to exceed the buffer size, we have to route it to the start of the buffer* This is to maintain the circular buffer* The old data in the main buffer will be overlapped*/if (oldPos+Size > MainBuf_SIZE)  // If the current position + new data size is greater than the main buffer{uint16_t datatocopy = MainBuf_SIZE-oldPos;  // find out how much space is left in the main buffermemcpy ((uint8_t *)MainBuf+oldPos, RxBuf, datatocopy);  // copy data in that remaining spaceoldPos = 0;  // point to the start of the buffermemcpy ((uint8_t *)MainBuf, (uint8_t *)RxBuf+datatocopy, (Size-datatocopy));  // copy the remaining datanewPos = (Size-datatocopy);  // update the position}/* if the current position + new data size is less than the main buffer* we will simply copy the data into the buffer and update the position*/else{memcpy ((uint8_t *)MainBuf+oldPos, RxBuf, Size);newPos = Size+oldPos;}/* start the DMA again */Uart2_SendStr((char*)RxBuf);HAL_UARTEx_ReceiveToIdle_DMA(&huart2, (uint8_t *) RxBuf, RxBuf_SIZE);__HAL_DMA_ENABLE_IT(&hdma_usart2_rx, DMA_IT_HT);}/****************** PROCESS (Little) THE DATA HERE *********************//* Let's say we want to do if IDEL Event happend */}

以上代码可以自定义内容,按照以上程序内容如果一次向DMA发送的数据超过了RxBuf_SIZE,新数据会把旧数据覆盖掉,但是!!!如果一次发送的数据量很大,memcpy拷贝函数操作时会越界,最好不要一次发送上百字节的较长数据流,或者将数据缓冲数组设置大一些,否则回调函数里数组越界将会有不可测的事情发生。

3、总结

还是没有在新版本HAL库中找到能够单独使用IDEL中断函数的用法,以上方法是使用了DMA和IDEL中断进行不定长数据的接收。

4、参考

  • 知乎: https://zhuanlan.zhihu.com/p/400728566
  • 网友博客教程: https://controllerstech.com/uart-dma-with-idle-line-detection/

http://chatgpt.dhexx.cn/article/pIKIy2fK.shtml

相关文章

Idel中maven全局配置

每次创建新项目&#xff0c;都要配置一遍maven&#xff0c;实在是麻烦。 所以&#xff0c;想到是否可以全局配置呢。 在File - Settings里没有找到相关内容。 方法&#xff1a; 关闭项目&#xff0c;在Idea的启动界面&#xff0c;右下角有个 【Configure】&#xff0c;进入【…

layers.Normalization

标准化&#xff0c;就是执行 特征标准化层&#xff0c; 第一种方式&#xff1a;通过数据计算出均值和方差&#xff1a; adapt_data np.array([[0., 7., 4.],[2., 9., 6.],[0., 7., 4.],[2., 9., 6.]], dtypefloat32) input_data np.array([[0., 7., 4.]], dtypefloat32) l…

Batch Normalization、Instance normalization简单理解

1. Batch Normalization 首先&#xff0c;简短介绍一下Batch Normalization&#xff0c;通常Batch Normalization更为大家所知&#xff0c;所以在此简要介绍BN来引入Instance Normalization。 引入BN层主要是为了解决"Internal Covariate Shift"问题&#xff0c;关…

Normalized Mutual information

在写论文做数据测试时有用到一个nmi(normalized mutual information)评价聚类的一种方法&#xff0c;不是很清楚&#xff0c;然后上网找了一下资料。 首先在理解nmi前&#xff0c;先说说mutual information这个东西。 我们先举个例子&#xff1a; 比如说&#xff0c;标准结果…

Cesium 定位到图层(ImageryLayer)报错 DeveloperError: normalized result is not a number

Cesium 定位到图层&#xff08;ImageryLayer&#xff09;报错 DeveloperError: normalized result is not a number 错误原因调试定位问题过程问题解决总结 2023年4月19日更新—搞了一个 Cesium 镜像&#xff0c;欢迎使用&#xff1a;沙盒示例 和 API 在使用 Cesium 封装代码的…

normalize 函数

2. normalize 函数介绍 函数原型&#xff1a; void normalize(InputArray src,OutputArray dst, double alpha1, doublebeta0, int norm_typeNORM_L2, int dtype-1, InputArray masknoArray() ) 该函数归一化输入数组使它的范数或者数值范围在一定的范围内。 Parameters: src …

(六)Normalization

&#xff08;六&#xff09;Normalization why 从图中可以看出&#xff0c;当输入太小或者太大的时候&#xff0c;函数的取值随着输入的变化几乎为0。这样就会发生梯度离散的情况&#xff0c;因此我们很有必要把输入控制在一个小一点的区间内。所以我们通过normalization操作&…

【C++】Eigen中norm、normalize、normalized的区别

参考&#xff1a; https://blog.csdn.net/m0_56348460/article/details/117386857https://blog.csdn.net/huangjunsheng123/article/details/119274776?spm1001.2101.3001.6650.7&utm_mediumdistribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7E…

理解各种 Normalization

引言 Batch Normalization&#xff08;BN&#xff09;似乎已经成为构建网络不可缺少的一部分&#xff0c;它是如此“熟悉”以至于我天天使用却不明白原理。对此&#xff0c;本文梳理了 BN 的意义&#xff0c;实现以及一系列变体&#xff1a;Layer Norm&#xff0c;Instance No…

Layer Normalization解析

原论文名称&#xff1a;Layer Normalization 原论文地址&#xff1a; https://arxiv.org/abs/1607.06450 之前有讲过Batch Normalization的原理&#xff0c;链接&#xff0c;今天来简单讲讲Layer Normalization。Layer Normalization是针对自然语言处理领域提出的&#xff0c;…

Eigen中norm、normalize、normalized的区别

Eigen中norm、normalize、normalized的区别 norm() 对于Vector&#xff0c;norm返回的是向量的二范数&#xff0c;即 例如&#xff1a; Vector2d vec(3.0,4.0); cout << vec.norm() << endl; //输出5 对于Matrix&#xff0c;norm返回的是矩阵的弗罗贝尼乌斯范数…

归一化函数 normalized()

1. 归一化定义与作用 归一化就是要把需要处理的数据经过处理后&#xff08;通过某种算法&#xff09;限制在你需要的一定范围内。 首先归一化是为了后面数据处理的方便&#xff0c;其次是保证程序运行时收敛加快。归一化的具体作用是归纳统一样本的统计分布性。归一化在0-1之间…

手机锁屏后微信收款语音不播报?-by:nixs

荣耀10&#xff0c;之前用荣耀7x就没这毛病&#xff01; 我确认与设置无关&#xff0c;微信语音播报是开启状态&#xff0c;通知设置都是允许的&#xff0c;我更不会二到把手机关静音&#xff01; 反正就是黑屏待机时&#xff0c;没有任何声音&#xff0c;一但点亮屏幕就有语音…

App微信小程序测试流程及要点

1 APP测试基本流程 1.1流程图 1.2测试周期 测试周期可按项目的开发周期来确定测试时间&#xff0c;一般测试时间为两三周&#xff08;即15个工作日&#xff09;&#xff0c;根据项目情况以及版本质量可适当缩短或延长测试时间。正式测试前先向主管确认项目排期。 1.3测试资源…

微信小程序,分享如何封装一个全局支持暂停,拖动等各类操作的音视频等多媒体管理器

不知不觉埋头于业务已许久&#xff0c;距离上一篇分享应该很久很久以前&#xff0c;具体何时&#xff0c;已无从知晓。慢慢的开始觉得锅有点热&#xff0c;感觉呼吸有点困难&#xff0c;温水里面的青蛙趁着腿还没完全麻木的时候&#xff0c;也想着开始重拾旧梦&#xff0c;稍微…

html微信登录密码输入密码,不用输密码,只要8个数字就能登录你的微信

不知道大家有没有遇到过这样的问题&#xff0c;就是当我们换新手机之后&#xff0c;在登录微信的时候就需要密码了。 打开凤凰新闻&#xff0c;查看更多高清图片 可是有些人记性不好&#xff0c;经常忘记微信登录密码&#xff0c;这该怎么办呢&#xff1f;今天小Q来教大家一招可…

微信上隐藏着6个功能,实在是太厉害了,真令人相见恨晚

很多人都说微信不太好用,那是因为你还没有找到好用的功能,如果你只会聊天和付款那就太out了,今天才知道,微信上隐藏着6个功能实在是太厉害了。 一、无线极速传输 微信不仅方便了生活,在办公上也是一个小能手,无需数据线就能与电脑相互传输文件,找到文件传输助手,将文件…

基于微信小程序音乐播放器的设计与实现毕业设计源码271156

Springboot音乐播放小程序的设计与实现 摘 要 本文设计了一种基于微信小程序的音乐播放器&#xff0c;系统为人们提供了方便快捷、即用即搜的音乐搜索播放服务&#xff0c;包括音乐资讯、音乐库推荐、交流论坛、注册登录、最近播放列表功能等&#xff0c;用户不仅能够方便快捷地…

微信按钮翻译中英对照表

申明&#xff1a;发文方便自己查阅&#xff0c;当然如对看到的朋友有所帮助&#xff0c;也是乐事一件。 代码中需要调用微信&#xff0c;翻译连续翻车&#xff0c;比如朋友圈&#xff0c;做个记录方便查阅&#xff1a; /** * 微信 中英文对照 * 微信 wechat * 朋友圈…

微信更新了 版本8.0.30

这次新功能包括&#xff1a; 朋友圈扩展文字输入区域&#xff1a;发朋友圈或朋友圈评论时&#xff0c;编辑文案&#xff0c;文本区域会随文字数量而增大。长按订阅号可以取消关注&#xff1a;在订阅号列表中&#xff0c;此前长按封面只有悬浮功能&#xff0c;更新后现在加入了…