官方提醒4 2023-03-14 21:23 采纳率: 68.2%
浏览 32
已结题

C#中如何一帧一帧的接收数据

我自己写的一串口工具发现接收数据的时候都是一次接收了两包数据,用其他的串口工具发现可以区分开,我的代码中如何做到跟别人一样的效果
其他的串口工具

img


我自己写的串口工具

img

以下是我的代码,

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.IO.Ports;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Runtime.InteropServices.ComTypes;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.ToolBar;

namespace xiaoniu
{

    public partial class Form1 : Form
    {   // 声明一个byte数组,用于存储接收到的数据
        byte[] receiveBuffer = new byte[10];
        // 声明一个变量,用于记录已经接收的数据字节数
        int receivedBytes = 0;
        public string receivedString;
        public string hitchr = "68 20 DF 68 82 31 7A 69 78 64 64 7D 64 63 7A 69 78 64 64 86 64 63 80 7A 69 69 69 75 65 77 6B 65 67 63 69 68 69 67 33 7B 70 8D 34 33 56 33 33 33 33 3B 33 53 33 33 33 A8 16 \r\n";
        

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)   // 主窗口

        {
            //获取电脑当前可用串口并添加到选项列表中
            ComboBox1.Items.AddRange(System.IO.Ports.SerialPort.GetPortNames());
            SerialPort1.DataReceived += new SerialDataReceivedEventHandler(SerialPort1_DataReceived);
        }


        private void Button1_Click(object sender, EventArgs e)   //点击打开串口
        {
            
            try
            {
                if (SerialPort1.IsOpen)
                {
                    SerialPort1.Close();
                    Button1.Text = "点击打开串口";
                }
                else
                {
                    SerialPort1.PortName = ComboBox1.Text;
                    SerialPort1.Open();
                    Button1.Text = "点击关闭串口";
                }
            }
            catch (Exception ex)
            {
                //捕获可能发生的异常并进行处理

                //捕获到异常,创建一个新的对象,之前的不可以再用
                SerialPort1 = new System.IO.Ports.SerialPort();
                //刷新COM口选项
                ComboBox1.Items.Clear();
                ComboBox1.Items.AddRange(System.IO.Ports.SerialPort.GetPortNames());
                //响铃并显示异常给用户
                System.Media.SystemSounds.Beep.Play();
                Button1.Text = "打开串口";
                Button1.BackColor = Color.ForestGreen;
                MessageBox.Show(ex.Message);
            }
        }
        private void Button4_Click(object sender, EventArgs e)  //全选所有功能
        {
            RadioButton5.Checked = true;
            checkBox1.Checked = true;
            checkBox2.Checked = true;
        }
        private void SerialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)  //串口类
        {   // 检查是否允许跨线程调用控件,这里为了简化代码直接禁用了该功能
            CheckForIllegalCrossThreadCalls = false;
            // 读取所有可用字节数
            int bytesToRead = SerialPort1.BytesToRead;
            // 如果缓冲区大小不足以存储所有的字节,则扩展缓冲区
            if (receivedBytes + bytesToRead > receiveBuffer.Length)
            {
                Array.Resize(ref receiveBuffer, receivedBytes + bytesToRead);
            }

            // 将所有可用字节读取到缓冲区中
            SerialPort1.Read(receiveBuffer, receivedBytes, bytesToRead);

            // 更新已经接收的字节数
            receivedBytes += bytesToRead;
            // 如果已经接收到了所有数据,则进行处理
            if (receivedBytes == receiveBuffer.Length)
            {
                // 将接收到的数据转换为十六进制字符串
                receivedString = BitConverter.ToString(receiveBuffer).Replace("-", "");
                // 将接收到的数据显示到文本框中
                textBox1.AppendText(receivedString + " ");
                // 将接收到的数据写入到文件中

                using (StreamWriter sw = new StreamWriter(@"C:\Users\g'x'r\Desktop\jieshou.txt", true))
                {
                    string timeStr = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                    sw.Write(timeStr +" "+receivedString + "\n");
                }

                // 清空接收缓冲区和已接收的字节数
                receivedBytes = 0;
                Array.Clear(receiveBuffer, 0, receiveBuffer.Length);
            }
        }

  • 写回答

2条回答 默认 最新

  • 少林and叔叔 2023-03-14 22:09
    关注

    把接收区的缓存调小一点,receiveBuffer.Length这个参数变小一些。单个字节取数,然后判断两个字节之间时间,超过一定的时间,就判断是两帧。i

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 3月27日
  • 已采纳回答 3月19日
  • 创建了问题 3月14日

悬赏问题

  • ¥15 第一天重装配置python和opencv后第二天打开就成这样,瞎捣鼓搞出来文件夹还是没法联网
  • ¥20 Arduino 循迹小车程序电路出错故障求解
  • ¥20 Arduino 循迹小车程序电路出错故障求解
  • ¥100 AT89C52单片机C语言调试之后再回答
  • ¥15 AT89C52单片机C语言串口助手发送数据包返回值
  • ¥15 C++数组中找第二小的数字程序纠错
  • ¥50 MATLAB APP 制作出现问题
  • ¥15 wannier复现图像时berry曲率极值点与高对称点严重偏移
  • ¥15 利用决策森林为什么会出现这样·的问题(关键词-情感分析)
  • ¥15 DispatcherServlet.noHandlerFound No mapping found for HTTP request with URI[/untitled30_war_e