串口环形收发原理及实现

一、环形收发队列构建
1、构造环形收发数组及其长度
#define buff_size 10
Unsigned char buff[buff_size];
2、定义环形收发读/写位置
u16 R_Buff;
u16 W_Buff;
3、结构体封装

typedef struct Qbuff
{u16 write;             //写位置u16 read;              //读位置u8  buff[buff_size];   //环形缓冲收发数组
}CircularBuff;   

二、案例
假设环形收发数组长度为8。W/R分贝为实际的读写位置,Size为实际存储的数据的长度。
1、写入4个数据,则Write=4; Read=0; Size=4;
在这里插入图片描述
2、读取3个数据,则Write=4; Read=3; Size=4-3=1;
在这里插入图片描述
4、写入7个数据,则Write=(4+7)=11; Read=3; Size=1+7=8;
数组会先写后四个数据,写满后,再从头开些写到第3位置,(4+7)%8=3
在这里插入图片描述
此时,写数据长度Write-读数据长度Read=11-3=8,环形收发数组满了。
5、读取8个数据,则Write=11; Read=3+8=11; Size=11-11=0
在这里插入图片描述
此时,写数据长度Write=读数据长度Read=11,环形收发数组为空。
三、代码
“.h文件”

#define buff_size 500      //环形缓冲队列的容量  	
typedef struct Qbuff
{u16 write;             //写位置u16 read;              //读位置u8  buff[buff_size];   //环形缓冲收发数组
}CircularBuff;   

“.c文件”

1、首先来实现队列
void init_buff(void)       //初始化队列
{Cbuff.write=0;Cbuff.read=0;memset(Cbuff.buff,0,buff_size);
}u8 write_buff(u8 wdata)     //入队
{if(((Cbuff.write-Cbuff.read)==buff_size))  //如果写位置减去读位置等于队列长度,就说明这个环形队列已经满{return 0;}Cbuff.buff[Cbuff.write%buff_size]=wdata;              //将数据放入环形队列 Cbuff.write=Cbuff.write+1;     //环形队列位置+1,如果超过了队列长度则回到队列头return 1;
}u8 read_buff(u8 *rdata)    //出队
{if(Cbuff.read==Cbuff.write)                //如果写位置和读的位置相等,就说明这个环形队列为空,则从头开始重新存{init_buff();return 0;}*rdata=Cbuff.buff[Cbuff.read%buff_size];Cbuff.read=Cbuff.read+1;return 1;
}
2、主循环做数据出队与数据包拆分
void move_data(void)
{int i=0;u16 size1,size2,size3;         //记录三包数据的切分位置u16 len1,len2,len3;            //记录三包数据的长度u8 CrcBuff1[100],CrcBuff2[100],CrcBuff3[100];               //CRC切分好的数据包if(ok_flag)                    //连续10ms没有接收到数据,ok_flag置1{	ok_flag=Cbuff.write;       //将接收到的数据长度赋值给ok_flagfor(i=0;i<ok_flag;i++)     //循环读取所有数据{if(read_buff(&data))   //缓冲非空,若有3个数据包{BuffHandle[i]=data;                }          } for(i=0;i<ok_flag;i++)     //数据包切分,最大三包数据{if((BuffHandle[i-2]==0xF0)&&(BuffHandle[i-1]==0x10)) //判断数据头0xF0 0x10{size1=i-2;                                      //记录切分位置len1=BuffHandle[i];                             //记录数据包长度memcpy(CrcBuff1,BuffHandle+size1,len1);         //获取切分好的数据包}if((BuffHandle[i-2]==0xF0)&&(BuffHandle[i-1]==0x0F)) //判断数据头0xF0 0x0F{size2=i-2;                                      //记录切分位置len2=BuffHandle[i];                             //记录数据包长度     memcpy(CrcBuff2,BuffHandle+size2,len2);         //获取切分好的数据包}	if((BuffHandle[i-2]==0xF0)&&(BuffHandle[i-1]==0x0F)) //判断数据头0xF0 0x0F{size3=i-2;                                      //记录切分位置len3=BuffHandle[i];                             //记录数据包长度memcpy(CrcBuff3,BuffHandle+size3,len3);         //获取切分好的数据包        }}}
}
3、串口接收中断入队
void USART1_IRQHandler(void)
{if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断{	USART_ClearITPendingBit(USART1,USART_IT_RXNE); //清除标志位write_buff(USART_ReceiveData(USART1));//读取接收到的数据}
}

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

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

相关文章

Zabbix自定义飞书webhook告警媒介1

说明&#xff1a;此配置仅适用于7版本及以上&#xff0c;低版本可能有问题 JavaScript 内容如下&#xff1a; try {var sourceData JSON.parse(value),req new HttpRequest(),response;if (sourceData.HTTPProxy) {req.setProxy(sourceData.HTTPProxy);}req.addHeader(Conte…

pytorch中的transpose用法

注意&#xff1a;维数从0开始&#xff0c;0维 1维2维…,负数代表从右往左数&#xff0c;-1代表第一维&#xff0c;以此类推 import torch import numpy as np# 创建一个二维数组 arr torch.tensor([[[1, 2],[3, 4]],[[5, 6],[7, 8]]]) print("原始数组&#xff1a;"…

Docker部署.NET6项目

Docker的三大核心概念 1、docker仓库&#xff08;repository&#xff09; docker仓库&#xff08;repository&#xff09;类似于代码库&#xff0c;是docker集中存放镜像的场所。实际上&#xff0c;注册服务器是存放仓库的地方&#xff0c;其上往往存放着很多仓库。每个仓库集…

案例058:基于微信小程序的智能社区服务系统

文末获取源码 开发语言&#xff1a;Java 框架&#xff1a;SSM JDK版本&#xff1a;JDK1.8 数据库&#xff1a;mysql 5.7 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.5.4 小程序框架&#xff1a;uniapp 小程序开发软件&#xff1a;HBuilder X 小程序…

操作符(原码反码补码)

目录 前言&#xff1a; 原反补码&#xff1a; 位操作符&#xff1a; &#xff06; &#xff5c; &#xff3e; &#xff5e; >> << 总结&#xff1a; 逻辑操作符 && || 其他操作符&#xff1a; sizeof -- () &#xff1f;&#xf…

AMEYA360--罗姆与Quanmatic公司利用量子技术优化制造工序并完成验证

全球知名半导体制造商罗姆(总部位于日本京都市)于2023年1月起与 Quanmatic Inc.(总部位于日本东京都新宿区&#xff0c;以下简称“Quanmatic”)展开合作&#xff0c;在半导体制造工序之一的EDS工序中测试并引入量子技术&#xff0c;以优化制造工序中的组合。目前&#xff0c;双…

C#excel导入dategridview并保存到数据库/dategridview增加一行或几行一键保存数据库

excel导入到dategridview显示并保存到数据库 dategridview增加一行或几行一键保存数据库 ExcelHelper类(这个要导入NPOI包) using NPOI.HSSF.UserModel; using NPOI.SS.UserModel; using NPOI.XSSF.UserModel; using System; using System.Collections.Generic; using Syste…

dtaidistance笔记:dtw_ndim (高维时间序列之间的DTW)

1 数据 第一个维度是sequence的index&#xff0c;每一行是多个元素&#xff08;表示这一时刻的record&#xff09; from dtaidistance.dtw_ndim import *s1 np.array([[0, 0],[0, 1],[2, 1],[0, 1],[0, 0]], dtypenp.double) s2 np.array([[0, 0],[2, 1],[0, 1],[0, .5],[0…

Elasticsearch--解决磁盘使用率超过警戒水位线

原文网址&#xff1a;Elasticsearch--解决磁盘使用率超过警戒水位线_IT利刃出鞘的博客-CSDN博客 简介 本文介绍如何解决ES磁盘使用率超过警戒水位线的问题。 问题描述 当客户端向 Elasticsearch 写入文档时候报错&#xff1a; cluster_block_exception [FORBIDDEN/12/inde…

Qt进程和线程

一、进程 在设计一个应用程序时,有时不希望将一个不太相关的功能集成到程序中,或者是因为该功能与当前设计的应用程序联系不大,或者是因为该功能已经可以使用现成的程序很好的实现了,这时就可以在当前的应用程序中调用外部的程序来实现该功能,这就会使用到进程。Qt应用程序…

亿胜盈科 HT4182,HT4186,HT4188 电量均衡 同步升压型 双节理电池充电器

HT4182&#xff0c;HT4186&#xff0c;HT4188是一款5V输入&#xff0c;升压模式的充电管理IC&#xff0c;适用于双节串联鲤电池。其能自适应任意5V电源进行充电&#xff0c;并且由输入过压、欠压保护。 HT4182&#xff0c;HT4186&#xff0c;HT4188采用同步升压结构&#xff0…

基于单片机出租车计价器控制系统

**单片机设计介绍&#xff0c;基于单片机出租车计价器控制系统 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机的出租车计价器控制系统是一个用于控制和管理出租车费用计算的电子设备。下面是一个简单的系统设计介绍&…

Windows 下 PyTorch 入门深度学习环境安装与配置 GPU 版

1.确定自己的硬件信息&#xff0c;确定电脑有英伟达 (NVIDIA)显卡 在任务栏上右键打开任务管理器 2.下载安装 Anaconda &#xff08;建议安装迅雷下载&#xff0c;同时浏览器添加扩展 “迅雷Chrome支持”&#xff09; https://www.anaconda.com/ https://repo.anaconda.com/arc…

文本编辑软件:Ulysses mac介绍说明

Ulysses mac是面向 Mac、iPhone 和 iPad 的一站式写作环境。Ulysses 提供令人愉悦、专注的写作体验&#xff0c;加上高效文稿管理、无缝同步以及灵活导出。markdown 可以直接对于文本进行不同类型的分类、编辑&#xff0c;比如标题、注解、评论之类的内容。 Ulysses让注意力专…

嵌入式学习---ARM中断控制系统

目录 外部事件与CPU的交互方式查询方式中断方式 什么是中断源S3C2440支持60个中断源FIQ和IRQ 中断处理流程将外设中断通知给CPUSUBSRCPND寄存器INTSUBMSK寄存器SRCPND寄存器INTMSK寄存器INTMOD寄存器INTPND寄存器 硬件中断处理是实时系统设计的最重要、最关键的问题。 外部事件…

Linux shell编程学习笔记33:type 命令

目录 0 引言1 type 命令的功能和格式 1.1 type命令的功能1.2 type 命令的格式2 type命令用法实例 2.1用type命令查看shell内置命令&#xff08;以echo命令为例&#xff09;2.2 用type命令查看别名&#xff08;以ls命令为例&#xff09;2.3 用type命令同时查看shell内置命令和别…

抽象类和接口(超重点!!)

[本节目标] 1.抽象类 2.接口 3.Object类 1.抽象类 1.1 抽象类概念 在面向对象的概念中&#xff0c;所有的对象都是通过类来描绘的&#xff0c;但是反过来&#xff0c;并不是所有的类都是用来描绘对象的&#xff0c;如果一个类中没有包含足够的信息来描绘一个具体的对象&a…

LabVIEW发开发电状态监测系统

LabVIEW发开发电状态监测系统 对发电设备的持续监测对于确保可靠的电力供应至消费者极为重要。它不仅能够及时提醒操作员注意发电设备的潜在损坏&#xff0c;还能减少由于设备故障造成的停机时间。为了达到这一目标&#xff0c;开发了一款基于LabVIEW的软件&#xff0c;专门用…

C语言进阶之路之内存镜像与字符操作函数篇

目录 一、学习目标&#xff1a; 二、内存镜像 什么是进程 C进程内存布局 栈内存 静态数据 数据段&#xff08;存储静态数据&#xff09;与代码段 堆内存 三、字符操作函数 函数strstr 函数strlen strlen与sizeof的区别 函数strtok 函数strcat与strncat 函数strc…

string类:`reserve()`,`resize()`详解

string类的重要接口说明(1)&#xff1a;reserve()&#xff0c;resize() 一、reserve() 和 resize() 注意不要把 reserve(储备) 和 reverse(逆向) 搞混了&#xff01; 1.1 reserve()&#xff1a;用于为字符串预留空间&#xff08;扩容&#xff09;&#xff0c;以便后续操作可以…