官方提醒4 2023-03-18 14:11 采纳率: 68.2%
浏览 36
已结题

C#串口接收一段数据后,就停止接收了

我写的串口工具,发现在接收了一会数据后 就停止接收了 有人知道是什么原因引起的吗


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO.Ports;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;

namespace Ck
{

    public partial class Form1 : Form
    {
        string timeStr = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
        byte[] receiveBuffer = new byte[20];

        // 声明一个变量,用于记录已经接收的数据字节数
        int receivedBytes = 0;

        public Form1()
        {
            InitializeComponent();
        }
        private void Form1_Load_1(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)
        {
            string abc;
            // 检查是否允许跨线程调用控件,这里为了简化代码直接禁用了该功能
            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)
            {
                // 将接收到的数据转换为十六进制字符串
                string receivedString = BitConverter.ToString(receiveBuffer).Replace("-", " ");
                StreamWriter sw = new StreamWriter(@"C:\Users\guoxiaoru\Desktop\ACVB.txt", true);
                sw.WriteLine(receivedString, "\n");
                //对比第一字节数据
                if (receivedString.Substring(0,2)=="68") 
                {
                    //截取自己想要的数据
                    abc = receivedString.Substring(0,30);
                    // 将接收到的数据显示到文本框中 
                    textBox1.AppendText(abc + " ");
                    sw.WriteLine(abc, "\n");
                    receivedBytes = 0;
                    Array.Clear(receiveBuffer, 0, receiveBuffer.Length);
                }
            }
        }
    }
}

  • 写回答

3条回答 默认 最新

  • 追cium 2023-03-18 14:15
    关注

    参考GPT和自己的思路:

    根据你提供的代码,我看到你已经通过DataReceived事件来实现了串口接收功能。而你在串口接收数据时使用了一个缓冲区(byte[] receiveBuffer)来存储接收到的数据。你同时也已经定义了一个receivedBytes变量来记录已经接收的数据字节数。

    但是,我注意到仅在接收到所有数据后才进行处理,而在接收数据的过程中,你没有任何代码来确保如果接收到的数据小于缓冲区大小时仍然可以进行处理。这可能是导致你的问题原因之一。

    此外,你从接收缓冲区中读取数据时,你使用了serialPort1.Read方法,并指定了startIndex和count。但是,这个方法不是读取所有可用的数据,而是从缓冲区的指定索引开始仅读取指定数量的字节。也就是说,如果可用数据字节数大于你指定的count参数时,你只能读取一部分数据。因此,在此处你需要使用另一个方法serialPort1.ReadExisting()读取所有可用的数据。

    为了解决这个问题,你可以尝试使用以下代码替换你的DataReceived事件处理程序中的代码:

    private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        //导入数据的长度
        int bytesToRead = serialPort1.BytesToRead;
        //用于存储接收到的数据
        byte[] receiveBuffer = new byte[bytesToRead];
        //从串口读取数据
        serialPort1.Read(receiveBuffer, 0, bytesToRead);
        //将接收到的数据转换为字符串格式
        string receivedString = BitConverter.ToString(receiveBuffer).Replace("-", " ");
        //将字符串追加至文本框中
        textBox1.AppendText(receivedString + " ");
    }
    

    你可以根据你自己的需求将上面的代码修改为你自己的代码。

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

报告相同问题?

问题事件

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

悬赏问题

  • ¥15 docker部署Mongodb后输入命令报错?
  • ¥15 将下列流程图转变成python程序代码
  • ¥15 我需要全国每个城市的最新小区名字等数据。
  • ¥15 开发一个小区生态的小程序
  • ¥15 如何解决Excel中dependent dropdown list 的问题
  • ¥15 MddBootstrapInitialize2失败
  • ¥15 LCD Flicker
  • ¥15 esp32在micropython环境下使用ssl/tls连接mqtt服务器出现以下报错Connected on 192.168.154.223发生意外错误: 5无法连接到 MQTT 代理,如何解决?
  • ¥15 关于#genesiscsheel#的问题,如何解决?
  • ¥15 Android aidl for hal