精华内容
下载资源
问答
  • 怎么做才能更加高效呢?
  • 在C#中使用串口接收数据时发现,在完整的接收完一次数据后,还会再次进入串口接收事件。 在网上搜索资料发现其他开发者也有遇到该问题: [1] c#串口事件接受一次数据莫名其妙会触发两次 原文链接:...

    在C#中使用串口接收数据时发现,在完整的接收完一次数据后,还会再次进入串口接收事件。

    在网上搜索资料发现其他开发者也有遇到该问题:

    [1]  c#串口事件接受一次数据莫名其妙会触发两次   原文链接:https://www.52pojie.cn/thread-1009851-1-1.html

    [2]Serial Port object's DataReceived Event firing twice   原文链接:https://stackoverflow.com/questions/30296199/serial-port-objects-datareceived-event-firing-twice

    其中[2]提到:串口接收事件触发2次是正常的,第1次是有数据接收,第2次收到的是EOF标志,直接忽略掉第2次就好了。

    在串口接收事件开头加入该部分判断后如下:

    private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
    {
    	//接收到EOF则直接退出
    	if (e.EventType == System.IO.Ports.SerialData.Eof)
    	{
    		return;	
    	}
    	
    	...
    }

    在串口接收事件的if语句处设置断点进行调试,第一次进入时:e.EventType 为System.IO.Ports.SerialData.Chars,串口缓冲区有3个字节需读取。

    第2次进入时:e.EventType 仍为System.IO.Ports.SerialData.Chars,串口缓冲区有0个字节需读取。

    通过程序调试可知:程序第2次进入串口接收事件并不是因为接收到EOF标志即System.IO.Ports.SerialData.Eof,而是接收到System.IO.Ports.SerialData.Chars,但接收到的字节长度为0。

    因此,通过加入if (e.EventType == System.IO.Ports.SerialData.Eof) return;的方式并不可行。既然可以保证在第1次进串口接收事件就将数据接收完毕,且第2次进入串口接收事件的数据长度为0。则可通过判断接收字节长度为0就直接退出的方式忽略掉第2次进入的串口接收事件。

    添加判断后的代码如下所示:经验证该方法可行,可以忽略掉第2次进入串口接收事件。具体导致进入第2次串口接收事件的原因还不明确,需继续探究!

    private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
    {
    	//if (e.EventType == System.IO.Ports.SerialData.Eof)
    	//添加此判断在接收完一帧数据后,第2次意外进入时会直接退出
    	if (serialPort1.BytesToRead == 0)
    	{
    		return;	//串口数据长度为0则直接退出
    	}
    
    	//串口接收并不是接收的每个字节都会进入该事件,因此需在该事件中接收完数据
    	Int32 readByteNum = 0;
    
    	/* 等待数据接收完成,即3mS内串口接收到的数据长度不再变化则认为数据已经接收完成 */
    	do
    	{
    		readByteNum = serialPort1.BytesToRead;
    		System.Threading.Thread.Sleep(10);
    	} while (readByteNum < serialPort1.BytesToRead && serialPort1.BytesToRead < 4096);
    
    
    	serialPort1.Read(usartRecvBuffer, 0, readByteNum);  //将串口缓冲区的数据保存至接收缓冲区
    	serialPort1.DiscardInBuffer();                      //清空串口缓冲区的内容
    	
    	//显示串口接收到的数据
    	string str = string.Empty;
    	for (int i = 0; i < readByteNum; i++)
    	{
    		str += (usartRecvBuffer[i].ToString("X02") + ' ');
    	}
    #if USE_DELEGATE
    	this.UpdataControl(tboxRecv, str);
    #else
    	tboxRecv.Text = str;
    #endif
    }

    微软官方对 SerialPort.DataReceived 事件 的使用说明:

     原文链接:https://docs.microsoft.com/zh-cn/dotnet/api/system.io.ports.serialport.datareceived?redirectedfrom=MSDN&view=dotnet-plat-ext-5.0

    展开全文
  • C#程序C#串口接收程序

    2014-03-24 12:49:39
    C#串口接收程序
  • C# VS2013 串口接收事件 通过委托跨线程操作TXTBOX
  • C#串口接收数据保存到数据库
  • 这里是c#串口自动接收处理后实时刷新处理,实时显示。可以直接new了,直接用看效果。
  • PC C# 串口接收数据

    2018-05-05 16:33:55
    简单的串口数据接收程序,是用C#做的,自己拿来改动下应该能使用在不同的场景下。多多支持
  • C# 串口接收的优化处理 引言 在VS中实用串口接收通讯的时候往往会遇到等待数据或需要解决接收数据效率的问题。这里小结一种比较实用的的方法,其通过线程接收来控制协调,约束时间和数据极限大小来输出处理,大大...

    C# 串口接收的优化处理


    引言

    在VS中实用串口接收通讯的时候往往会遇到等待数据或需要解决接收数据效率的问题。这里小结一种比较实用的的方法,其通过线程接收来控制协调,约束时间和数据极限大小来输出处理,大大提高了数据处理的效率。这里为了简要说明,省略了线程部分开启部分。
    一段经典的代码往往解决用户实际实用的痛点又能提高代码的效率。

    ......
    namespace app
    {
       public partial class Form1 : Form
       {
        
            private const int UART_COUNT_MAX = 512;
           //定义线程 
           Thread listenThread;
           public bool rx_thread_stop_flag = false;//线程停止标志
    
     		public Form1()
           {
      			    InitializeComponent();
      			    //在这里可以或者其它控件启动接收线程
            }
    
    ......
           
           /// <summary>
           ///  串口数据接收线程循环程序
           /// </summary>
           public void ReceiveData()
           {
               //接收线程
               int len = 0;
               string rx_data = "";
               while (_serialPort.IsOpen && !rx_thread_stop_flag)//线程循环
               {
                   len = this._serialPort.BytesToRead;//获取当前的串口数据长度
                   Thread.Sleep(20);//间隔20ms
                  //判断数据长度是否有变化//判断数据是否超过最大值
                   while (len < this._serialPort.BytesToRead && len < UART_COUNT_MAX)
                   {
                   	//在长度范围内有数据变化就循环累加
                       len = this._serialPort.BytesToRead;
                       //时间继续累加
                       Thread.Sleep(20);
                   }
    
                   if (len > 0)//有数据则接收处理数据
                   {
                       SerialPortEventArgs args = new SerialPortEventArgs();
                       byte[] data = new Byte[len];
                       try
                       {
                           this._serialPort.Read(data, 0, len);   //向串口中读取数据
                           rx_data = System.Text.Encoding.UTF8.GetString(data);
                            
                           //这里添加数据处理的代码,处理rx_data 
                           
                       }
                       catch (Exception)//异常处理
                       {
                           MessageBox.Show("数据接收失败!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                           return;
                       }
                   }
    
               }
    
           }
    
           /// <summary>
           /// 接收串口读取数据
           /// </summary>
           public class SerialPortEventArgs : EventArgs
           {
               public byte[] receivedBytes = null; // 用来接收串口读取的数据
           }
       }
    }
    
    
    展开全文
  • 下面小编就为大家分享一篇C# 串口接收数据中serialPort.close()死锁的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
  • c#串口接收数据之后同时发送另外两个虚拟串口,虚拟串口供另外两个程序使用,解决一个串口数据库多个程序同时读取问题
  • 最近笔者使用C#编程时,经常用到串口通信功能。所以总结记录一下串口通信功能的使用方法。 串口组件 在工具箱中找到SerialPort组件,将其添加到设计中。 串口端口和波特率设置 属性名称 含义 (Name) 指示...

    最近笔者使用C#编程时,经常用到串口通信功能。所以总结记录一下串口通信功能的使用方法。

    串口组件

    在工具箱中找到SerialPort组件,将其添加到设计中。
    在这里插入图片描述

    串口端口和波特率设置

    在这里插入图片描述

    属性名称含义
    (Name)指示代码中用来标识该对象的名称
    BaudRate此串行端口上要使用的波特率
    DataBits没发送/接收一个字节的数据位数目
    DiscardNull在添加到序列缓冲区前是否丢弃端口上接收的空字节
    DtrEnable在通信过程中是否启用数据终端就绪(DTR)行
    GenerateMember指示是否将为此组件生成成员变量
    Handshake用于数据交换中流控制的握手协议
    Modifiers指示对象的可见性级别
    Parity用于对每个接收字节进行奇偶校验检查并且标记每个发送的字节的方案
    ParityPeplace用来替换接收的有奇偶校验错误的字节的字节
    PortName要打开的通信端口的名称
    ReadBufferSize读取缓冲区的大小(以字节为单位)
    ReadTimeout读取超时(以毫秒为单位)
    ReceivedBytesThreshold触发Read事件前要求可用的字节数
    RtsEnable在通信过程中是否启用请求发送(RTS)行
    StopBits每发送/接收一个字节的停止位数目
    WriteBufferSize写入缓冲区的大小(以字节为单位)
    WriteTimerout写入超时(以毫秒为单位)

    上表是SerialPort组件的属性及其对应的含义,在实际编程中,鼠标选中某个属性时也会显示出对应的含义。平时使用时,我们大多只需修改PortName、BaudRate、DataBits 、StopBits、Parity、ReadBufferSize、WriteBufferSize这个几个属性。其中DataBits 、StopBits、Parity这三个属性在大多数串口通信中,都默认为8、One、None。在STM32F1单片机中关于串口的配置有如下语句。
    在这里插入图片描述
    在.cs文件中调用如下语句进行SerialPort组件的初始化。

    serialPort1.PortName = comboBox1.Text;//设置端口名
    serialPort1.BaudRate = Convert.ToInt32(comboBox2.Text);//设置波特率
    serialPort1.Open();//打开串口
    

    其中comboBox1、comboBox2为设计中的两个控件。
    在这里插入图片描述
    调用以下函数关闭串口。

    serialPort1.Close();//关闭串口
    

    在定时器中调用以下函数用以更新可用端口。

    private void Updata_Serialport_Name(ComboBox MycomboBox)
    {
    	string[] ArryPort = SerialPort.GetPortNames();
    	MycomboBox.Items.Clear();
    	for (int i = 0; i < ArryPort.Length; i++)
    	{
    		MycomboBox.Items.Add(ArryPort[i]); 
    	}
    }
    

    串口接收在这里插入图片描述

    事件名称含义
    DataReceived每次从SerialPort接收数据时引发
    ErrorReceived每次从SerialPort接收错误时引发
    PinChanged每次SerialPort的pin更改时引发

    上表SerialPort组件的事件及其对应的含义。我们将主要使用DataReceived事件。

    在DateRecived事件中引用以下函数,即可完成串口数据的接收与显示。

    private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        //string str = serialPort1.ReadExisting();//直接以字符串方式读并显示
        //textBox1.AppendText(str);
    	int length = serialPort1.BytesToRead;
    	byte[] data = new byte[length];
    	serialPort1.Read(data, 0, length);
    	//对串口接收数据的处理,可对data进行解析
    	for (int i = 0; i < length; i++)
    	{
    		string str = Convert.ToString(data[i], 16).ToUpper();
    		textBox1.AppendText(str.Length == 1 ? "0" + str + " " : str + " ");//将接收到的数据以十六进制显示到文本框内
    	}
    	//string str = Encoding.UTF8.GetString(data, 0, length);
        //textBox1.AppendText(str);//以字符显示
    }
    

    串口发送

    SerialPort组件的发送方法如下。

    //serialPort1.Write(textBox2.Text.Trim());//以字符串方式发送数据
    int length;
    byte[] data = new byte[length];
    serialPort1.Write(data, 0, length);
    //write()的后两个参数为offset和count,就是发送数据的起始位置和长度
    //比如只发数组的第二个数据,则使用serialPort1.Write(data, 1, 1);
    

    至此,我们就可实现C#串口通信的基本操作。
    关于串口发送数据时,需要从输入控件读取各种数据类型以及不同数据类型的转换请参考笔者之前的博客。

    C#使用TextBox作数据输入方法
    C#串口通信例程

    展开全文
  • 在做项目时,发现C#串口经常会发生丢帧的情况,在发送/接收大量数据时,这种状况尤为明显。因此,在对比了各种缓存处理办法的基础上,做了这个小程序。经过实测,完全可以应对48byte/5ms的数据量。这个小程序只做了...
  • C#串口数据接收

    2013-12-29 10:28:08
    本源代码是在win7下利用vs2010开发的C#串口接收数据界面,类似于串口助手。上传的是完整的工程文件。
  • private void port_DataReceived(object sender, SerialDataReceivedEventArgs e) ...接收数据方法一 string recive_data; //recive_data = serialPort1.ReadExisting(); recive_data = seri...

    private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
            {
                try
                {

    接收数据方法一
                    string recive_data;
                    //recive_data = serialPort1.ReadExisting();
                    recive_data = serialPort1.ReadTo("=");//一直读取到输入缓冲区中的指定 value 的字符串。

                    //textBox1.AppendText(recive_data);
                    //textBox1.AppendText("\r\n");

                    i += 1;
                    if (i % 10 == 0)
                    {
                        textBox1.AppendText(recive_data);
                        textBox1.AppendText("\r\n");
                    }

                    if (i == 100)
                    {
                        i = 0;
                        textBox1.AppendText("A");
                    }

    接收数据方法二
                    //    Thread.Sleep(50);  //(毫秒)等待一定时间,确保数据的完整性 int len        
                    //int len = serialPort1.BytesToRead;
                    //string receivedata = string.Empty;
                    //if (len != 0)
                    //{
                    //    byte[] buff = new byte[len];
                    //    serialPort1.Read(buff, 0, len);
                    //    receivedata = Encoding.Default.GetString(buff);

                    //}
                    //textBox1.AppendText(receivedata + "\r\n");
                }
                catch { }
            }

    展开全文
  • C# 串口接收数据

    千次阅读 2019-03-02 15:52:31
    //注册接收事件 sp.ReceivedBytesThreshold = 1; //接收到一个字节就触发事件 sp.Encoding = Encoding.Default; //设置编码,避免中文乱码 sp.Open(); //打开串口 } //接收方法 private void Sp_...
  • VS 软件C#串口接收中断存在BUG,此BUG在VS2019版本已修复,内容如下: 在串口 接收中,如果串口接收到含有0x3f的内容时,会忽视设定的ReceivedBytesThreshold=n; 引发串口事件产生,从而产生BUG;即: 当...
  • 使用了C#中的SerialPort控件来接收串口发来的数据。
  • C# 串口数据接收与发送 示例源码
  • 的数据,末尾自带换行符,可是接收数据时却是分段接受的,因为每一次触发事件我都额外加了换行符,得到的显示结果是分为好几段,并且末尾会空出一行。请问怎样设置才能保证每次触发事件接收的是完整的一条数据呢?...
  • C#上位机串口接收温度数据
  • C#串口接收数据

    2013-05-17 11:24:14
    给位高手,我在C#中用串口接收数据时,必须的延时一下才能正确执行,现在我也找不出原因所在,串口号和波特率都对,请各位高手指点一下,下面是我的串口接收处理函数的一部分 void comm_DataReceived(object ...
  • 必须要两个软件同时对方才有效,软件自带帧头 长度
  • 问题描述:都知道用事件dataReceive来处理串口非常的方便,...解决办法:可以通过设置串口的ReceivedBytesThreshold来设置当接收到几个字节来触发接收事件,如上面所说可以用serialPort1.ReceivedBytesThreshold = ...
  • //串口接收事件 sp1.DtrEnable = true; sp1.RtsEnable = true; sp1.ReadTimeout = 1000; sp1.Close(); } ``` ``` private void button_open_Click(object sender, EventArgs e) { ...
  • //将串口接收到的数据写入接收数组 //sc.DataReceived(object sender, EventArgs e, rec); builder.Append(Encoding.ASCII.GetString(rec)); 这个是我自己写的,获取不到东西,还有一个是别人提供...
  • c#串口接收字符串

    2016-06-11 20:03:13
    上位机接收事件里面将接收到的字符和时间记录日志,代码如下: private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e) { string str = serialPort1....
  • C#串口发送接收

    2012-07-08 22:34:06
    使用VS2008编写的C#串口程序,成功发送接收ASCC数据,没有做发送接收二进制的

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 5,543
精华内容 2,217
关键字:

c#串口接收事件

c# 订阅