Skip to content

第一个串口通信

0. 硬件配置

如果你购买了教程配套的开发版的话,需要将如图所示的位置短接,这样的话就可以将发送的回传到接收的位置去 alt text

1. Form的配置

1.1 public Form1() 函数的配置

将串口的接收事件放在Form 这个函数中去,让他一直在执行相关的代码,能够持续的将读到的显示在界面上去

C
public Form1()
{
    InitializeComponent();

    serialPort1.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);      //串口数据接收事件
    serialPort1.Encoding = Encoding.GetEncoding("GB2312");                                  //串口接收编码
    System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;                   //
}

private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)             //串口接收事件
{

    richTextBox2.AppendText(serialPort1.ReadExisting());                                //串口类会自动处理汉字,所以不需要特别转换
    
}

1.2 Form1_Load 函数的调用

Form1_Load,这个函数点击form这个窗口可以显示出来, 我的理解是会在打开程序的时候运行一次,所以可以做一些界面的初始化操作,下面的代码就是初始化了相关的串口信息,以及初始化了comboBox中默认的值,这样在第一次显示的时候就可以显示上相关的内容。

C
private void Form1_Load(object sender, EventArgs e)
{
    SearchAndAddSerialToComboBox(serialPort1, comboBox6);       //扫描初始化串口
    comboBox3.Text = "115200";//波特率
    comboBox4.Text = "1";//停止位
    comboBox2.Text = "8"; //数据位
    comboBox5.Text = "None"; //校验位

    richTextBox2.ReadOnly = true;
}

2. 串口函数的操作

2.1 刷新com口

因为com口随着设备的插拔,会有新的出现。那么需要一个功能来手动跟新。 SerialPort:串口编号,传递要刷新的是哪一个串口 ComboBox:下拉框,可以将串口号,在下拉框中显示出来

C
//刷新com
private string SearchAndAddSerialToComboBox(SerialPort MyPort, System.Windows.Forms.ComboBox MyBox)
{
    //将可用端口号添加到ComboBox

    string[] ports = System.IO.Ports.SerialPort.GetPortNames();//获取电脑上可用串口号
    MyBox.Items.Clear();                                        //清空ComboBox内容
    foreach (string i in ports)
    {
        MyBox.Items.Add(i);
    }
    //没有的话直接传给串口空
    if(ports.Length==0)
    {
        return "";
    }else
    {
        MyBox.Text = ports[0];          //初始化
        return ports[0];
    }
    
}

这个函数就是在按键中去调用上面写的刷新串口的函数,刷新成功后可以显示上去。

C
/// <summary>
/// 刷新串口
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button6_Click(object sender, EventArgs e)
{
    if (serialPort1.IsOpen)
    {
        MessageBox.Show("请关闭串口");
    }
    else
    {
        SearchAndAddSerialToComboBox(serialPort1, comboBox6);       //扫描并讲课用串口添加至下拉列表            
    }

}

2.2 打开串口

流程大概如下

  1. 判断是否有打开,打开就关闭,关闭就打开
  2. 没有打开的话,从串口配置的下拉框中,去读取配置的参数,读取后对串口进行配置
  3. 将配置好的传递到串口中去,做打开串口的动作,并且跟新按键的状态
C

/// <summary>
/// 打开串口
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button7_Click(object sender, EventArgs e)
{
    //串口打开就关闭
    if (serialPort1.IsOpen)
    {
        try
        {
            serialPort1.Close();
        }
        catch { }     //确保万无一失
        button7.Text = "打开串口";
    }
    else
    {
        try
        {

            //字符串转成数字,判断是否转换成功
            int num1 = 0;
            bool a = int.TryParse(comboBox3.Text, out num1);
            if (a == true)
            {
                serialPort1.BaudRate = num1;      //串口波特率                    
            }
            else
            {
                MessageBox.Show("串口波特率错误", "错误");
            }

            serialPort1.PortName = comboBox6.Text;              //端口号
            serialPort1.DataBits = Convert.ToInt32(comboBox2.Text);

            //停止位
            switch (comboBox4.Text)
            {
                case "1":
                    serialPort1.StopBits = StopBits.One;
                    break;
                case "1.5":
                    serialPort1.StopBits = StopBits.OnePointFive;
                    break;
                case "2":
                    serialPort1.StopBits = StopBits.Two;
                    break;
                default:
                    MessageBox.Show("Error:参数不正确", "Error");
                    break;
            }
            //校验位
            switch (comboBox5.Text)
            {
                case "None":
                    serialPort1.Parity = Parity.None;
                    break;
                case "Odd":
                    serialPort1.Parity = Parity.Odd;
                    break;
                case "Even":
                    serialPort1.Parity = Parity.Even;
                    break;
                default:
                    MessageBox.Show("Error:参数不正确", "Error");
                    break;
            }

            serialPort1.Open();                                 //打开端口


            button7.Text = "关闭串口";
        }
        catch
        {
            MessageBox.Show("串口打开失败", "错误");
        }
    }
}

2.3 发送串口的数据

判断串口是否正常打开,可以的话就调用发送函数发送相关的代码,将richTextBox1 中的字符发送出去。

C
/// <summary>
/// 发送串口的数据
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button1_Click(object sender, EventArgs e)
{
    byte[] Data = new byte[1]; //单字节发数据     
    if (serialPort1.IsOpen)
    {
        if (richTextBox1.Text != "")
        {
            try
            {
                serialPort1.Write(richTextBox1.Text);

            }
            catch
            {
                MessageBox.Show("串口数据写入错误");
            }
        }
        else
        {
            MessageBox.Show("请输入内容", "错误");
        }
    }
    else
    {
        MessageBox.Show("请打开串口");
    }
}

3. UI界面的其他操作

3.1 清楚和保存

这边主要列举了清除相关richTextBox中的文字信息,直接调用就可以

C
/// <summary>
/// 清除接收
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button3_Click(object sender, EventArgs e)
{
    richTextBox2.Text = "";//清除接收的数据
}


/// <summary>
/// 保存串口接收的内容
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button2_Click(object sender, EventArgs e)
{

}
/// <summary>
/// 清除发送的信息
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button4_Click(object sender, EventArgs e)
{
    richTextBox1.Text = "";//清除发送的数据
}

保存的功能还待实现,有兴趣的观众可以思考一下可以如何实现,这里提供一个主要的步骤

  1. 获取需要保存的文件路径
  2. 获取一段串口接收的数据,数据长度可以是时间,也可以是数据的大小
  3. 将数据写入相关的文件中去,保存文件

3.2 linkLabel的使用

触发点击事件后,直接连接到UP主相关的网站页面中去。

C
private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{

    System.Diagnostics.Process.Start("http://rumena.cn");
}

private void linkLabel2_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
    System.Diagnostics.Process.Start("https://space.bilibili.com/2044983862");
}

4 演示

下图就是,将外部串口的Rx和Tx短接后收到的信息 alt text

5 其他

这边给一个微软的.net相关的参考

这个是ComboBox 类的一个参考,可以根据自己的实际情况,来学习相关的事件,属性,方法等

https://learn.microsoft.com/zh-cn/dotnet/api/system.windows.forms.combobox?view=windowsdesktop-8.0alt text

右边属性栏中的几个按键的作用

  1. 按照分类排序:会将内容分为不同的分类,然后排序
  2. 按照字母排序:将内容以字母的方式排序,适合已知名称的查找
  3. 属性:比如说按键的颜色,按键的尺寸,按键的字体等等属于属性类别,点击属性后可以修改
  4. 事件:按键被点击后的动作,鼠标悬停在按键上应该有什么变化,这个是事件的类别。点击事件后双击可以在 Form1.cs 中生成对应的函数接口,从而产生一些动作 alt text