第七节:基于Winform框架的串口助手小项目---协议解析《C#编程》

介绍

目标

代码实现

        private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            if (isRxShow == false) return;
            // 1,需要读取有效的数据 BytesToRead
            byte[] dataTemp = new byte[serialPort1.BytesToRead];
            serialPort1.Read(dataTemp,0,dataTemp.Length);

            reciveBuffer.AddRange(dataTemp);

            reciveCount += dataTemp.Length;

            this.Invoke(new EventHandler(delegate
            {
                // 显示接收数据的长度
                recivecount_tssl.Text = reciveCount.ToString();
                if (startData_chb.Checked == false)
                {
                    if (!recivehex_chb.Checked)
                    {
                        // 2, 编码格式的选择
                        string str = Encoding.GetEncoding("gb2312").GetString(dataTemp);
                        // 3,0x00 -> \0 结束 不会显示
                        str = str.Replace("\0", "\\0");

                        recive_rtb.AppendText(str);

                        // recive_rtb.AppendText(Encoding.GetEncoding("gb2312").GetString(dataTemp).Replace("\0", "\\0"));
                    }
                    else
                    {
                        //  十六进制是选中的状态下
                        recive_rtb.AppendText(Transform.ToHexString(dataTemp, " "));
                    }
                }
                else
                {
                    // 解析数据 queue

                    foreach (byte item in dataTemp)
                    {
                        // 入列
                        bufferQueue.Enqueue(item);
                    }

                    // 解析获取帧头
                    if (isHeadRecive == false)
                    {

                        foreach (byte item in bufferQueue.ToArray())
                        {
                            if (item != 0x7f)
                            {
                                // 出列
                                bufferQueue.Dequeue();
                                Console.WriteLine("not 0x7f, Dequeue !!");
                            }
                            else
                            {
                                // get 0x7f from bufferQueue
                                isHeadRecive = true;
                                Console.WriteLine("0x7f is recived !!");
                                break;
                            }
                        }
                    }

                    if (isHeadRecive == true)
                    {
                        // 判断有数据帧长度
                        if (bufferQueue.Count >= 2)
                        {
                            Console.WriteLine(DateTime.Now.ToLongTimeString());
                            Console.WriteLine($"show the data in bufferQueue{Transform.ToHexString(bufferQueue.ToArray())}");
                            Console.WriteLine($"frame lenth ={String.Format("{0:X2}", bufferQueue.ToArray()[1])}");
                            frameLenth = bufferQueue.ToArray()[1];
                            // 一帧完整的数据长度判断,不代表数据是正确的
                            if(bufferQueue.Count>=1+1+frameLenth+2)
                            {
                                byte[] frameBuffer = new byte[1 + 1 + frameLenth + 2];
                                Array.Copy(bufferQueue.ToArray(), 0, frameBuffer, 0, frameBuffer.Length);
                                if(crc_chech(frameBuffer))
                                {
                                    Console.WriteLine("frame is check ok,pick it");
                                    data_txb.Text = Transform.ToHexString(frameBuffer);
                                    data1_txb.Text = String.Format("{0:X2}", frameBuffer[2]);
                                    data2_txb.Text = String.Format("{0:X2}", frameBuffer[3]);
                                    data3_txb.Text = String.Format("{0:X2}", frameBuffer[4]);
                                    data4_txb.Text = String.Format("{0:X2}", frameBuffer[5]);

                                }
                                else
                                {
                                    // 无效数据
                                    Console.WriteLine("bad frame, drop it");
                                    
                                }


                                for(int i=0; i<1 + 1+frameLenth+2;i++)
                                {
                                    bufferQueue.Dequeue();
                                }

                                isHeadRecive = false;
                            }
                        }
                        //接续接收数据
                    }
                }
            }));
        }
   private bool crc_chech(byte[] frameBuffer)
   {
       /*大端模式: 是指数据的高字节保存在内存的低地址中,
        * 而数据的低字节保存在内存的高地址中,这样的存储
        * 模式有点儿类似于把数据当作字符串顺序处理:地址
        * 由小向大增加,而数据从高位往低位放;这和我们的
        * 阅读习惯一致。
        * 
        * 小端模式: 是指数据的高字节保存在内存的高地址中,
        * 而数据的低字节保存在内存的低地址中,这种存储模
        * 式将地址的高低和数据位权有效地结合起来,高地址
        * 部分权值高,低地址部分权值低。
        */
       bool ret = false;

       byte[] temp = new byte[frameBuffer.Length-2];
       Array.Copy(frameBuffer, 0, temp, 0, temp.Length);
       byte[] crcdata = DataCheck.DataCrc16_Ccitt(temp, DataCheck.BigOrLittle.BigEndian);
       if (crcdata[0] == frameBuffer[frameBuffer.Length - 2] &&
           crcdata[1]== frameBuffer[frameBuffer.Length-1])
       {
           // check ok
           ret = true;
       }

       return ret;

   }

效果展示

待续》》》》》

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

关于tresos Studio(EB)的MCAL配置之GPT

概念 GPT&#xff0c;全称General Purpose Timer&#xff0c;就是个通用定时器&#xff0c;取的名字奇怪了点。定时器是一定要的&#xff0c;要么提供给BSW去使用&#xff0c;要么提供给OS去使用。 配置 General GptDeinitApi控制接口Gpt_DeInit是否启用 GptEnableDisable…

C语言基础要素(011):增量、减量运算

让变量自身加一或减一是一种常用的运算&#xff0c;C语言提供了增量与减量运算符支持这些操作。 增量运算() 让变量自身加1&#xff0c;可以这样实现&#xff1a; int size 3; size size 1; // 语句执行后 size 值为 4 size 1; // 语句执行后 size 值为 5使…

深入探索WebGL:解锁网页3D图形的无限可能

深入探索WebGL&#xff1a;解锁网页3D图形的无限可能 引言 。WebGL&#xff0c;作为这一变革中的重要技术&#xff0c;正以其强大的功能和广泛的应用前景&#xff0c;吸引着越来越多的开发者和设计师的关注。本文将深入剖析WebGL的核心原理、关键技术、实践应用&#xff0c;并…

Python +Anaconda,DeepSeeK API入门小例子

一、环境搭建 1.安装pycharm 、anaconda&#xff0c;deepseek官网申请api key(不会的去百度&#xff0c;申请完了可以充值几块钱&#xff0c;现在官网应该没有免费token可以测试了) 2.anaconda创建虚拟环境 &#xff0c;打开windows dos界面依次输入 命令&#xff1a;1) con…

股指期货的交易时间是几点到几点?

股指期货是一种金融衍生品&#xff0c;简单来说&#xff0c;就是以股票指数&#xff08;比如沪深300指数&#xff09;为标的的期货合约。投资者可以通过买卖这些合约来对冲风险或者投机。它的交易方式和股票有点像&#xff0c;但又有自己的特点。 股指期货的交易时间是什么时候…

推流项目的ffmpeg配置和流程重点总结一下

ffmpeg的初始化配置&#xff0c;在合成工作都是根据这个ffmpeg的配置来做的&#xff0c;是和成ts流还是flv&#xff0c;是推动远端还是保存到本地&#xff0c; FFmpeg 的核心数据结构&#xff0c;负责协调编码、封装和写入操作。它相当于推流的“总指挥”。 先来看一下ffmpeg的…

数字电子技术基础(二十四)——TTL门电路的高、低电平的输出特性曲线

目录 1 TTL门电路的特性曲线 1.1 高电平输出特性 1.1.2 高电平输出特性的实验过程 1.1.2 TTL门电路的输出特性的实验结果 1.2 低电平的输出特性 1 TTL门电路的特性曲线 1.1 高电平输出特性 1.1.2 高电平输出特性的实验过程 现在想要测试TTL门电路的输出特性&#xff0c…

盛铂科技SCP4000射频微波功率计与SPP5000系列脉冲峰值 USB功率计 区别

在射频&#xff08;RF&#xff09;和微波测试领域&#xff0c;快速、精准的功率测量是确保通信系统、雷达、卫星设备等高性能运行的核心需求。无论是连续波&#xff08;CW&#xff09;信号的稳定性测试&#xff0c;还是脉冲信号的瞬态功率分析&#xff0c;工程师都需要轻量化、…

GCC RISCV 后端 -- cc1 入口

GCC编译工具链中的 gcc 可执行程序&#xff0c;实际上是个驱动程序&#xff08;Driver&#xff09;&#xff0c;其根据输入的参数&#xff0c;然后调用其它不同的程序&#xff0c;对输入文件进行处理&#xff0c;包括编译、链接等。可以通过以下命令查看&#xff1a; gcc -v h…

C++第二十讲:C++11

C第二十讲&#xff1a;C11 1.列表初始化1.1C98时的{}初始化1.2C11的新规{}初始化1.3initializer_list初始化 2.右值引用和移动语义2.1右值引用2.1.1左值和右值2.1.2左值引用和右值引用2.1.3引用延长声明周期2.1.4左值和右值的参数匹配 2.2右值引用和移动语义的使用2.2.1移动构造…

Finebi_求组内占比和组内累计占比

需求&#xff1a;原始数据结构如下&#xff0c;要求各每个月的各产品销量占比&#xff0c;至每月的各产品销量累计占比 实现步骤&#xff1a; ①维度拖入日期&#xff0c;按年月分组 ②各产品销量占比DEF(SUM_AGG(${&#xfeff;产品销量表&#xfeff;_&#xfeff;销量&…

PE文件结构详解(DOS头/NT头/节表/导入表)使用010 Editor手动解析notepad++.exe的PE结构

一&#xff1a;DOS部分 DOS部分分为DOS MZ文件头和DOS块&#xff0c;其中DOS MZ头实际是一个64位的IMAGE_DOS——HEADER结构体。 DOS MZ头部结构体的内容如下&#xff0c;我们所需要关注的是前面两个字节&#xff08;e_magic&#xff09;和后面四个字节&#xff08;e_lfanew&a…

自由学习记录(41)

代理服务器的核心功能是在客户端&#xff08;用户设备&#xff09;和目标服务器&#xff08;网站/资源服务器&#xff09;之间充当“中介”&#xff0c;具体过程如下&#xff1a; 代理服务器的工作流程 当客户端希望访问某个网站&#xff08;比如 example.com&#xff09;时&…

学习工具的一天之(burp)

第一呢一定是先下载 【Java环境】&#xff1a;Java Downloads | Oracle 下来是burp的下载 Download Burp Suite Community Edition - PortSwigger 【下载方法二】关注的一个博主 【BurpSuite 安装激活使用详细上手教程 web安全测试工具】https://www.bilibili.com/video/BV…

大模型gpt结合drawio绘制流程图

draw下载地址 根据不同操作系统选择不同的安装 截图给gpt 并让他生成drawio格式的&#xff0c;选上推理 在本地将生成的内容保存为xml格式 使用drawio打开 保存的xml文件 只能说效果一般。

K8S学习之基础六:k8s中pod亲和性

Pod节点亲和性和反亲和性 podaffinity&#xff1a;pod节点亲和性指的是pod会被调度到更趋近与哪个pod或哪类pod。 podunaffinity&#xff1a;pod节点反亲和性指的是pod会被调度到远离哪个pod或哪类pod 1. Pod节点亲和性 requiredDuringSchedulingIgnoredDuringExecution&am…

FPGA学习篇——Verilog学习4

1.1 结构语句 结构语句主要是initial语句和always语句&#xff0c;initial 语句它在模块中只执行一次&#xff0c;而always语句则不断重复执行&#xff0c;以下是一个比较好解释的图: (图片来源于知乎博主罗成&#xff0c;画的很好很直观&#xff01;) 1.1.1 initial语句 ini…

[Computer Vision]图像分割技术

一、技术介绍 1.1 GrabCut 算法 1.1.1 算法原理 GrabCut 算法是一种交互式的图像分割方法,整体流程围绕着用户提供的少量先验信息(如用矩形框大致框选前景区域等),通过构建图模型、拟合高斯混合模型,利用图割算法不断迭代优化,实现了一种有效的交互式图像分割,最终将…

原型链与继承

#搞懂还是得自己动手# 原型链 function Person(name) { this.name name; } Person.prototype.sayName function() { console.log(this.name); };const p new Person("Alice"); 原型链关系图&#xff1a; 原型链&#xff1a;person->Person.prototype->O…

MagicDriveDiT:具有自适应控制的自动驾驶高分辨率长视频生成

24年11月来自香港中文大学、香港科技大学和华为公司的论文“MagicDriveDiT: High-Resolution Long Video Generation for Autonomous Driving with Adaptive Control”。 扩散模型的快速进步极大地改善视频合成&#xff0c;特别是可控视频生成&#xff0c;这对于自动驾驶等应用…