当前位置: 首页 > 编程语言 > C#

如何在C#中使用SerialPort端口对象的dataReceived事件?分享

时间:2023-04-10 22:49:38 C#

C#中如何使用SerialPort端口对象的dataReceived事件?我正在尝试创建一个小应用程序来收集从连接到COM10的外部传感器接收到的数据。我已经成功创建了一个小型C#控制台对象和应用程序,它使用for循环打开一个端口并将数据流式传输到一个文件中一段固定的时间。我想将此应用程序转换为使用dataReceived事件而不是流。在阅读了前5个SerialPort提示之后,我似乎仍然无法让它工作并且不知道我错过了什么。我重写了控制台应用程序,以便所有代码都在Main中并粘贴在下面。有人可以帮助启发我为什么即使我知道硬件有数据发送到端口也没有调用事件处理程序port_OnReceiveDatazz吗?谢谢AzimPS:感谢@Gabe、@JasonDown和@abatishchev提供的所有建议。我很难过,似乎无法让事件处理程序工作。也许它与设备有关。我只能在一个线程中读取端口并将数据直接传输到文件中。代码命名空间serialPortCollection{类程序{staticvoidMain(string[]args){constintbufSize=2048;Byte[]buf=newByte[bufSize];//存储接收到的数据。SerialPortsp=newSerialPort("COM10",115200);sp.DataReceived+=port_OnReceiveDatazz;//添加DataReceived事件处理程序sp.Open();sp.WriteLine("$");//启动数据流的命令//等待数据或用户输入继续。控制台.ReadLine();sp.WriteLine("!");//停止数据流命令sp.Close();}//我的事件处理程序方法privatestaticvoidport_OnReceiveDatazz(objectsender,SerialDataReceivedEventArgse){SerialPortspL=(SerialPort)sender;常数bufSize=12;Byte[]buf=newByte[bufSize];Console.WriteLine("数据收到!");Console.WriteLine(spL.Read(buf,0,bufSize));我认为你的问题是:**sp.DataReceived+=port_OnReceiveDatazz;不应该是:sp.DataReceived+=newSerialDataReceivedEventHandler(port_OnReceiveDatazz);**没关系,语法很好(在我对这个问题的原始回答中当我问这个问题时没有意识到快捷方式)我还看到一些建议你应该为你的串行端口打开以下选项:sp.DtrEnable=true;//数据终端就绪sp.RtsEnable=true;//Request-to-send您可能还必须将握手设置为RequestToSend(通过握手枚举)。更新:发现一个建议,说你应该先打开你的端口,然后分配事件处理程序。也许这是一个错误?所以不是这个:sp.DataReceived+=newSerialDataReceivedEventHandler(port_OnReceiveDatazz);sp.Open();这样做:sp.Open();sp.DataReceived+=newSerialDataReceivedEventHandler(port_OnReceiveDatazz);让我知道事情的后续。首先,我建议您使用以下构造函数代替您当前使用的构造函数:newSerialPort("COM10",115200,Parity.None,8,StopBits.One);接下来,你真的应该删除这段代码://Wait10Secondsfordata...for(inti=0;iinsteadjustloopuntiltheuserpressesakeyorsomething,likethis:namespaceserialPortCollection{classProgram{staticvoidMain(string[]args){SerialPortsp=newSerialPort("COM10",115200);sp.DataReceived+=port_OnReceiveDatazz;//添加DataReceived事件处理程序sp.Open();sp.WriteLine("$");//CommandtostartDataStreamConsole.ReadLine();sp.WriteLine("!");//StopDataStreamCommandsp.Close();}//我的事件处理方法privatestaticvoidport_OnReceiveDatazz(objectsender,SerialDataReceivedEventArgse){SerialPortspL=(SerialPort)sender;byte[]buf=newbyte[spL.BytesToRead];Console.WriteLine("DATARECEIVED!");spL.Read(buf,0,buf.Length);foreach(Bytebinbuf){Console.Write(b.ToString());}Console.WriteLine();}}}另外,请注意对数据接收事件处理程序的修改,它现在应该实际打印缓冲区。更新1我刚刚在我的机器上成功运行了以下代码(在COM33和COM34之间使用零调制解调器电缆));SerialPortsp=newSerialPort("COM33",115200,Parity.None,8,StopBits.One);sp.DataReceived+=port_OnReceiveDatazz;//添加DataReceived事件处理程序sp.Open();sp.WriteLine("$");//启动数据流的命令writeThread.Start();控制台.ReadLine();sp.WriteLine("!");//停止数据流命令sp.Close();}privatestaticvoidport_OnReceiveDatazz(objectsender,SerialDataReceivedEventArgse){SerialPortspL=(SerialPort)sender;byte[]buf=newbyte[spL.BytesToRead];Console.WriteLine("数据收到!");spL.Read(buf,0,buf.Length);foreach(buf中的字节b){Console.Write(b.ToString()+"");}控制台.WriteLine();}privatestaticvoidWriteThread(){SerialPortsp2=newSerialPort("COM34",115200,Parity.None,8,StopBits.One);sp2.打开();字节[]卜f=新字节[100];for(bytei=0;iUPDATE2考虑到最近关于这个问题的所有流量,我开始怀疑你的串行端口配置错误,或者设备没有响应。我强烈建议尝试另一种方法来与设备(我经常使用HyperTerminal)。然后您可以使用所有这些设置(比特率、奇偶校验、数据位、停止位、流量控制),直到找到一个可用的设置。设备的文档也应该指定这些设置。一次我弄清楚了,我会确保我的.NETSerialPort已正确配置以使用这些设置。有关配置串行端口的一些提示:请注意,当我说您应该使用以下构造函数时,我的意思是使用函数,不一定是那些参数!你应该填写你设备的参数,以下设置是通用的,但你的设备可能会有所不同。newSerialPort("COM10",115200,Parity.None,8,StopBits.One);它将.NETSerialPort设置为使用与设备相同的流量控制也很重要(正如其他人之前所说)。您可以在此处找到更多信息:http://www.lammertbies.nl/comm/info/RS-232_flow_control.html我曾经使用调制解调器遇到同样的问题,然后有一天它停止引发DataReceived事件。就我而言,非常随机的解决方案是启用RTS,例如sp.RtsEnable=true;不知道为什么那个特定的工具包(不是真正的通信器)也不知道为什么它工作然后停止,但它可能有一天会帮助某人所以只是发布它以防万一...顺便说一句你可以使用下一个代码:switch(e.EventType){caseSerialData.Chars:{//意味着你收到了一些中断;}caseSerialData.Eof:{//表示接收结束中断;我相信这是行不通的,因为您使用的是控制台应用程序并且没有运行事件循环。当您创建Winforms应用程序时,用于事件处理的事件循环/消息泵会自动设置,但它不适用于控制台应用程序。事实上,很可能是Console.ReadLine阻塞了回调的Console.Writeline。MSDN上的示例看起来几乎相同,只是它们使用ReadKey(不锁定控制台)。请注意,使用.NET/C#和高于COM9的任何COM端口存在问题。请参阅:HOWTO:指定大于COM9的串行端口格式有一个解决方法:底层CreateFile方法支持“\.COM10”,但.NET阻止使用该解决方法格式;SerialPort构造函数和PortName属性都不允许格式以“”开头我一直在努力在C#/.NET中与COM10进行可靠通信。例如,如果我在COM9和COM10上有一个设备,用于COM10的流量将转到COM9上的设备!如果我删除COM9上的设备,COM10流量将转到COM10上的设备。我还没有想出如何使用CreateFile返回的句柄来创建C#/.NET风格的SerialPort对象,如果我想出如何去做,那么我想我可以在C#中使用COM10+。以上就是C#学习教程:如何在C#中使用SerialPort端口对象的dataReceived事件?如果分享的所有内容对您有用,需要了解更多C#学习教程,希望您多多关注---本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: