C# serial port data sending and receiving

Creation and management of multiple threads


https://blog.csdn.net/u010307521/article/details/50238997

1. Start

Recently, I worked on a serial communication project between the upper computer and the equipment in the company. I wrote a serial communication tool myself. Today is the third day, and I just realized the two-way communication of the serial port.

2. Software interface

Design the interface first, and put the required functions on it. 
interface design 
The main functions include: open the serial port, close the serial port, send data to the serial port and read data from the serial port. In the sending and receiving text boxes, I added the function of switching hexadecimal, which is convenient for debugging. 
Some variables are needed in the main form to store related information such as serial port name and serial port buffer data.

private string[] portNames = null;
private List<SerialPort> serialPorts;
private byte[] portBuffer;
  • 1
  • 2
  • 3
  • 4

The selection of the serial port number adopts a drop-down menu, and all available serial ports need to be scanned and displayed in the comboBox when the Form is initialized. After initialization, you need to add the following code:

this.serialPorts = new List<SerialPort>();
this.portNames = SerialPort.GetPortNames();
this.portBuffer = new byte[1000];   
  • 1
  • 2
  • 3
  • 4

The second line stores the scanned serial port names as strings into the this.portNames array. Then you need to read the scanned serial port into the comboBox.

//Assign the value of port names to serial ports display
if (this.portNames.Length > 1)
{         
    for(int i = 0;i<this.portNames.Length;i++)
    {
        this.serialPorts.Add(new SerialPort(this.portNames[i]));
    }                
}
            this.portNumberComboBox1.Items.AddRange(this.portNames);             this.portNumberComboBox2.Items.AddRange(this.portNames); 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

The code above does this. At this point, the initialization of the software interface and the initial scanning of the serial port number are completed, and then the response function of the button needs to be completed.

3. The operation function of the serial port

It is very simple to open and close the serial port, just call the corresponding API directly.

private void openButton_Click(object sender, EventArgs e)
    {
        for (int i = 0; i < this.portNames.Length; i++)
        {
            try
            {
                if (this.portNames.ElementAt(i) == this.portNumberComboBox1.Text.ToString())
                {
                    if (!this.serialPorts.ElementAt(i).IsOpen)
                    {
                        this.serialPorts.ElementAt(i).Open();
                        MessageBox.Show("已打开串口!");
                    }
                    //this.serialPorts.ElementAt(i).
                }
            }
            catch (IOException eio)
            {
                MessageBox.Show("打开串口异常:" + eio);
            }

        }
    }

    private void closeButton_Click(object sender, EventArgs e)
    {
        for (int i = 0; i < this.portNames.Length; i++)
        {
            try
            {
                if (this.portNames.ElementAt(i) == this.portNumberComboBox1.Text.ToString())
                {
                    if (this.serialPorts.ElementAt(i).IsOpen)
                    {
                        this.serialPorts.ElementAt(i).Close();
                        MessageBox.Show("已关闭串口!");
                    }

                }
            }
            catch (IOException eio)
            {
                MessageBox.Show("关闭串口异常:" + eio);
            }
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47

When sending data through a serial port, you need to read the content to be sent in the text box first, and then call the write function.

private void sendButton_Click(object sender, EventArgs e)
    {
        for (int i = 0; i < this.portNames.Length; i++)
        {
            try
            {
                if (this.portNames.ElementAt(i) == this.portNumberComboBox1.Text.ToString())
                {
                    if (this.serialPorts.ElementAt(i).IsOpen)
                    {
                        string sendContent = this.sendTextBox.Text.ToString();
                        this.serialPorts.ElementAt(i).Write(sendContent);                            
                        MessageBox.Show("已发送数据!");
                    }

                }
            }
            catch (IOException eio)
            {
                MessageBox.Show("串口发送异常:" + eio);
            }
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

For the read operation, since the serial port has dataReceived events that can be monitored, here we choose not to use threads, but to monitor events. Create a timer to scan the second comboBox, when the second comboBox is selected, the event will be monitored.

private void timer1_Tick(object sender, EventArgs e)
{
    this.AddEventHandlerForResponse();
}

private void AddEventHandlerForResponse()
    {
        for (int i = 0; i < this.portNames.Length; i++)
        {
            try
            {
                if (this.portNames.ElementAt(i) == this.portNumberComboBox2.Text.ToString())
                {
                    if ((this.serialPorts.ElementAt(i).IsOpen)&&(this.serialPorts.ElementAt(i).BytesToRead > 0))
                    {
                        this.serialPorts.ElementAt(i).Read(this.portBuffer, 0, this.serialPorts.ElementAt(i).BytesToRead);
                        this.serialPorts.ElementAt(i).DataReceived += new SerialDataReceivedEventHandler(this.DataReceiveEventHandler);
                    }

                }
            }
            catch (IOException eio)
            {
                MessageBox.Show("串口异常:" + eio);
            }
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

In the above code, there is a function to handle the DataReceived event. this.DataReceiveEventHandler 
Here, because the read operation of the serial port is relatively special, the serial port reads the buffer data through the auxiliary thread. When performing the read operation, the content in the UI cannot be directly modified, so the receive in the text box The content should be realized through invoke.

private void DataReceiveEventHandler(object sender, SerialDataReceivedEventArgs e)
{
    SerialPort sp = (SerialPort)sender;
    this.receiveTextBox.Invoke(
        new MethodInvoker(
            delegate 
        {
                this.receiveTextBox.AppendText(sp.ReadExisting());
                this.receiveTextBox.Text += " ";

        }
                        )
                            );
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

So far, the basic functions of serial port communication have been realized, including opening the serial port, closing the serial port, and reading and writing operations.

Guess you like

Origin blog.csdn.net/u010655348/article/details/80677553
Recommended