官方提醒4 2023-03-06 20:02 采纳率: 68.2%
浏览 105
已结题

C#串口接收数据不完整

串口接收数据的时候,textbox1 只显示了2位数据,在写入文件只写入了8位数据 我发送的68 20 DF 68 02 02 35 41 49 16 我希望显示我发送的所有数据

img

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.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
    {
        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 RadioButton5_CheckedChanged(object sender, EventArgs e)  //控制器类
        {
          
        }

        private void SerialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)  //串口类
        {
            CheckForIllegalCrossThreadCalls = false;
            byte ReceiveData;
            ReceiveData  =(byte)SerialPort1.ReadByte();    
            string  str = Convert.ToString(ReceiveData, 16).ToUpper();
            StreamWriter sw = new StreamWriter(@"C:\Users\g'x'r\Desktop\jieshou.txt", true);//写入文件夹
            textBox1.Text = str;
            sw.Write(str);
            sw.Close(); 
            
            
        }

    }
}




  • 写回答

4条回答 默认 最新

  • 「已注销」 2023-03-06 20:07
    关注

    参考GPT和自己的思路,您的代码存在一些问题,包括:

    只读取了一个字节的数据,因此无法读取完整的数据帧。

    在数据接收事件处理程序中,创建了一个StreamWriter对象,每次接收到一个字节的数据就将其写入文件,这将导致文件中包含不完整的数据,而且文件也无法关闭。

    下面是修改后的代码,注释中标明了修改的地方:

    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.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 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 SerialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)  //串口类
    {
        // 检查是否允许跨线程调用控件,这里为了简化代码直接禁用了该功能
        CheckForIllegalCrossThreadCalls = false;
    
        // 在接收到的数据中读取一个字节
        byte receivedByte = (byte)SerialPort1.ReadByte();
    
        // 将接收到的字节存储到缓冲区中
        receiveBuffer[receivedBytes] = receivedByte;
    
        // 记录已经接收的字节数
        receivedBytes++;
    
        // 判断是否已经接收完
        if (receivedBytes == receiveBuffer.Length)
        {
            // 将接收到的数据转换为十六进制字符串
            string receivedString = BitConverter.ToString(receiveBuffer);
    
            // 将接收到的数据显示到文本框中
            textBox1.AppendText(receivedString + " ");
    
            // 将接收到的数据写入到文件中
            using (StreamWriter sw = new StreamWriter(@"C:\Users\g'x'r\Desktop\jieshou.txt", true))
            {
                sw.Write(receivedString + " ");
            }
    
            // 清空接收缓冲区和已接收的字节数
            receivedBytes = 0;
            Array.Clear(receiveBuffer, 0, receiveBuffer.Length);
        }
    }
    

    在这段代码中,我们引入了一个接收缓冲区 receiveBuffer 和已接收的字节数 receivedBytes。每当串口接收到一个字节时,就将其存储到缓冲区中,并增加已接收的字节数。当已接收的字节数达到了缓冲区的长度时,就说明已经接收完了一个完整的数据包。接着,我们将接收到的数据转换为十六进制字符串,并显示在文本框中,同时将其写入到文件中。最后,我们清空接收缓冲区和已接收的字节数,以便接收下一个数据包。

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

报告相同问题?

问题事件

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

悬赏问题

  • ¥15 ansys fluent计算闪退
  • ¥15 有关wireshark抓包的问题
  • ¥15 Ubuntu20.04无法连接GitHub
  • ¥15 需要写计算过程,不要写代码,求解答,数据都在图上
  • ¥15 向数据表用newid方式插入GUID问题
  • ¥15 multisim电路设计
  • ¥20 用keil,写代码解决两个问题,用库函数
  • ¥50 ID中开关量采样信号通道、以及程序流程的设计
  • ¥15 U-Mamba/nnunetv2固定随机数种子
  • ¥30 C++行情软件的tick数据如何高效的合成K线