C# 串口收不到任何数据
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8907490/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
SerialPort not receiving any data
提问by Frank Myat Thu
I am developing program which need to interact with COM ports.
我正在开发需要与 COM 端口交互的程序。
By learning from this Q&A: .NET SerialPort DataReceived event not firing, I make my code like that.
通过从这个问答中学习:.NET SerialPort DataReceived event not fire,我让我的代码像这样。
namespace ConsoleApplication1
{
class Program
{
static SerialPort ComPort;
public static void OnSerialDataReceived(object sender, SerialDataReceivedEventArgs args)
{
string data = ComPort.ReadExisting();
Console.Write(data.Replace("\r", "\n"));
}
static void Main(string[] args)
{
string port = "COM4";
int baud = 9600;
if (args.Length >= 1)
{
port = args[0];
}
if (args.Length >= 2)
{
baud = int.Parse(args[1]);
}
InitializeComPort(port, baud);
string text;
do
{
String[] mystring = System.IO.Ports.SerialPort.GetPortNames();
text = Console.ReadLine();
int STX = 0x2;
int ETX = 0x3;
ComPort.Write(Char.ConvertFromUtf32(STX) + text + Char.ConvertFromUtf32(ETX));
} while (text.ToLower() != "q");
}
private static void InitializeComPort(string port, int baud)
{
ComPort = new SerialPort(port, baud);
ComPort.PortName = port;
ComPort.BaudRate = baud;
ComPort.Parity = Parity.None;
ComPort.StopBits = StopBits.One;
ComPort.DataBits = 8;
ComPort.ReceivedBytesThreshold = 9;
ComPort.RtsEnable = true;
ComPort.DtrEnable = true;
ComPort.Handshake = System.IO.Ports.Handshake.XOnXOff;
ComPort.DataReceived += OnSerialDataReceived;
OpenPort(ComPort);
}
public static void OpenPort(SerialPort ComPort)
{
try
{
if (!ComPort.IsOpen)
{
ComPort.Open();
}
}
catch (Exception e)
{
throw e;
}
}
}
}
My problem is DataReceived event never gets fired.
我的问题是 DataReceived 事件永远不会被触发。
My program specifications are:
我的程序规范是:
- Just .net console programming
- I use VSPE from http://www.eterlogic.com
- My computer has COM1 and COM2 ports already.
- I created COM2 and COM4 by using VSPE.
- I get output result from mystring array (COM1, COM2, COM3, COM4)
- 只是 .net 控制台编程
- 我使用来自http://www.eterlogic.com 的VSPE
- 我的电脑已经有 COM1 和 COM2 端口。
- 我使用 VSPE 创建了 COM2 和 COM4。
- 我从 mystring 数组(COM1、COM2、COM3、COM4)得到输出结果
But I still don't know why DataReceivedevent is not fired.
但我仍然不知道为什么DataReceived没有触发事件。
Updated
更新
Unfortunately, I still could not make to fire DataReceivedevent in any way.
不幸的是,我仍然无法DataReceived以任何方式触发事件。
So, I created new project by hoping that I will face a way to solve.
所以,我创建了一个新项目,希望我能找到解决的方法。
At that new project [just console application], I created a class...
在那个新项目 [只是控制台应用程序],我创建了一个类......
public class MyTest
{
public SerialPort SPCOM4;
public MyTest()
{
SPCOM4 = new SerialPort();
if(this.SerialPortOpen(SPCOM4, "4"))
{
this.SendToPort(SPCOM4, "com test...");
}
}
private bool SerialPortOpen(System.IO.Ports.SerialPort objCom, string portName)
{
bool blnOpenStatus = false;
try
{
objCom.PortName = "COM" + portName;
objCom.BaudRate = 9600;
objCom.DataBits = 8;
int SerParity = 2;
int SerStop = 0;
switch (SerParity)
{
case 0:
objCom.Parity = System.IO.Ports.Parity.Even;
break;
case 1:
objCom.Parity = System.IO.Ports.Parity.Odd;
break;
case 2:
objCom.Parity = System.IO.Ports.Parity.None;
break;
case 3:
objCom.Parity = System.IO.Ports.Parity.Mark;
break;
}
switch (SerStop)
{
case 0:
objCom.StopBits = System.IO.Ports.StopBits.One;
break;
case 1:
objCom.StopBits = System.IO.Ports.StopBits.Two;
break;
}
objCom.RtsEnable = false;
objCom.DtrEnable = false;
objCom.Handshake = System.IO.Ports.Handshake.XOnXOff;
objCom.Open();
blnOpenStatus = true;
}
catch (Exception ex)
{
throw ex;
}
return blnOpenStatus;
}
private bool SendToPort(System.IO.Ports.SerialPort objCom, string strText)
{
try
{
int STX = 0x2;
int ETX = 0x3;
if (objCom.IsOpen && strText != "")
{
objCom.Write(Char.ConvertFromUtf32(STX) + strText + Char.ConvertFromUtf32(ETX));
}
}
catch (Exception ex)
{
throw ex;
}
return true;
}
}
I am not sure that I face good luck or bad luck because this new class could make fire DataReceivedevent which is from older console application that is still running. It is miracle to me which I have no idea how this happen.
我不确定我的运气是好还是坏,因为这个新类可能会触发DataReceived来自仍在运行的旧控制台应用程序的火灾事件。对我来说这是奇迹,我不知道这是怎么发生的。
Let me tell you more detail so that you could give me suggestion for better way.
让我告诉你更多细节,以便你可以给我建议更好的方法。
- Finally I created 2 console projects.
- First project is the class which I posted as a question yesterday.
- Second project is the class called MyTest which could make fire
DataReceivedevent from First project, at the same time when two of the project is running.
- 最后我创建了 2 个控制台项目。
- 第一个项目是我昨天作为问题发布的课程。
- 第二个项目是名为 MyTest 的类,它可以
DataReceived在两个项目运行的同时从第一个项目中生成火灾事件。
Could anyone give me suggestions on how could I combine these two projects as a single project?
谁能给我关于如何将这两个项目合并为一个项目的建议?
采纳答案by Hans Passant
ComPort.Handshake = Handshake.None;
The problem is not that the DataReceived event doesn't fire, the problem is that the serial port isn't receiving any data. There are very, very few serial devices that use no handshaking at all. If you set it to None then the driver won't turn on the DTR (Data Terminal Ready) and RTS (Request To Send) signals. Which a serial port device interprets as "the machine is turned off (DTR)" or "the machine isn't ready to receive data (RTS)". So it won't send anything and your DataReceived event won't fire.
问题不在于 DataReceived 事件没有触发,问题在于串行端口没有接收任何数据。很少有串行设备完全不使用握手。如果将其设置为 None,则驱动程序将不会打开 DTR(数据终端就绪)和 RTS(请求发送)信号。串行端口设备将其解释为“机器已关闭(DTR)”或“机器尚未准备好接收数据(RTS)”。所以它不会发送任何东西,你的 DataReceived 事件也不会触发。
If you reallywant None then set the DTREnable and RTSEnable properties to true. But it is likely you want HandShake.RequestToSend since the device appears to be paying attention to the handshake signals.
如果你真的想要 None 然后将 DTREnable 和 RTSEnable 属性设置为 true。但您可能需要 HandShake.RequestToSend,因为设备似乎正在关注握手信号。
If you still have trouble then use another serial port program like Putty or HyperTerminal to ensure the connection and communication parameters are good and the device is responsive. SysInternals' PortMon utility gives a low-level view of the driver interaction so you can compare good vs bad.
如果您仍然遇到问题,请使用其他串行端口程序,如 Putty 或 HyperTerminal,以确保连接和通信参数良好且设备响应良好。SysInternals 的 PortMon 实用程序提供了驱动程序交互的低级视图,因此您可以比较好与坏。
回答by Carlito
I have never worked with VSPE so I'm not sure if that causes the problem. I have worked with a COM port before and I looked up my code. The only main difference is the way you declare the event. You have:
我从未使用过 VSPE,所以我不确定这是否会导致问题。我以前使用过 COM 端口,并且查找了我的代码。唯一的主要区别是您声明事件的方式。你有:
ComPort.DataReceived += OnSerialDataReceived;
I have it like this:
我有这样的:
ComPort.DataReceived += new SerialDataReceivedEventHandler(OnSerialDataReceived);
OnSerialDataReceived is your eventhandler. I'm not sure if this will make any difference, but you can try it. I hope this helps!
OnSerialDataReceived 是您的事件处理程序。我不确定这是否会有所作为,但您可以尝试一下。我希望这有帮助!
回答by Freak
I had a quite similar problem. In a graphical application (C# win form) I had a class which encapsulate a SerialPortcomponent. The DataReceivedevent was firing only one time, but then any following data received didn't fire any event. I solved the problem by calling the Closemethod in my principal form Closedevent function.
No idea of why that changes anything, but now it's working.
我有一个非常相似的问题。在图形应用程序(C# win 表单)中,我有一个封装SerialPort组件的类。该DataReceived事件仅触发一次,但随后收到的任何后续数据均未触发任何事件。我通过Close在主窗体Closed事件函数中调用该方法解决了这个问题。不知道为什么这会改变任何东西,但现在它起作用了。

