问题描述
我正在开发需要与 COM 端口交互的程序.
I am developing program which need to interact with COM ports.
通过本问答学习:.NET SerialPort DataReceived 事件未触发,我的代码是这样的.
By learning from this Q&A: .NET SerialPort DataReceived event not firing, I make my code like that.
namespace ConsoleApplication1
{
class Program
{
static SerialPort ComPort;
public static void OnSerialDataReceived(object sender, SerialDataReceivedEventArgs args)
{
string data = ComPort.ReadExisting();
Console.Write(data.Replace("
", "
"));
}
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;
}
}
}
}
我的问题是 DataReceived 事件永远不会被触发.
My problem is DataReceived event never gets fired.
我的程序规格是:
- 只需 .net 控制台编程
- 我使用 http://www.eterlogic.com 的 VSPE
- 我的电脑已经有 COM1 和 COM2 端口.
- 我使用 VSPE 创建了 COM2 和 COM4.
- 我从 mystring 数组 (COM1, COM2, COM3, COM4) 得到输出结果
但我仍然不知道为什么没有触发 DataReceived
事件.
But I still don't know why DataReceived
event is not fired.
不幸的是,我仍然无法以任何方式触发 DataReceived
事件.
Unfortunately, I still could not make to fire DataReceived
event in any way.
所以,我创建了一个新项目,希望我能找到解决办法.
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;
}
}
我不确定我会遇到好运还是坏运,因为这个新类可能会触发来自仍在运行的旧控制台应用程序的 DataReceived
事件.这对我来说是个奇迹,我不知道这是怎么发生的.
I am not sure that I face good luck or bad luck because this new class could make fire DataReceived
event which is from older console application that is still running. It is miracle to me which I have no idea how this happen.
让我告诉你更多细节,以便你给我建议更好的方法.
Let me tell you more detail so that you could give me suggestion for better way.
- 最后我创建了 2 个控制台项目.
- 第一个项目是我昨天作为问题发布的课程.
- 第二个项目是一个名为 MyTest 的类,它可以从第一个项目中触发
DataReceived
事件,同时在两个项目运行时.
- 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
DataReceived
event from First project, at the same time when two of the project is running.
谁能给我一些建议,告诉我如何将这两个项目合并为一个项目?
Could anyone give me suggestions on how could I combine these two projects as a single project?
推荐答案
ComPort.Handshake = Handshake.None;
问题不在于 DataReceived 事件没有触发,问题在于串行端口没有接收到任何数据.很少有串行设备根本不使用握手.如果您将其设置为无,那么驱动程序将不会打开 DTR(数据终端就绪)和 RTS(请求发送)信号.串行端口设备将其解释为机器已关闭 (DTR)"或机器尚未准备好接收数据 (RTS)".所以它不会发送任何东西,你的 DataReceived 事件也不会触发.
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.
如果您真的想要None,则将DTREnable 和RTSEnable 属性设置为true.但您可能需要 HandShake.RequestToSend,因为设备似乎正在关注握手信号.
If you really want 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.
如果您仍然遇到问题,请使用其他串行端口程序,例如 Putty 或 HyperTerminal,以确保连接和通信参数良好并且设备响应.SysInternals 的 PortMon 实用程序提供了驱动程序交互的低级视图,因此您可以比较好与坏.
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.
这篇关于SerialPort 没有收到任何数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!