STM32 串口超时中断+DMA接收不定长数据 比 空闲中断(IDLE)更加灵活、稳定(一)

2023-05-16

前言:

        最近项目有使用串口接收大段不定长GPS数据的需求,调试了很久,终于找到一个比较好的解决办法。我觉得这个项目需求(高波特率、大段数据、不定长)十分典型,所以在这里记录一下,与大家分享。

        这次项目用的是STM32H7的主控+cubemx+MDK做的开发,项目中使用到了FreeRTOS+lwip以及多个串口,且每个串口的波特率都是一个比较高的波特率(均在460800以上),与传统大家常用的9600及115200在调试过程中会有一些不同(感觉是更容易受到干扰)。

        在接手项目时,第一时间想的是使用IDLE中断+DMA这种主流的接收不定长数据的方式进行操作,但在调试过程中遇到了串口一帧数据(400-600字节)被打断成两帧数据的情况,在这种情况下需要额外花费CPU的算力去解析、拼包,否则就会导致丢帧,由于项目的特殊性和gps数据只有1HZ的性质,丢弃掉被打散的包和花费额外算力去拼包都是不优先考虑的方法,于是我开始进行对于这个bug的分析与尝试性解决。

问题分析:

        针对包被打散的情况,我分析是在数据传输的过程中,单片机跳到了空闲中断,读取了一次DMA中的数据,原因可能有几种:

1、GPS模块在发送数据时并不是均匀连续的,中间存在一定长度的中断,导致IDLE中断触发。

2、误触发,由于波特率较高容易受到其他干扰,以及单片机运行的任务较多,单片机内部中断、任务调度产生了干扰,导致IDLE中断触发。

        针对以上两种可能性,展开调试,首先先使用电脑用460800波特率接收GPS同样的数据,发现没有任何问题;

        然后通过示波器查看GPS数据,未发现明显异常,示波器的Decode功能也能正常解析GPS数据(这里本来想贴几张图,由于目前工作环境不太允许,所以就省略了);

        最后将GPS的波特率拉低,设置在115200,单片机通过115200波特率接收同样的数据,发现数据接收正常了,但是领导无法接受115200波特率下,整帧数据接收时间将会达到40ms左右的延时。所以无奈再去寻找其他解决办法。

        那么就得从原理上来分析这个问题了,我们首先来看一下ST官方对于空闲中断条件的说明:

        当在参考手册RM0433中文文档(文档号029587 Rev 1)1912页我们可以看到,当检测到空闲线路时IDLE会置1并产生中断,我们继续查看,产生空闲线路的条件

        同文的1859、1860页讲述了起始位检测,当起始位检测中止时,即停止位结束后,下降沿检测成功,随后连续检测一位时间没有起始位的话,接收器就会返回空闲状态,继而触发空闲中断,结合之前改为115200波特率bug消除的现象来看的话,我们可以认为,460800波特率下,一位时间太短了,很容易误检测,导致单片机IDLE中断触发,那么,我接下来就需要考虑,如何去将触发中断的时间延长,使中断没有这么容易被触发,让我们可以更好的接收一整帧的数据。

解决问题:

        当然解决这个问题有很多种方式,降低波特率也好,改变接收中断也罢,都能解决这个问题,针对我的需求,我查看了STM32H7串口接收的几种中断:

         在中断介绍中,我发现接收器超时中断也许可以解决我目前的问题,我查找了接收器超时中断触发的条件:

 

        当我们在RTOR寄存器中设置超时值之后,没有任何通信时就可以触发这个中断,不过手册上又说并非每一个串口都支持这个超时中断,所以我们还要去48.4节USART实现中查找我们要用的串口是否支持超时中断:

 

        可以看到除了LPUART,所有串口都是支持的。

阶段总结: 

        经过分析与查找手册,我们找到了一个可以自由调整“空闲”时间的“空闲中断”——RTOF接收器超时中断,这样的中断方式从原理上是可以解决我们大段不定长高波特率数据在使用空闲中断时会被打断的问题的,在下一节,我将编写代码来实现使用接收器超时中断的不定长数据串口接收。

        非常感谢大家的阅读,如果喜欢请给我点个赞吧,如文章中有错漏欢迎大家在评论区或私信斧正,一些其他的技术问题也可以在评论区或私信交流。

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STM32 串口超时中断+DMA接收不定长数据 比 空闲中断(IDLE)更加灵活、稳定(一) 的相关文章

  • Nginx控制IP(段)的访问策略配置

    Nginx engine x 是一个高性能的HTTP和反向代理web服务器 xff0c 同时也提供了IMAP POP3 SMTP服务 有着负载均衡 动静分离等强大的功能 xff0c 而且还有众多三方插件来满足应用要求 这里重点介绍nginx
  • 敏捷开发-互联网时代的软件开发方式

    一 什么是敏捷开发 敏捷开发简单的描述为 xff1a 是一种应对需求快速变化的软件开发方式 敏捷开发的核心思想就是小步快跑 不断迭代 xff0c 在一次次的迭代升级中完成 小目标 最终完成那个 大目标 正因为敏捷开发的这种不断迭代升级的开发
  • Window系统查看端口是否启用以及占用程序

    1 打开DOS命令行窗口 开始 gt 运行 gt cmd xff0c 或者是 window 43 R gt cmd xff0c 调出命令窗口 2 查看当前正在使用的所有端口 命令 xff1a netstat ao 包括协议 xff0c 端口
  • ThreadLocal的深度解读

    一 J2SE的原始描述 This class provides thread local variables These variables differ from their normal counterparts in that eac
  • 消息中间件如何保证消息不丢失

    一 消息队列MQ的三个阶段 1 生产者发送消息到MQ 2 MQ存储消息到内存或者硬盘 3 消费者消费消息 由于网络的原因 服务器的原因 程序的原因等等 xff0c 在每个阶段都有可能引起消息的丢失 xff1a 1 生产者发送消息到MQ xf
  • 32位系统为什么最大只支持4GB运存?

    首先要明白 1B 61 2 3b 1KB 61 2 10B 1MB 61 2 20B 1GB 61 2 30B 4GB 61 2 2 2 30B 61 2 32B b表示一个比特位 xff0c B表示一个字节 xff0c 一字节等于8个比特
  • 数据库和Spring事务隔离级别

    事务隔离级别 xff0c 指的是数据库多个并发事务操作共享数据时 xff0c 共享的数据对多个并发事务之间的可见性和影响程度 隔离的内容主要指数据方面 具体举例来说就是一个事务A读操作时 xff0c 其他并发事务修改操作事务A读的数据时 x
  • Java中各种锁的详细介绍(二):悲观锁和乐观锁

    Java中锁的类型多种多样 xff0c 有简单有复杂 xff0c 适合各种不同的应用场景 xff0c 接下来会分几章给大家详细介绍java中各种类型的锁 一 悲观锁和乐观锁的说明 1 悲观锁 Pessimistic Lock xff1a 对
  • Java中各种锁的详细介绍(三):自旋锁 VS 适应性自旋锁

    一 自旋锁 在介绍自旋锁前 xff0c 需要介绍一些前提知识来帮助大家更好的明白自旋锁的概念 阻塞或唤醒一个Java线程需要操作系统切换CPU状态来完成 xff0c 这种状态转换需要耗费处理器时间 如果同步代码块中的内容过于简单 xff0c
  • Java中各种锁的详细介绍(四):无锁|偏向锁|轻量级锁|重量级锁

    无锁 偏向锁 轻量级锁和重量级锁 xff0c 都是指锁的状态 xff0c 专门针对synchronized的 一 Synchronized如何实现线程同步 xff1f Java对象中有两个重要概念 xff1a Java对象头 和 Monit
  • A-star 算法原理分析

    搜索算法 图论中 xff0c 应用最广泛的就是搜索算法了 xff0c 比如 xff0c 深度优先搜索 广度优先搜索等 在介绍 Dijkstra 算法那篇中 xff0c 除了深度优先 广度优先这种暴力搜索算法 xff0c 还有一些最短路算法也
  • ROS物理仿真环境学习 gazebo + rviz【问题记录】

    Turtlebot3与仿真 仿真环境搭建 span class token comment 一个命令安装所有TurtleBot3依赖项 span span class token function sudo span span class
  • 机器人技术-HC-SR04超声波传感器数据及机器人避障的应用

    比较详细的HC SR04超声波传感器数据及机器人避障的应用方法 言 超声波传感器概述 超声波传感器型号繁多 价格从几元钱到几百元不等 主要用于检测距离 同时根据声速计算出物体的距离 但超声波传感器有四个缺点 1 声音速度易受温度和风向等环境
  • 自旋锁基本原理

    自旋锁基本原理 轻量级锁在加锁过程中 xff0c 用到了自旋锁 所谓自旋 xff0c 就是指当有另外一个线程来竞争锁时 xff0c 这个线 程会在原地循环等待 xff0c 而不是把该线程给阻塞 xff0c 直到那个 获得锁的线程释放锁之后
  • python获取视频帧率,总帧数,python ffmpeg获取视频信息ffmpeg.prob,python opencv获取视频信息cap.get(cv2.CAP_PROP_FRAME_WIDTH)

    文章目录 1 xff0c 效果2 xff0c ffmpeg获取视频信息2 xff0c opencv获取视频信息 1 xff0c 效果 2 xff0c ffmpeg获取视频信息 其中key xff1a streams 对应的值是一个list
  • 抓包教程(安卓抓包)Fiddler,HttpCancy使用~浅谈前几日抓包中遇到的坑

    安卓抓包 xff1a 0 直接设置手机wifi代理 xff0c 电脑fiddler抓包 xff08 可能有些抓不到 xff09 1 使用justtrustme这个xposed模块 43 virtual xposed 43 fiddler 可
  • multiple definition of `main'

    文章目录 1 目录结构2 报错内容3 cmake4 错误原因5 修改方案一5 修改方案二 1 目录结构 2 报错内容 3 cmake cmake minimum required span class token punctuation s
  • perf工具报错,升级ubuntu子系统linux内核

    文章目录 1 xff0c 运行perf工具报错1 1 xff0c 可能的原因有 xff1a 2 xff0c 我选择升级linux内核 xff0c 和当前perf工具版本保持一致2 1 xff0c 下载6 2 12内核源码2 2 xff0c
  • perf生成火焰图

    文章目录 1 xff0c top发现webserver进程空转情况下CPU占用高达200 2 xff0c 使用性能分析工具perf来进行分析2 1 xff0c 抓取采集样本2 2 xff0c 使用perf简单分析性能数据 3 xff0c 火
  • nohup运行程序竟然会使CPU飙到200%

    文章目录 1 xff0c 现象1 1 xff0c 直接运行程序CPU占用平均0 1 2 xff0c 使用nohup运行程序CPU占用平均200 2 xff0c 原因是 xff1a linux中nohup写操作与程序中读操作冲突引起cpu占用

随机推荐