从库中的串行端口返回值的最佳方法

时间:2015-04-09 05:51:15

标签: c# .net dll serial-port

我正在尝试通过串口发送和接收数据,我可以正常从DataReceived事件中获取数据 现在,我创建了一个库,它被开发用于通过串口发送和接收数据。我不知道如何通过两种不同的方法发送命令和检索价值 这让我很困惑,请帮助我!

    static void Main(string[] args)
    {
        FXReader reader = new FXReader();
        reader.ComPort = port;
        reader.Connect();

        Console.WriteLine(reader.SetPortPower(1));
        Console.ReadLine();
        Console.WriteLine(reader.GetPortStatus(1));
        Console.ReadLine();
    }

public class FXReader : IDisposable
{
    private SerialPort rs232 = null;

    public string ComPort
    {
        get { return rs232.PortName; }
        set { rs232.PortName = value; }
    }

    public bool IsConnected
    {
        get { return rs232.IsOpen; }
    }

    public F520Reader()
    {
        rs232 = new SerialPort();
        rs232.BaudRate = 115200;            
        rs232.Parity = Parity.None;
        rs232.DataBits = 8;
        rs232.StopBits = StopBits.One;
        rs232.DataReceived += new SerialDataReceivedEventHandler(rs232_DataReceived);
    }

    public void Connect()
    {
        rs232.Open();
    }

    public void Disconnect()
    {
        rs232.Close();
    }

    public int GetPortPower(int port)
    {
        if (rs232.IsOpen)
        {
            byte[] command = { 0x5A, 0x00, 0x19, 0x00, 0x01, 0xFF, 0xFF, 0x7E };
            rs232.Write(command, 0, command.Length);

            //How can i get value from the event of "rs232_DataReceived"
            return powervalue;
        }
    }

    public int GetPortStatus(int port)
    {
        if (rs232.IsOpen)
        {
            byte[] command = { 0x5A, 0x00, 0x19, 0x00, 0x01, 0xFF, 0xFF, 0x7E };
            rs232.Write(command, 0, command.Length);

            //How can i get value from the event of "rs232_DataReceived"
            return statusvalue;
        }
    }

    void rs232_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        System.Threading.Thread.Sleep(50);
        if (rs232.BytesToRead > 0)
        {
            byte[] recvBuffer = new byte[1024];
            int recvLength = rs232.Read(recvBuffer, 0, recvBuffer.Length);
            Array.Resize(ref recvBuffer, recvLength);

            PharseResponse(recvBuffer);
        }
    }

    private void PharseResponse(byte[] buffer)
    {
        if (buffer[0] == 0x5A && buffer[buffer.Length - 1] == 0x7E)
        {
            #region Response for Get Port Power
            if (buffer[1] == 0x01 && buffer[2] == 0x13)
            {
                //How can I return value by the method of "GetPortPower"
                return buffer[7];
            }
            #endregion

            #region Response for Get Port Status
            if (buffer[1] == 0x01 && buffer[2] == 0x14)
            {
                //How can I return value by the method of "GetPortStatus"
                return buffer[7];
            }
            #endregion
        }
    }       

    #region IDisposable Members

    public void Dispose()
    {
        if (rs232.IsOpen)
            rs232.Close();

        rs232.Dispose();
    }

    #endregion
}

1 个答案:

答案 0 :(得分:2)

这肯定不是"最佳方式"。使用DataReceived事件无法获得任何好处。它在事件驱动的应用程序中很有用,例如GUI应用程序。但不是在这样的应用程序,你必须得到一个响应,然后才能继续你的程序。

所以根本不使用它,而是直接调用Read()方法。您的程序将阻止,直到设备发回信息为止。

这也可以帮助您编写正确的代码,现在不正确。从串口读取通常只产生一个或两个字节。 Read()的返回值告诉您有多少。在获得完整之前,您无法解析响应。从您当前的代码中可以看出,"完成"看起来像,但在PharseResponse()方法停止使用IndexOutOfRangeException崩溃之前,您需要至少接收8个字节。串行协议通常使用特定的字节值来指示响应的结束。