C#winform上位机开发学习笔记6-串口助手的断帧功能添加

1.功能描述

按照设定时间对接收数据进行断帧(换行)

应用于需要接收完整数据包的场景,例如下位机发送一包数据为1秒,每100ms发送一组数据

大部分用于接收十六进制数据时

2.代码部分

步骤1:添加计时器,设置默认时间为500ms

步骤2:去掉断帧复选框默认使能

步骤3:设置断帧复选框时间集合

步骤4:开启HEX接收数据选择框时

cs 复制代码
//当开启HEX接收时事件
        private void checkBox16_CheckedChanged(object sender, EventArgs e)
        {
            //启动与禁用断帧功能
            if (checkBox16.Checked == true)
            {
                comboBox16.Enabled = true;//使能断帧时间复选框
                //设定定时参数
                timer4.Interval = Convert.ToUInt16(comboBox16.Text, 10);
                //启动定时器4
                timer4.Start();
            }
            else
            {
                comboBox16.Enabled = false;
                //停止定时器4
                timer4.Stop();
            }
        }

步骤5:编写定时器事件

定义局部变量声明

cs 复制代码
//断帧定时器事件
        private void timer4_Tick(object sender, EventArgs e)
        {
            Timer4_Flag = true;//置位定时器4标志位
        }

步骤6:串口接收事件中添加代码

cs 复制代码
                    //断帧功能
                    if (Timer4_Flag == true)
                    {
                        Timer4_Flag = false;

                        textBox1.AppendText("\r\n");
                        textBox1.AppendText("[" + DateTime.Now.ToString("HH:mm:ss") + "]" + "->");
                    }

步骤7:断帧复选时间设置

cs 复制代码
//断帧复选框事件_选择断帧时间
        private void comboBox16_SelectedIndexChanged(object sender, EventArgs e)
        {
            //设定定时参数
            //将组合框中的数据转换为整型赋值给定时器参数
            timer4.Interval = Convert.ToUInt16(comboBox16.Text, 10);
        }

3.完整代码

cs 复制代码
        //用于串口通讯断帧
        bool Timer4_Flag = false;

//串口接收事件
        private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            //接收格式为ASCII码
            if (!checkBox16.Checked)//复用框没有被选择时
            {
                try
                {
                    textBox1.AppendText("[" + DateTime.Now.ToString("HH:mm:ss") + "]" + "->");

                    string str = serialPort1.ReadExisting();//将接收到的数据存在自定义的字符串变量中
                    textBox1.AppendText(str + "\r\n");

                    //统计接收字节数
                    UInt32 RBytes = Convert.ToUInt32(textBox7.Text, 10);//定义接收字节数变量,并初始化为已接收字节数
                    RBytes += (UInt32)str.Length;//加ASCII码字节数
                    textBox7.Text = Convert.ToString(RBytes, 10);//显示总接收字节数
                }
                catch
                {
                    textBox1.AppendText("[" + DateTime.Now.ToString("HH:mm:ss") + "]" + "->");
                    textBox1.AppendText("ASCII格式接收错误!\r\n");
                }
            }
            //接收格式为HEX
            else
            {
                try
                {
                    //断帧功能
                    if (Timer4_Flag == true)
                    {
                        Timer4_Flag = false;

                        textBox1.AppendText("\r\n");
                        textBox1.AppendText("[" + DateTime.Now.ToString("HH:mm:ss") + "]" + "->");
                    }

                    //textBox1.AppendText("[" + DateTime.Now.ToString("HH:mm:ss") + "]" + "->"); //此处被断帧功能替代换行

                    byte[] data = new byte[serialPort1.BytesToRead];//定义接收缓冲区,长度为串口接收的数据长度
                    serialPort1.Read(data, 0, data.Length);//形参,起始位置,终止位置,将读取的数据存放在缓冲区

                    //遍历用法
                    foreach (byte Member in data)//循环函数
                    {
                        string str = Convert.ToString(Member, 16).ToUpper();//转化为十六进制大写
                        textBox1.AppendText((str.Length == 1 ? "0" + str : str) + " ");//数据+空格""
                    }
                    //textBox1.AppendText("\r\n"); //此处被断帧功能替代换行

                    //统计接收字节数
                    UInt32 RBytes = Convert.ToUInt32(textBox7.Text, 10);//定义接收字节数变量,并初始化为已接收字节数
                    RBytes += (UInt32)data.Length;//加HEX字节数
                    textBox7.Text = Convert.ToString(RBytes, 10);//显示总接收字节数

                }
                catch
                {
                    textBox1.AppendText("[" + DateTime.Now.ToString("HH:mm:ss") + "]" + "->");
                    textBox1.AppendText("HEX格式接收错误!\r\n");
                }
            }
        }

//当开启HEX接收时事件
        private void checkBox16_CheckedChanged(object sender, EventArgs e)
        {
            //启动与禁用断帧功能
            if (checkBox16.Checked == true)
            {
                comboBox16.Enabled = true;//使能断帧时间复选框
                //设定定时参数
                timer4.Interval = Convert.ToUInt16(comboBox16.Text, 10);
                //启动定时器4
                timer4.Start();
            }
            else
            {
                comboBox16.Enabled = false;
                //停止定时器4
                timer4.Stop();
            }
        }
//断帧定时器事件
        private void timer4_Tick(object sender, EventArgs e)
        {
            Timer4_Flag = true;//置位定时器4标志位
        }
//断帧复选框事件_选择断帧时间
        private void comboBox16_SelectedIndexChanged(object sender, EventArgs e)
        {
            //设定定时参数
            //将组合框中的数据转换为整型赋值给定时器参数
            timer4.Interval = Convert.ToUInt16(comboBox16.Text, 10);
        }
    }

4.测试结果

当下位机为500m定时发送,上位机设置断帧为500ms断帧时,接收的十六进制数据为500ms一帧数据,当设置上位机断帧时间为1s时,接收的十六进制一帧数据为下位机发送的两帧数据。

参考自B站硬件家园

相关推荐
何事误红尘4 小时前
全志A40i学习笔记():开发资料、启用串口
学习
虎王物联4 小时前
物联网协议网关设计:多协议融合与数据转换的工程实战
物联网·嵌入式·esp32
for_ever_love__4 小时前
python基础语法学习: 异常的传递性
开发语言·python·学习
PC2005-cloud5 小时前
DeepSeek Harness 创建 skill 指南:结构、安装、使用
笔记·学习
YM52e5 小时前
分页查询的基石:ArkTS 为鸿蒙商品列表设计 LIMIT/OFFSET 的表
android·学习·华为·harmonyos
math_hongfan5 小时前
主从嵌套层次分明:ArkUI 订单卡片内嵌明细的鸿蒙界面
学习·华为·harmonyos
库玛西6 小时前
现代 C++ 智能指针全景指南:从 RAII 思想到工业级实践
c语言·开发语言·c++·笔记·面试
还不秃顶的计科生7 小时前
具身智能论文学习8:Octo: An Open-Source Generalist Robot Policy
人工智能·深度学习·学习·机器学习·语言模型·vla·vlm
woshihuanglaoshi7 小时前
事务加持防超卖:ArkTS 在鸿蒙里玩转 TRANSACTION 出入库
学习·华为·harmonyos
世人万千丶8 小时前
去重插入与超限淘汰:ArkTS 实现鸿蒙搜索历史的 LIMIT 艺术
运维·服务器·学习·华为·harmonyos·鸿蒙