C#读取多串口

新加监听标记,界面关闭时停止读取串口数据,防止异步数据展示报错
串口读取出错,在创建窗口句柄之前,不能在控件上调用 invoke 或 Beginimvoke

1.串口初始化

	SerialPort serialPort1 = new SerialPort();
	serialPort1.PortName = "COM1";
	serialPort1.BaudRate = 9600;
	serialPort1.Parity = Parity.None;
	serialPort1.StopBits = StopBits.One;
	serialPort1.DataBits = 8;
	serialPort1.Handshake = Handshake.None;
	SerialPort serialPort2 = new SerialPort();
	serialPort2.PortName = "COM2";
	serialPort2.BaudRate = 9600;
	serialPort2.Parity = Parity.None;
	serialPort2.StopBits = StopBits.One;
	serialPort2.DataBits = 8;
	serialPort2.Handshake = Handshake.None;

	//数据展示
    public delegate void Displaydelegate(string indata);
    public Displaydelegate disp_delegate= new Displaydelegate(DispUI);
    //新加监听标记
    public CancellationTokenSource cancellationTokenSource1 = new CancellationTokenSource();
    public CancellationTokenSource cancellationTokenSource2 = new CancellationTokenSource();

2.串口接收事件

通过异步多线程进行接收,不会导致界面卡顿

    Task.Run(() => {
	  serialPort1.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived);
	  serialPort2.DataReceived += new SerialDataReceivedEventHandler(serialPort2_DataReceived);
	                });

取数处理字符串的方式可能不太合理

	private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        try
        {
            if (serialPort1.IsOpen&&!cancellationTokenSource1.IsCancellationRequested)
            {
                Thread.Sleep(100);  //(毫秒)等待一定时间,确保数据的完整性  
                int len = serialPort1.BytesToRead;
                byte[] buff = new byte[len];
                serialPort1.Read(buff, 0, len);
                var alldata = Encoding.Default.GetString(buff);
                var indata = alldata;
                if (alldata.Contains("+") && alldata.Length - alldata.IndexOf('+') >= 7)
                {
                    indata = alldata.Substring(alldata.IndexOf('+') + 1, 6);//000304   +000628314  
                }
                if (alldata.Contains("-") && alldata.Length - alldata.IndexOf('-') >= 7)
                {
                    indata = alldata.Substring(alldata.IndexOf('-') + 1, 6);//   -00015031A
                    indata = "-" + indata;
                }
                if (!string.IsNullOrEmpty(indata) && indata.Length > 0)
                {
                    this.Invoke(disp_delegate, indata);
                }
            }
        }
        catch (Exception ex)
        {
            MsgBox.Information("串口1读取出错," + ex.Message);
            return;
        }
    }
	private void serialPort2_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        try
        {
            if (serialPort2.IsOpen&&!cancellationTokenSource2.IsCancellationRequested)
            {
                Thread.Sleep(100);  //(毫秒)等待一定时间,确保数据的完整性    
                int len = serialPort2.BytesToRead;
                 byte[] buff = new byte[len];
                 serialPort2.Read(buff, 0, len);
                 var alldata = Encoding.Default.GetString(buff);
                 var indata = alldata;
                 if (alldata.Contains("+") && alldata.Length - alldata.IndexOf('+') >= 8)
                 {
                     indata = alldata.Substring(alldata.IndexOf('+') + 1, 7);//000304   +000628314  
                 }
                 if (alldata.Contains("-") && alldata.Length - alldata.IndexOf('-') >= 8)
                 {
                     indata = alldata.Substring(alldata.IndexOf('-') + 1, 7);//   -00015031A
                     indata = "-" + indata;
                 }
                 if (!string.IsNullOrEmpty(indata) && indata.Length > 0)
                 {
                     this.Invoke(disp_delegate, indata);
                 } 
            }
        }
        catch (Exception ex)
        {
            MsgBox.Information("串口2读取出错," + ex.Message);
            return;
        }
    }

3.串口接收数据展示

    public void DispUI(string indata)
    {
         控件值=indata;
    }

4.界面关闭关闭串口

	try
	{
	    cancellationTokenSource1.Cancel(); // 取消监听任务
	    cancellationTokenSource2.Cancel(); // 取消监听任务
	    serialPort1.DiscardInBuffer(); // 清空输入缓冲区(可选)
	    serialPort2.DiscardInBuffer(); // 清空输入缓冲区(可选)
	    if (serialPort1 != null && serialPort1.IsOpen)
	    {//关闭串口
	        serialPort1.Close();
	    }
	    if (serialPort2 != null && serialPort2.IsOpen)
	    {//关闭串口
	        serialPort2.Close();
	    }
	}
	catch (Exception ex)
	{
	    MessageBox.Show(ex.Message);
	}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值