shmilyshushu 2019-01-03 20:22 采纳率: 66.7%
浏览 633
已结题

C#,用串口读缓存文件时只读了一小部分,没有读完整。求大佬帮忙。

如题,原文件很大,50多万个字符吧。不知道是不是太大影响的
以下是代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Ports;
namespace 串口实验2
{
public partial class Form1 : Form
{
string s = "";
string ss = "";
string[] s_1;
int i=0;
SerialPort serialPort1 = new SerialPort("COM2", 9600, Parity.None, 8, StopBits.One); //初始化串口设置

public delegate void Displaydelegate(byte[] InputBuf);

   // Byte[] OutputBuf = new Byte[128];
    public Displaydelegate disp_delegate;
    public Form1()
    {
        disp_delegate = new Displaydelegate(DispUI);
        serialPort1.DataReceived += new SerialDataReceivedEventHandler(Comm_DataReceived);
        InitializeComponent();
        this.BackgroundImage = Image.FromFile(@"C:\Users\hasee\Desktop\plane.jpg");
    }

    private void Form1_Load(object sender, EventArgs e)
    {

    }

    private void button1_Click(object sender, EventArgs e)
    {
        try
        {
            if (button1.Text == "打开")
            {
                serialPort1.Open();

                button1.Text = "关闭";
            }
            else
            {
                serialPort1.Close();
                button1.Text = "打开";
            }

        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message, "错误提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
            return;
        }
    }
    void Comm_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {

        int count = serialPort1.BytesToRead;
        Byte[] InputBuf = new Byte[count];

        try
        {
            serialPort1.Read(InputBuf, 0, serialPort1.BytesToRead);                                //读取缓冲区的数据直到“}”即0x7D为结束符  
            System.Threading.Thread.Sleep(50);
            this.Invoke(disp_delegate, InputBuf);

        }
        catch (TimeoutException ex)         //超时处理  
        {
            MessageBox.Show(ex.ToString());
        }
    }

    public void DispUI(byte[] InputBuf)
    {

        ASCIIEncoding encoding = new ASCIIEncoding();   
        s= encoding.GetString(InputBuf);
        ss = s.Replace(@"\r\nNNNN", "a");
        s_1=ss.Split(new char[] { 'a' });
       // TextBox1.Text = ss;// encoding.GetString(InputBuf);
    }

    private void timer1_Tick(object sender, EventArgs e)
    {
        //TextBox1.Text = s_1[i];
         TextBox1.Text = s_1.Length.ToString();
         i = i + 1;
    }

    private void button2_Click(object sender, EventArgs e)
    {
          timer1.Enabled = true;
         timer1.Interval = 10;

    }


}

}

  • 写回答

1条回答

  • 幻泪风痕 2019-01-05 18:44
    关注

    串口读取文件线程更具设置读取2进制数据,或字符串格式数据。你的程序有点乱也没有注释。
    读取时还需要注意编程欢迎使用的时宽字节还是单字节。
    读取一次可以根据需要设置缓存大小,通常设置512或1024等。
    发送时更具你设置的缓存大小拆分文件或者字符串。一次发一部分。
    接收到再重新拼接起来。
    通常文字或信息可以一次传输完成。
    如你时指文字信息接收只有一半的话应该是你是用的环境是 Unicode 字符集。

    //接收数据线程
    UINT ThreadRecv(LPVOID lparam)
    {
        C串口通信助手Dlg* pWnd = (C串口通信助手Dlg*)lparam;
    
        VARIANT variant;                //Variant 是一种特殊的数据类型,除了定长String数据及用户定义类型外,可以包含任何种类的数据。
        COleSafeArray safearray;
        LONG len = 0, k = 0;
        BYTE rxdata[2048] = { 0 };        //字节数组,用来接收数据
        CString s;
        static int iRecvBytes = 0;
        if (pWnd->m_cmsCom.get_CommEvent() == 2) //事件值为2表示接收缓冲区内有字符     
        {
            //可以根据自己定义的通信协议,修改代码
            variant = pWnd->m_cmsCom.get_Input();                   //读缓冲区  
            safearray = variant;                            //VARIANT型变量转换为ColeSafeArray型变量
            len = safearray.GetOneDimSize();                //得到有效数据长度        
            for (k = 0;k < len;k++)
                safearray.GetElement(&k, rxdata + k);       //转换为BYTE型数组         
            for (k = 0;k < len;k++)                         //将数组转换为Cstring型变量    
            {
                BYTE bt = *(char*)(rxdata + k); //字符型      
                s.Format(_T("%c"), bt);
                pWnd->m_recvEdit += s;              //显示到接收窗口中
                ++iRecvBytes;
                pWnd->m_iRecvBytes = iRecvBytes;
            }
        }
    
        pWnd->SetDlgItemText(IDC_EDIT_RECV, pWnd->m_recvEdit);
    
        return 0;
    }
    
    评论

报告相同问题?

悬赏问题

  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!
  • ¥15 drone 推送镜像时候 purge: true 推送完毕后没有删除对应的镜像,手动拷贝到服务器执行结果正确在样才能让指令自动执行成功删除对应镜像,如何解决?