帮做软件测试的网站/免费建立网站步骤

帮做软件测试的网站,免费建立网站步骤,网站建设的关键点,万年网站建设导言 《[[STM32F103_LL库寄存器学习笔记09 - DMA串口接收与DMA串口发送,串口接收空闲中断]]》上一章节完成DMA发送与接收。此时,有一个致命的问题可能会导致数据包丢失。原因是USART1接收只开启了接收空闲中断(IDLE),DMA在连续模式下&#xf…

导言


《[[STM32F103_LL库+寄存器学习笔记09 - DMA串口接收与DMA串口发送,串口接收空闲中断]]》上一章节完成DMA发送与接收。此时,有一个致命的问题可能会导致数据包丢失。原因是USART1接收只开启了接收空闲中断(IDLE),DMA在连续模式下,如果数据一直持续发送(或者数据包的大小比接收缓存区要大),将会出现数据被覆盖,被覆盖的数据等于丢失的数据。

实现更加健壮的串口接收程序是同时利用USART空闲中断来判断数据包的结束,并配合DMA半传输和传输完成中断及时处理数据,从而避免数据溢出或被覆盖。 总的来说就是接收空闲中断 + DMA传输过半中断 + DMA传输完成中断。
方案如下:

  1. 开启接收空闲中断
    • 当数据传输过程中出现空闲(即一段数据传输结束后总线静默),USART空闲中断就会触发。这时,立即关闭DMA,读取DMA剩余计数器(或利用缓冲区总大小减去剩余计数得到实际接收字节数),将这部分数据交给上层处理,然后清除中断标志并重新启动DMA。这样即使数据包不足一个完整缓冲区,也能准确提取数据。
  2. 开启半传输和全传输中断
    • 半传输中断:当DMA接收到缓冲区前半部分的数据时触发。此时可以先处理前半部分的数据,避免数据不断写入后覆盖还未处理的数据。
    • 传输完成中断:当DMA完成整个缓冲区的数据接收时触发,同样可处理后半部分数据。这种“双缓冲”技术允许你在数据接收的同时就将已接收部分取出处理,降低丢包风险。

总的来说:

  • 对于连续且数据量较大的情况,DMA半传输和传输完成中断能保证数据能及时被轮换处理,不会因缓冲区满而丢失数据。
  • 对于数据量较小或者数据传输间有间隔的情况,空闲中断能够准确捕获数据包结束时刻,防止因数据不足而不触发DMA半/全传输中断而导致数据滞留。

另外,中断的处理必须保证简单,尽可能保证快进快出。 所以,数据的处理必须留在主循环来做(配合高效的数据结构ringbuffer)。后续章节会介绍ringbuffer的移植与使用。
在这里插入图片描述
以115200波特率计算(假设每字节约10位,即包括起始、数据、停止位),理论上每秒可以传输约11520字节,也就是每毫秒大约11.5个字节。512个字节大概需要44~46毫秒填满。当然,这个值会依据具体的帧配置(比如数据位、停止位、校验位)略有不同。所以,如果数据量很大(一直连续)当触发传输过半中断时,要在大概44ms内把数据搬运出去,否则会被覆盖。
在这里插入图片描述
效果如下所示:
在这里插入图片描述
项目地址:https://github.com/q164129345/MCU_Develop/tree/main/stm32f103_ll_library10_usart_dma_rx_interrupt

一、代码(LL库)


1.1、main.c

在这里插入图片描述
在这里插入图片描述

1.2、usart.c

在这里插入图片描述

1.3、stm32f1xx_it.c

在这里插入图片描述
在这里插入图片描述

1.4、编译、下载

在这里插入图片描述
如上所示,编译通过。
在这里插入图片描述
效果如上所示,大量发送数据包,不丢包!

二、调试传输过半中断与传输完成中断


调试传输过半中断与传输完成中断之前,先被USART1的接收空闲中断关闭掉,从而方便你单独调试这两个中断。如下所示:
在这里插入图片描述

2.1、传输过半中断

在这里插入图片描述
如上所示,从串口助手发送512个字节到STM32F103,触发了DMA1通道5的传输过半中断。从寄存器表格看到,HTIF5确认被置1了。
在这里插入图片描述
如上所示,代码LL_DMA_ClearFlag_HT5(DMA1)运行完,HTIF5标志位确实被清0了。
在这里插入图片描述
如上所示,串口助手发送512个字节给STM32F103,让它触发DMA1通道5的传输过半中断。在中断里将前半段512个字节让DMA1通道4回传给电脑的串口助手。数据传输数量寄存器CNDTR5从0x400(1024)变成0x200(512),写指针指向接收缓存区的偏移512。从整个过程看来,传输过半中断程序调试OK。

2.2、传输完成中断

在这里插入图片描述
如上所示,串口助手再一次发送512个字节给STM32F103后,进入传输完成中断。此时,TCIF5被置1。
在这里插入图片描述
如上所示,代码LL_DMA_ClearFlag_TC5(DMA1)运行之后,TCIF5标志被清0。
在这里插入图片描述
如上所示,将断点放开后,STM32F103将第二次收到的512个字节回传给电脑的串口助手。此时,寄存器CNDTR5从0x200(512)变回最开始的0x400(1024)。从整个过程看来,传输完成中断正常!

三、寄存器梳理


3.1、启动传输过半中断、传输完成中断

在这里插入图片描述
在这里插入图片描述
如上所示,寄存器DMA_CCR5的位2与位1置1就可以打开半传输中断与传输完成中断。

// 增加传输完成与传输过半中断
DMA1_Channel5->CCR |= (1UL << 1);             // 传输完成中断 (TCIE)
DMA1_Channel5->CCR |= (1UL << 2);             // 传输过半中断 (HTIE)

3.2、全局中断DMA1_Channel5_IRQHandler()里判断传输过半标志与传输完成标志

在这里插入图片描述
在这里插入图片描述

void DMA1_Channel5_IRQHandler(void) {// 半传输中断if (DMA1->ISR & (1UL << 18)) {DMA1->IFCR |= (1UL << 18); // 清除标志}// 传输完成中断if (DMA1->ISR & (1UL << 17)) {DMA1->IFCR |= (1UL << 17); // 清除标志}// 改为if...else if,中断运行的时间更短
}

如上所示,通过寄存器ISR判断是否进入该中断,接着使用寄存器IFCR来清除中断标志位。

四、代码(寄存器)


4.1、main.c

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4.2、stm32f1xx_it.c

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4.3、编译、下载

在这里插入图片描述

4.4、串口助手调试

在这里插入图片描述
如上所示,效果跟LL库一样。

五、细节补充


5.1、当接收缓存区大小1024bytes,刚好收到一帧大小512bytes数据时,会怎样???

当接收缓存区大小1024bytes,刚好收到一帧大小512bytes数据时,将会进入传输过半中断,然后再进入接收空闲中断。 然后,传输过半中断与接收空闲中断都有将接收缓存区复制到发送缓存区的功能,会复制两遍数据给发送缓存区吗?代码处理好了,不会! 以下是接收空闲中断里的某部分代码。

// 根据剩余字节判断当前正在哪个半区
// 还有,避免当数据长度刚好512字节与1024字节时,传输过半中断与空闲中断复制两遍数据,与传输完成中断与空闲中断复制两遍数据。
if (remaining > (RX_BUFFER_SIZE/2)) {// 还在接收前半区:接收数据量 = (1K - remaining),但肯定不足 512 字节count = RX_BUFFER_SIZE - remaining;if (count != 0) { // 避免与传输完成中断冲突,多复制一次memcpy((void*)tx_buffer, (const void*)rx_buffer, count);}
} else {// 前半区已写满,当前在后半区:后半区接收数据量 = (RX_BUFFER_SIZE/2 - remaining)count = (RX_BUFFER_SIZE/2) - remaining;if (count != 0) { // 避免与传输过半中断冲突,多复制一次memcpy((void*)tx_buffer, (const void*)(rx_buffer + RX_BUFFER_SIZE/2), count);}
}
if (count != 0) {recvd_length = count;rx_complete = 1;
}

假设RX_BUFFER_SIZE为1024,当串口助手发送512个字节时,DMA剩余计数remaining正好为512。此时remaining不大于512,所以进入else分支,计算得到count = (1024/2) - 512 = 512 - 512 = 0。因此不会再复制数据,也就避免了重复拷贝前半段数据。

当接收缓存区大小1024bytes,刚好收到一帧大小1024bytes数据时,发生顺序大致如下:

  1. 当接收到前512字节时,DMA触发半传输中断,此时会调用对应中断服务程序,将前半区(偏移0~511)的数据复制到发送缓冲区,并设置接收完成标志。
  2. 当接收到后512字节时,DMA触发传输完成中断,同样将后半区(偏移512~1023)的数据复制到发送缓冲区(注意,如果使用同一个tx_buffer,则需要根据应用需求处理两次复制的数据是合并还是分别处理)。
  3. 如果此时串口没有继续接收数据,USART1空闲中断也可能触发。此时,在空闲中断处理代码中,会先禁用DMA,然后通过下面这段代码来计算“新增”的数据长度:
// 禁用 DMA1 通道5,防止数据继续写入
LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_5);
uint16_t remaining = LL_DMA_GetDataLength(DMA1, LL_DMA_CHANNEL_5); // 获取剩余的容量
uint16_t count = 0;
// 根据剩余字节判断当前正在哪个半区
// 还有,避免当数据长度刚好512字节与1024字节时,传输过半中断与空闲中断复制两遍数据,与传输完成中断与空闲中断复制两遍数据。
if (remaining > (RX_BUFFER_SIZE/2)) {// 还在接收前半区:接收数据量 = (1K - remaining),但肯定不足 512 字节count = RX_BUFFER_SIZE - remaining;if (count != 0) { // 避免与传输完成中断冲突,多复制一次memcpy((void*)tx_buffer, (const void*)rx_buffer, count);}
} else {// 前半区已写满,当前在后半区:后半区接收数据量 = (RX_BUFFER_SIZE/2 - remaining)count = (RX_BUFFER_SIZE/2) - remaining;if (count != 0) { // 避免与传输过半中断冲突,多复制一次memcpy((void*)tx_buffer, (const void*)(rx_buffer + RX_BUFFER_SIZE/2), count);}
}
if (count != 0) {recvd_length = count;rx_complete = 1;
}
// 重新设置 DMA 传输长度并使能 DMA
LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_5, RX_BUFFER_SIZE);
LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_5);

对于1024字节的情况,DMA工作在循环模式下,当完整数据传输完成后,DMA的计数器会重新加载为 RX_BUFFER_SIZE(即1024),因此当空闲中断进入处理时:

  • remaining 将等于1024,
  • 如果进入第一个分支,则计算得到 count = RX_BUFFER_SIZE - remaining = 1024 - 1024 = 0,
  • 如果进入第二个分支(一般不会出现,因为remaining不小于512),同样结果为0。
    因此,空闲中断处理代码不会再复制数据,也不会重复处理前半区数据。总结来说,当刚好发送1024字节时:
  • 半传输中断处理了前512字节,
  • 传输完成中断处理了后512字节,
  • 空闲中断因计算出的新接收字节数为0而不再进行复制。
    这就避免了数据重复拷贝的问题!

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

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

相关文章

李宏毅机器学习笔记06 | 鱼和熊掌可以兼得的机器学习 - 内容接宝可梦

本章提要 深度学习可以在较少参数量的情况下得到比较低的loss&#xff1a; h a l l a r g min ⁡ h ∈ H L ( h , D a l l ) h^{all}arg \min_{h \in H}L(h,D_{all}) hallargminh∈H​L(h,Dall​) 引入 如何权衡模型的复杂程度 Tradeoff of Model Complexity 理论上&#…

海康gdb流程

gdb相关 在initrun.sh文件里加入&#xff0c;注意需要在hikauto起来之前 # 设置core dump大小 ulimit -c unlimited if [ $? -eq 0 ];then echo "core dump size set success" else echo -e "\33[31m core dump size set fail\33[0m" fi echo …

springBoot统一响应类型3.3版本

前言&#xff1a; 通过实践而发现真理&#xff0c;又通过实践而证实真理和发展真理。从感性认识而能动地发展到理性认识&#xff0c;又从理性认识而能动地指导革命实践&#xff0c;改造主观世界和客观世界。实践、认识、再实践、再认识&#xff0c;这种形式&#xff0c;循环往…

基于Linux下的MyBash命令解释器

项目介绍&#xff1a;⼀个⽤C语⾔实现的简单shell&#xff0c;可以接受⽤⼾输⼊的命令并执⾏操作&#xff0c;⽀持多管道和重 定向。 mybash---打造自己的命令解释器 目前我们Linux的系统默认的命令解释器是bash; 命令解释器&#xff08;也称为命令行解释器或shell&#xff0…

Ingredient-oriented Multi-Degradation Learning for Image Restoration论文阅读

摘要&#xff1a;重点在于关联多个任务本质的联系。 不同恢复任务的关联性很重要。 揭示退化现象的内在机理联系很有意义。 多合一的方法能在单一模型中处理多种退化问题&#xff0c;可扩展性较差。 成分导向范式挖掘不同图像退化现象背后的物理规律或特征模式。 成分导向退化重…

禅道后台命令执行漏洞

漏洞简介 禅道是第一款国产的开源项目管理软件。它集产品管理、项目管理、质量管理、文档管理、 组织管理和事务管理于一体&#xff0c;是一款专业的研发项目管理软件&#xff0c;完整地覆盖了项目管理的核心流程。 禅道管理思想注重实效&#xff0c;功能完备丰富&#xff0c;…

密码学——知识问答

目录 1、阐述公开密钥算法的定义&#xff0c;结合RSA算法说明公钥密码的基本要求。 说明公钥与私钥两种密码学并举例与其应用 1. 公钥密码学&#xff08;非对称加密&#xff09;&#xff1a; 2. 私钥密码学&#xff08;对称加密&#xff09;&#xff1a; 对比公钥与私钥密码…

海思烧录工具HITool电视盒子刷机详解

HiTool是华为开发的一款用于海思芯片设备的刷机和调试工具&#xff0c;可对搭载海思芯片的机顶盒、智能电视等设备进行固件烧录、参数配置等操作。以下为你详细介绍&#xff1a; 功能用途 固件烧录&#xff1a;这是HiTool最主要的功能之一。它能够将下载好的适配固件文件烧录到…

软考中级-软件设计师 23种设计模式(内含详细解析)

23种设计模式 &#x1f3af; 创建型设计模式&#x1f4cc; 抽象工厂&#xff08;Abstract Factory&#xff09; 设计模式&#x1f4cc; 工厂方法&#xff08;Factory Method&#xff09;设计模式&#x1f4cc; 单例&#xff08;Singleton&#xff09;设计模式&#x1f4cc; 生成…

软考笔记5——软件工程基础知识

第五章节——软件工程基础知识 软件工程基础知识 第五章节——软件工程基础知识一、软件工程概述1. 计算机软件2. 软件工程基本原理3. 软件生命周期4. 软件过程 二、软件过程模型1. 瀑布模型2. 增量模型3. 演化模型&#xff08;原型模型、螺旋模型)4. 喷泉模型5. 基于构建的开发…

Git入门——常用指令汇总

以下是一份精心整理的 Git常用指令速查表&#xff0c;基本覆盖日常开发使用场景&#xff0c;建议收藏备用&#x1f447; &#x1f527; 环境配置 指令作用git config --global user.name "你的名字"设置全局用户名git config --global user.email "你的邮箱&qu…

常见中间件漏洞攻略-Jboss篇

一、CVE-2015-7501-Jboss JMXInvokerServlet 反序列化漏洞 第一步&#xff1a;开启靶场 第二步&#xff1a;访问该接口&#xff0c;发现直接下载&#xff0c;说明接⼝开放&#xff0c;此接⼝存在反序列化漏洞 http://47.103.81.25:8080/invoker/JMXInvokerServlet 第三步&…

播放本地视频-实现视频画廊功能

实现一个视频画廊&#xff0c;播放本地视频 可以切换不同视频的功能 文章目录 需求&#xff1a;场景实现方案遇到的坑播放器选择界面显示不全视频友好显示问题缓存 总结 需求&#xff1a; 实现一个视频画廊&#xff0c;播放本地视频 可以切换不同视频的功能 场景 图片画廊的…

从零构建大语言模型全栈开发指南:第二部分:模型架构设计与实现-2.2.2文本生成逻辑:Top-k采样与温度控制

👉 点击关注不迷路 👉 点击关注不迷路 👉 点击关注不迷路 文章大纲 2.2.2 文本生成逻辑:Top-k采样与温度控制1. 文本生成的核心挑战与数学框架1.1 自回归生成的基本流程2. `Top-k`采样原理与工程实现2.1 数学定义与算法流程2.2 PyTorch实现优化3. 温度控制的数学本质与参…

01 相机标定与相机模型介绍

学完本文,您将了解不同相机模型分类、内参意义,及对应的应用代码模型 标定的意义 建模三维世界点投影到二维图像平面的过程。标定输出的是相机模型。 相机模型 相机模型可以解理解为投影模型 +

Stereolabs ZED Box Mini:机器人与自动化领域的人工智能视觉新选择

在人工智能视觉技术快速发展的今天&#xff0c;其应用场景正在持续拓宽&#xff0c;从智能安防到工业自动化&#xff0c;从机器人技术到智能交通&#xff0c;各领域都在积极探索如何利用这一先进技术。而 Stereolabs 推出的ZED Box Mini&#xff0c;正是一款专为满足这些多样化…

K8S学习之基础五十九:部署gitlab服务

部署gitlab docker pull gitlab/gitlab-ce:latest docker tag gitlab/gitlab-ce:latest 172.16.80.140/gitlab/gitlab-ce:latest docker push 172.16.80.140/gitlab/gitlab-ce:latest docker run -d -p 443:443 -p 80:80 -p 222:22 --name gitlab --restart always -v /home/…

多线程 --- 多线程编程

在写代码的时候&#xff0c;可以使用多进程进行并发编程&#xff08;在Java中&#xff0c;不太推荐&#xff0c;很多很多关于进程相关的API&#xff0c;在Java标准库中&#xff0c;都没有提供&#xff09;&#xff0c;也可以使用多线程进行并发编程&#xff08;系统提供了多线程…

vue中上传接口file表单提交二进制文件流

1.使用elementui上传组件 要做一个选择文件后&#xff0c;先不上传&#xff0c;等最后点击确定后&#xff0c;把file二进制流及附加参数一起提交上去。 首先使用elementui中的上传组件&#xff0c;设置auto-uploadfalse&#xff0c;也就是选择文件后不立刻上传。 <el-uplo…

C++ map容器总结

map基本概念 简介&#xff1a; map中所有元素都是pair pair中第一个元素为key&#xff08;键值&#xff09;&#xff0c;起到索引作用&#xff0c;第二个元素为value&#xff08;实值&#xff09; 所有元素都会根据元素的键值自动排序 本质&#xff1a; map/multimap属于关…