Как открыть несколько портов, используя класс SerialPort в C # - PullRequest
0 голосов
/ 17 января 2012

Я пытаюсь создать приложение, которое обрабатывает 2 внешних модемных устройства, которые подключены к компьютерному устройству через USB COM, я закончил создание класса, который управляет этой операцией, и использовал этот класс в своем приложении, чтобы открыть первый порт ... до теперь все в порядке, но когда я пытаюсь открыть другой порт, компьютер отображает сообщение dumping physical memory to disk с синим экраном, а затем выключается, кто-нибудь знает, что происходит? Ниже приведен класс CommunicationManager, который реализует класс SerailPort:

    #region Manager Enums
/// <summary>
/// enumeration to hold our transmission types
/// </summary>
public enum TransmissionType { Text, Hex }

/// <summary>
/// enumeration to hold our message types
/// </summary>
public enum MessageType { Incoming, Outgoing, Normal, Warning, Error };

public enum DispalyedValue { All, CalledNumnber };

#endregion

//public delegate void DataReceivedHnadler(ReceivedData r);

public class CommunicationManager
{

    #region Members

    private string _baudRate = string.Empty;
    private string _parity = string.Empty;
    private string _stopBits = string.Empty;
    private string _dataBits = string.Empty;
    private string _portName = string.Empty;
    private string m_ATCommand = String.Empty;
    private TransmissionType _transType;
    private TextBox _displayWindow;
    private Label m_DisplayNameLable;
    private DispalyedValue m_DispalyedValue = DispalyedValue.All;

    public event EventHandler DataReceivedFinished;
    //global manager variables
    private Color[] MessageColor = { Color.Blue, Color.Green, Color.Black, Color.Orange, Color.Red };
    private SerialPort comPort = new SerialPort();

    private String[] m_DeletedCode = new String[] { };

    public event EventHandler ATCommandWorked;
    public event EventHandler FinishDataReceiving;

    private String m_OldNumber = String.Empty;

    private bool m_FirstOpen = false;

    #endregion End Members

    #region Manager Constructors

    /// <summary>
    /// Constructor to set the properties of our Manager Class
    /// </summary>
    /// <param name="baud">Desired BaudRate</param>
    /// <param name="par">Desired Parity</param>
    /// <param name="sBits">Desired StopBits</param>
    /// <param name="dBits">Desired DataBits</param>
    /// <param name="name">Desired PortName</param>
    public CommunicationManager(string baud, string par, string sBits, string dBits, string name, TextBox tbx)
    {
        _baudRate = baud;
        _parity = par;
        _stopBits = sBits;
        _dataBits = dBits;
        _portName = name;
        _displayWindow = tbx;
        //now add an event handler
        comPort.DataReceived += new SerialDataReceivedEventHandler(comPort_DataReceived);
    }

    /// <summary>
    /// Comstructor to set the properties of our
    /// serial port communicator to nothing
    /// </summary>
    public CommunicationManager()
    {
        _baudRate = string.Empty;
        _parity = string.Empty;
        _stopBits = string.Empty;
        _dataBits = string.Empty;
        _portName = "COM1";
        _displayWindow = null;
        this.m_DisplayNameLable = null;
        //add event handler
        comPort.DataReceived += new SerialDataReceivedEventHandler(comPort_DataReceived);
    }

    #endregion

    #region Public Methods

    public void WriteData(string msg)
    {
        switch (CurrentTransmissionType)
        {
            case TransmissionType.Text:
                //first make sure the port is open
                //if its not open then open it
                if (!(comPort.IsOpen == true)) {
                    try{comPort.Open();}
                    catch (Exception exp){MessageBox.Show("Error while open port:" + this.PortName + "\n" + exp.Message, "",  MessageBoxButtons.OK, MessageBoxIcon.Error);}
                }
                //send the message to the port
                try { comPort.Write(msg); }
                catch (Exception exp) { MessageBox.Show("Error while write date on port:" + this.PortName + "\n" + exp.Message, "", MessageBoxButtons.OK, MessageBoxIcon.Error); }

                //display the message
                DisplayData(MessageType.Outgoing, msg);//+ "\n"
                break;
            case TransmissionType.Hex:
                try
                {
                    //convert the message to byte array
                    byte[] newMsg = HexToByte(msg);
                    //send the message to the port
                    comPort.Write(newMsg, 0, newMsg.Length);
                    //convert back to hex and display
                    DisplayData(MessageType.Outgoing, ByteToHex(newMsg) + "\n");
                }
                catch (FormatException ex)
                {
                    //display error message
                    DisplayData(MessageType.Error, ex.Message);
                }
                finally
                {
                    _displayWindow.SelectAll();
                }
                break;
            default:
                //first make sure the port is open
                //if its not open then open it
                if (!(comPort.IsOpen == true)) comPort.Open();
                //send the message to the port
                comPort.Write(msg);
                //display the message
                DisplayData(MessageType.Outgoing, msg);//+ "\n"
                break;
                break;
        }
    }

    public bool OpenPort()
    {
        try
        {
            //first check if the port is already open
            //if its open then close it
            if (comPort.IsOpen == true) {
                try { comPort.Close(); }
                catch (Exception exp) { MessageBox.Show("Error while close port:" + this.PortName + "\n" + exp.Message, "", MessageBoxButtons.OK, MessageBoxIcon.Error); }
            }

            //set the properties of our SerialPort Object
            comPort.BaudRate = int.Parse(_baudRate);    //BaudRate
            comPort.DataBits = int.Parse(_dataBits);    //DataBits
            comPort.StopBits = (StopBits)Enum.Parse(typeof(StopBits), _stopBits);   //StopBits
            comPort.Parity = (Parity)Enum.Parse(typeof(Parity), _parity);   //Parity
            comPort.PortName = _portName;   //PortName
            //now open the port
            try { comPort.Open(); }
            catch (Exception exp) { MessageBox.Show("Error while open port:" + this.PortName + "\n" + exp.Message, "", MessageBoxButtons.OK, MessageBoxIcon.Error); }
            //display message
            if (!this.m_FirstOpen)
            {
                DisplayData(MessageType.Normal, "Port opened at " + DateTime.Now + "\n");
                this.m_FirstOpen = true;
            }
            else if (this.m_FirstOpen)
            {
                this.WriteData(this.m_ATCommand);
            }
            //return true
            return true;
        }
        catch (Exception ex)
        {
            DisplayData(MessageType.Error, ex.Message);
            return false;
        }
    }

    public void SetParityValues(object obj)
    {
        foreach (string str in Enum.GetNames(typeof(Parity)))
        {
            ((ComboBox)obj).Items.Add(str);
        }
    }

    public void SetStopBitValues(object obj)
    {
        foreach (string str in Enum.GetNames(typeof(StopBits)))
        {
            ((ComboBox)obj).Items.Add(str);
        }
    }

    public void SetPortNameValues(object obj)
    {
        foreach (string str in SerialPort.GetPortNames())
        {
            ((ComboBox)obj).Items.Add(str);
        }
    }

    public void SetLabelName(string LabelName)
    {
        this.m_DisplayNameLable.Invoke(new EventHandler(delegate
        {
            this.m_DisplayNameLable.Text = LabelName;
        }));
    }

    public void ChangeControlPropertyValue(Control Ctrl, String PropertyName, Object PropertyValue)
    {
        Ctrl.Invoke(new EventHandler(delegate{

            if (PropertyName == "Text")
            {
                Ctrl.Text = Convert.ToString(PropertyValue);
            }
            else if (PropertyName == "Enabled")
            {
                Ctrl.Enabled = Convert.ToBoolean(PropertyValue);
            }
            else if (PropertyName == "Visible")
            {
                Ctrl.Visible = Convert.ToBoolean(PropertyValue);
            }
            else if (PropertyName == "ForeColor"){
                Ctrl.ForeColor = (Color)PropertyValue;    
            }
            else if (PropertyName == "BackColor") {
                Ctrl.BackColor = (Color)PropertyValue;    
            }

        }));

    }
    #endregion End Public Methods

    #region Private Methods
    /// <summary>
    /// method to convert hex string into a byte array
    /// </summary>
    /// <param name="msg">string to convert</param>
    /// <returns>a byte array</returns>
    private byte[] HexToByte(string msg)
    {
        //remove any spaces from the string
        msg = msg.Replace(" ", "");
        //create a byte array the length of the
        //string divided by 2
        byte[] comBuffer = new byte[msg.Length / 2];
        //loop through the length of the provided string
        for (int i = 0; i < msg.Length; i += 2)
            //convert each set of 2 characters to a byte
            //and add to the array
            comBuffer[i / 2] = (byte)Convert.ToByte(msg.Substring(i, 2), 16);
        //return the array
        return comBuffer;
    }

    /// <summary>
    /// method to convert a byte array into a hex string
    /// </summary>
    /// <param name="comByte">byte array to convert</param>
    /// <returns>a hex string</returns>
    private string ByteToHex(byte[] comByte)
    {
        //create a new StringBuilder object
        StringBuilder builder = new StringBuilder(comByte.Length * 3);
        //loop through each byte in the array
        foreach (byte data in comByte)
            //convert the byte to a string and add to the stringbuilder
            builder.Append(Convert.ToString(data, 16).PadLeft(2, '0').PadRight(3, ' '));
        //return the converted value
        return builder.ToString().ToUpper();
    }

    /// <summary>
    /// method to display the data to & from the port
    /// on the screen
    /// </summary>
    /// <param name="type">MessageType of the message</param>
    /// <param name="msg">Message to display</param>
    [STAThread]
    private void DisplayData(MessageType type, string msg)
    {
        try
        {
            string printValue = string.Empty;
            string messge = string.Empty;
            if (msg.Contains("OK"))
            {
                if (this.ATCommandWorked != null) { this.ATCommandWorked(this, new EventArgs()); }
            }
            else
            {
                messge = msg;
                string[] splitor = messge.Split(new char[] { '\n' });
                foreach (string val in splitor)
                {
                    if (val.Contains("NMBR"))
                    {
                        messge = val.Replace("NMBR=", "");
                        if (this.m_DeletedCode.Length > 0)
                        {
                            foreach (string cod in this.m_DeletedCode)
                            {
                                if (printValue.Contains(cod))
                                {
                                    messge = messge.Remove(0, cod.Length);
                                    if (this.m_OldNumber != messge)
                                    {
                                        this.m_OldNumber = printValue = messge;
                                        if (this.FinishDataReceiving != null) { this.FinishDataReceiving(this, new EventArgs()); }
                                    }
                                    else if (this.m_OldNumber == messge)
                                    {
                                        printValue = this.m_OldNumber;
                                    }
                                }
                            }
                        }
                        else
                        {
                            if (this.m_OldNumber != messge)
                            {
                                this.m_OldNumber = printValue = messge;
                                if (this.FinishDataReceiving != null) { this.FinishDataReceiving(this, new EventArgs()); }
                            }
                            else if (this.m_OldNumber == messge)
                            {
                                printValue = this.m_OldNumber;
                            }
                        }
                    }
                }
            }

            _displayWindow.Invoke(new EventHandler(delegate
            {
                if (!String.IsNullOrEmpty(printValue))
                {
                    _displayWindow.Text = printValue;
                    //MessageBox.Show(printValue);
                }
            }));
        }
        catch (Exception exp)
        {
            throw exp;
        }
    }

    #endregion End Private Methods

    #region Event Implementation
    /// <summary>
    /// method that will be called when theres data waiting in the buffer
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    void comPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        //determine the mode the user selected (binary/string)
        switch (CurrentTransmissionType)
        {
            //user chose string
            case TransmissionType.Text:
                //read data waiting in the buffer
                string msg = comPort.ReadExisting();
                //display the data to the user
                DisplayData(MessageType.Incoming, msg + "\n");
                break;
            //user chose binary
            case TransmissionType.Hex:
                //retrieve number of bytes in the buffer
                int bytes = comPort.BytesToRead;
                //create a byte array to hold the awaiting data
                byte[] comBuffer = new byte[bytes];
                //read the data and store it
                comPort.Read(comBuffer, 0, bytes);
                //display the data to the user
                DisplayData(MessageType.Incoming, ByteToHex(comBuffer) + "\n");
                break;
            default:
                //read data waiting in the buffer
                string str = comPort.ReadExisting();
                //display the data to the user
                DisplayData(MessageType.Incoming, str + "\n");
                break;
        }
    }

    #endregion End Event Implementation

    #region Properties
    /// <summary>
    /// Property to hold the BaudRate
    /// of our manager class
    /// </summary>
    public string BaudRate
    {
        get { return _baudRate; }
        set { _baudRate = value; }
    }

    /// <summary>
    /// property to hold the Parity
    /// of our manager class
    /// </summary>
    public string Parity
    {
        get { return _parity; }
        set { _parity = value; }
    }

    /// <summary>
    /// property to hold the StopBits
    /// of our manager class
    /// </summary>
    public string StopBits
    {
        get { return _stopBits; }
        set { _stopBits = value; }
    }

    /// <summary>
    /// property to hold the DataBits
    /// of our manager class
    /// </summary>
    public string DataBits
    {
        get { return _dataBits; }
        set { _dataBits = value; }
    }

    /// <summary>
    /// property to hold the PortName
    /// of our manager class
    /// </summary>
    public string PortName
    {
        get { return _portName; }
        set { _portName = value; }
    }

    /// <summary>
    /// property to hold our TransmissionType
    /// of our manager class
    /// </summary>
    public TransmissionType CurrentTransmissionType
    {
        get { return _transType; }
        set { _transType = value; }
    }

    /// <summary>
    /// property to hold our display window
    /// value
    /// </summary>
    public TextBox DisplayWindow
    {
        get { return _displayWindow; }
        set { _displayWindow = value; }
    }

    public String[] DeletedCode
    {
        get { return this.m_DeletedCode; }
        set { this.m_DeletedCode = value; }
    }

    public bool IsPortWorked
    {
        get { return this.comPort.IsOpen; }
    }

    public DispalyedValue DispalyedValue
    {
        get { return this.m_DispalyedValue; }
        set { this.m_DispalyedValue = (DispalyedValue)value; }
    }

    public String Number
    {
        get { return this.m_OldNumber; }
    }

    public Label DisplayNameLable
    {
        get { return this.m_DisplayNameLable; }
        set { this.m_DisplayNameLable = value; }
    }

    public string ATCommand
    {
        get { return this.m_ATCommand; }
        set { this.m_ATCommand = value; }
    }

    #endregion End Properties
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...