SerialPort没有收到任何数据

时间:2012-01-18 09:00:29

标签: c# serial-port

我正在开发需要与COM端口交互的程序。

通过学习这个Q& A:.NET SerialPort DataReceived event not firing,我就可以制作我的代码了。

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;
        }
    }
}
}

我的问题是DataReceived事件永远不会被触发。

我的计划规范是:

  1. 只是.net控制台编程
  2. 我使用http://www.eterlogic.com
  3. 中的VSPE
  4. 我的电脑已经有COM1和COM2端口。
  5. 我使用VSPE创建了COM2和COM4。
  6. 我从mystring数组(COM1,COM2,COM3,COM4)获得输出结果
  7. 但我仍然不知道为什么DataReceived事件没有被解雇。


    更新

    不幸的是,我仍无法以任何方式解雇DataReceived事件。

    所以,我创建了一个新项目,希望我将面临一个解决方法。

    在那个新项目[只是控制台应用程序]中,我创建了一个类......

    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;
        }
    }
    

    我不确定我会遇到好运还是运气不好,因为这个新类可以发出来自仍在运行的旧控制台应用程序的fire DataReceived事件。对我来说这是奇迹,我不知道这是怎么发生的。

    让我告诉你更多细节,以便你能给我更好的建议。

    1. 最后我创建了2个控制台项目。
    2. 第一个项目是我昨天发布的一个问题。
    3. 第二个项目是名为MyTest的类,它可以在第一个项目中生成fire DataReceived事件,同时两个项目正在运行。
    4. 有人可以给我一些关于如何将这两个项目合并为一个项目的建议吗?

3 个答案:

答案 0 :(得分:19)

    ComPort.Handshake = Handshake.None;

问题不在于DataReceived事件没有触发,问题是串口没有接收到任何数据。很少有串口设备根本不使用握手。如果将其设置为“无”,则驱动程序将不会打开DTR(数据终端就绪)和RTS(请求发送)信号。哪个串口设备解释为“机器已关闭(DTR)”或“机器未准备好接收数据(RTS)”。所以它不会发送任何内容,你的DataReceived事件也不会触发。

如果确实想要None,则将DTREnable和RTSEnable属性设置为true。但是你可能想要HandShake.RequestToSend,因为设备似乎正在关注握手信号。

如果仍然遇到问题,请使用Putty或HyperTerminal等其他串口程序,以确保连接和通信参数良好,并且设备具有响应能力。 SysInternals的PortMon实用程序提供了驱动程序交互的低级视图,因此您可以比较好与坏。

答案 1 :(得分:0)

我从未使用过VSPE,所以我不确定是否会导致问题。我之前使用过COM端口,然后查找了我的代码。唯一的主要区别是您声明事件的方式。你有:

ComPort.DataReceived += OnSerialDataReceived;

我喜欢这样:

ComPort.DataReceived += new SerialDataReceivedEventHandler(OnSerialDataReceived);

OnSerialDataReceived是您的事件处理程序。我不确定这会有什么不同,但你可以尝试一下。我希望这有帮助!

答案 2 :(得分:0)

我有一个非常相似的问题。在图形应用程序(C#win form)中,我有一个封装SerialPort组件的类。 DataReceived事件仅触发一次,但随后收到的任何后续数据均未触发任何事件。我通过在我的主要形式Close事件函数中调用Closed方法来解决问题。 不知道为什么会改变任何东西,但现在它正在发挥作用。