[Ooonly新人贴]记录工作中遇到的问题,话不多说先上干货

问题:类似K线与蓝牙接收部门模块,要求由原来的接收串口中断改为DMA接收。据说要用到空闲中断与DMA中断,但是经仿真发现DMA每完成传输一个数据(比如1BYTE)就会进入空闲中断(k线发现这种情况),考虑到这样进入中断的频率和以前串口接收中断的频率差不多,所以放弃此方案,听说有的DMA具有超时中断机制(具体有没有我也没考证),但是我手上的板子经过研读芯片手册发现只有传输一半中断,传输完成中断,传输越界错误中断,所以也没法用此方案。

网上有很多理解DMA接收机制的帖子,这里我就不在赘述,我个人认为其中最要紧的就是判断接收数据长度的问题因为配置DMA的传输数据量大多都是接收缓存区的最大值,对于不定长数据无法预测什么时间传输结束。

话不多说先上干货(拙见)


一、配置DMA接收函数

这里具体根据对应的芯片手册写出需要的DMA接收函数,并在K线或者蓝牙初始化模块时调用此函数

(注意点: 在函数内使能DMA中断,但是不要使能对应串口DMA接收通道。使能对应串口DMA接收通道可以在对应串口初始化时自行按需调用)

二、初始化串口函数

在此处取消使能串口接收中断(视具体情况而定,蓝牙可以在开始接收时再取消),并在此调用DMA接收函数进行初始化配置,并使能DMA通道(视具体情况而定)。

三、定时器检查串口函数

此处为实时操作系统中定时器中断里的一个检查串口状态的函数,在此处加入衔尾法。

uint8_t now, last, before;

	//+++//  10个字节的数据逐个赋值循环检查DMA通道余量
if(num >= 10)
{
num = 0;
}
RecRem[num++]=Get_Transfer_Number_Remain ();
if(num >= 3)
{
now = num - 1;
last = num - 2;
before = num - 3;
}
else if(num == 2)
{
now = 1;
last = 0;
before = 9;
}
else if(num == 1)
{
now = 0;
last = 9;
before = 8;
}
else if(num == 0)
{
now = 9;
last = 8;
before = 7;
} if((RecRem[now] == RecRem[last]) && (RecRem[now] != MAXBUFFSIZE) )//这样下来处理时就像每次盯着循环数组什么时候露出一个尾巴处理一样,一旦数组中连着两个余量相等了就表示DMA传输结束(也可以三个数据一样,这就是before的作用,这里我只用了两个),可以开始处理数据了
{
Channel_Enable(); //DMA通道FALSE
Reclen = MAXBUFFSIZE - Get_Transfer_Number_Remain ();//获取本次DMA传输帧长
Address_Config ();//重新配置传输地址(还是原来的地址,这里需要把通道余量充满)
Transfer_Number_Config (MAXBUFFSIZE);//配置传输数量
Channel_Enable(); //DMA通道TRUE
USARTBusy = 0;//所有原接收中断里需要处理的串口状态位都要在这里变更
}

总结

此方法的大概思路就是在串口开始接收数据之前开启DMA传输并关闭接收中断,并在串口检查函数里加入检查通道余量的内容,如果通道余量两次(或者三次)相等并且不等于最大值,那么就判断接收结束,此时关闭DMA通道获取此次传输帧长,重新配置DMA传输地址和通道余量,再打开DMA通道(一般如果不重新使能DMA通道,只配置是没有效果的,这个要看具体的芯片),处理串口状态位。

这就是全部内容啦,在遇到问题时我除了请教前辈之外还在网上查询了相关的资料,虽然关于如何DMA接收发送的方法有很多但是都很笼统,具体实现比较困难,这里是我自己想出的不用中断的方法(像k线可以直接取消接收中断,蓝牙串口也可以用但是蓝牙一般需要保留接收中断用以初始化配对,除此之外可以把关于具体指令内容的传输全改为DMA),可能网上也有只是我没有找到,也可能我这样方法是有一些问题的,希望各位大佬可以指导一下。

需要转载请告诉我一下让我高兴高兴哈哈哈~

衔尾法解决当无法使用空闲中断以及DMA中断时配置DMA接收串口不定长数据的更多相关文章

  1. STM32 HAL库使用中断实现串口接收不定长数据

    以前用DMA实现接收不定长数据,DMA的方法接收串口助手的数据,全部没问题,不过如果接收模块返回的数据,而这些数据如果包含回车换行的话就会停止接收,例如接收:AT\r\nOK\r\n,就只能接收到AT ...

  2. 串口配合DMA接收不定长数据(空闲中断+DMA接收)-(转载)

    1.空闲中断和别的接收完成(一个字节)中断,发送完成(发送寄存器控)中断的一样是串口中断: 2.空闲中断是接收到一个数据以后,接收停顿超过一字节时间  认为桢收完,总线空闲中断是在检测到在接收数据后, ...

  3. 串口1配合DMA接收不定长数据(空闲中断+DMA接收)

    1.空闲中断和别的接收完成(一个字节)中断,发送完成(发送寄存器控)中断的一样是串口中断: 2.空闲中断是接收到一个数据以后,接收停顿超过一字节时间  认为桢收完,总线空闲中断是在检测到在接收数据后, ...

  4. 串口通信DMA中断

    这是以前学32的时候写的,那时候学了32之后感觉32真是太强大了,比51强的没影.关于dma网上有许多的资料,亲们搜搜,这里只贴代码了,其实我也想详详细细地叙述一番,但是自己本身打字就慢,还有好多事情 ...

  5. Stm32使用串口空闲中断,基于队列来接收不定长、不定时数据

    串口持续地接收不定长.不定时的数据,把每一帧数据缓存下来且灵活地利用内存空间,下面提供一种方式供参考.原理是利用串口空闲中断和DMA,每当对方发来一帧完整的数据后,串口接收开始空闲,触发中断,在中断处 ...

  6. 拉链法解决Hash节点冲突问题

    <?php /* * hash::拉链法解决hash节点存储冲突问题 * ::2014-07-02 * ::Small_Kind */ class small_hash { private $s ...

  7. 链表法解决hash冲突

    /* @链表法解决hash冲突 * 大单元数组,小单元链表 */ #pragma once #include <string> using namespace std; template& ...

  8. JS保留小数 去尾法 进一法 四舍五入法

    //toFixed 四舍五入遇到坑. 1.235.toFixed(2) = 1.23 1.2350001.toFixed(2) = 1.24 //去尾法 Number.prototype.toFloo ...

  9. Python基于回溯法解决01背包问题实例

    Python基于回溯法解决01背包问题实例 这篇文章主要介绍了Python基于回溯法解决01背包问题,结合实例形式分析了Python回溯法采用深度优先策略搜索解决01背包问题的相关操作技巧,需要的朋友 ...

  10. 拉链法解决hashtable冲突问题

    拉链法解决冲突.拉链法解决冲突的做法是将所有的相同Hash值的key放在一个链表中,比如key3和key14在hash之后都是0,那么在数组的键为0的地方存储这两个值,形式是链表.如果不能理解我的文字 ...

随机推荐

  1. 看我如何用定值 Cookie 实现反爬

    摘要:本次案例,用定值Cookie实现反爬. 本文分享自华为云社区<我是怎么用一个特殊Cookie,限制住别人的爬虫的>,作者: 梦想橡皮擦 . Cookie 生成 由于本案例需要用到一个 ...

  2. 在 Vue 中控制表单输入

    Vue中v-model的思路很简单.定义一个可响应式的text(通常是一个ref),然后用v-model="text"将这个值绑定到一个input上.这就创造了一个双向的数据流: ...

  3. 第一推动|2023年VSCode插件最新推荐(54款)

    本文介绍前端开发领域常用的一些VSCode插件,插件是VSCode最重要的组成部分之一,本文列出了我自己在以往工作经验中积累的54款插件,个人觉得这些插件是有用或有趣的,根据它们的作用,我粗略的把它们 ...

  4. SpringBoot中如何实现业务校验,这种方式才叫优雅!

    大家好,我是飘渺. 在日常的接口开发中,为了保证接口的稳定安全,我们一般需要在接口逻辑中处理两种校验: 参数校验 业务规则校验 首先我们先看看参数校验. 参数校验 参数校验很好理解,比如登录的时候需要 ...

  5. 电商AARRR模型分析(二)—R语言

    AARRR模型可以说是用户运营和业务增长非常重要的模型.模型以用户的生命周期为核心,把增长步骤拆分为5个步骤,分别是:获取用户(Acquisition).用户激活(Activiation).用户留存( ...

  6. 系统建模之UML用例视图

    <用例视图> 1 用例图的目标 who「参与者」:确定谁要使用系统 what「功能」:他们使用系统做什么? 2 用例图-四大主要组件 2.1 参与者 参与者:与应用程序或系统进行交互的用户 ...

  7. [Web服务容器/Apache Tomcat]WINDOWS系统下:一台机器部署多个[解压版]Tomcat

    以windows为例. 1 思路 1.1 前置条件 已成功配置JDK (JAVA_HOME / Path) 控制面板>所有控制面板项>系统>高级系统设置>系统变量(S): JA ...

  8. 基于SqlSugar的开发框架循序渐进介绍(26)-- 实现本地上传、FTP上传、阿里云OSS上传三者合一处理

    在前面介绍的随笔<基于SqlSugar的开发框架循序渐进介绍(7)-- 在文件上传模块中采用选项模式[Options]处理常规上传和FTP文件上传>中介绍过在文件上传处理的过程中,整合了本 ...

  9. LeeCode 318周赛复盘

    T1: 对数组执行操作 思路:模拟 public int[] applyOperations(int[] nums) { int n = nums.length; for (int i = 0; i ...

  10. Go语言实现基于HTTP的内存缓存服务

    所有的缓存数据都存储在服务器的内存中,因此重启服务器会导致数据丢失,基于HTTP通信会将使开发变得简单,但性能不会太好 缓存服务接口 本程序采用REST接口,支持设置(Set).获取(Get)和删除( ...