2.3-使用C#Winform开发串口小助手开发步骤

一、界面设计

在做软件之前使用“软件界面设计工具”先设计并绘制出软件界面,方便在写代码之前确认“功能需求”以及“交互流程”。
这里使用的软件是:“Axure RP”
在这里插入图片描述

二、新建工程与绘制界面

  1. 新建工程:
    使用任意一个Visual studio即可,这里使用Visual studio2017作为开发环境(安装的时候选择.net桌面开发)。新建工程选择“c# winform类型的工程,然后填写工程名字即可完成工程创建”。如下图所示:
    在这里插入图片描述
  2. 绘制图形界面:
    鼠标单击打开“From1.cs”文件,会出现界面绘制界面。点击软件左侧栏的“工具栏”弹出界面控件列表,选择要绘制的控件拖动到软件绘制界面,并调整控件位置,直到达到设计图所设计的样子。如下图所示:
    在这里插入图片描述
  3. 添加按钮按下相应函数:
    选中按钮并使用右键点击“属性”,从而打开这个按钮的属性配置窗口,在窗口里可以设置很多属性,切换到事件配置页面(闪电图标)即可编辑与此控件相关的事件。在“事件配置页面”即可给按钮添加点击事件响应函数,如下图所示:
    在这里插入图片描述

三、用到的库函数说明

用到了.net的类为:“SerialPort”。这个类中常用的函数说明如下:
“SerialPort”类的官方文档:https://docs.microsoft.com/zh-cn/dotnet/api/system.io.ports.serialport?view=netframework-4.8

  • 公有成员函数
    Open();//打开串口设备
    Close();//关闭串口设备
    int Write (byte[] buffer, int offset, int count);//给串口写数据
    int Read (byte[] buffer, int offset, int count);//从串口读数据
  • 公有成员变量
    IsOpen //串口设备是否打开
    ComDevice.PortName //设置或读取串口名称
    ComDevice.BaudRate //设置或读取波特率
    ComDevice.DataBits //设置或读取数据位
    ComDevice.Parity //设置或读取校验位
    ComDevice.StopBits //设置或读取停止位

四、核心编写逻辑代码

.net提供了串口编程函数类,为了避免把逻辑代码和界面代码混合编写。这里给串口相关操作函数做了二次封装。界面代码只要调用二次封装的类,即可完成串口通信。

  1. 逻辑代码
    二次封装需要新定义一个类,使用Visual Studio添加自定义类方法如下图所示:
    在这里插入图片描述
    填写类名字:
    在这里插入图片描述
    新建完类后,在类中编写如下代码(简化展示,详情查看源代码):
namespace winform_serial_port_gui_tool
{
public delegate void RecvListener(byte[] data, int length); //定义一个委托

    class SerialComm
    {
        private SerialPort ComDevice;
        private static SerialComm mInstance = null;
        private RecvListener recvListener = null;

        
        public SerialComm()
        {
            ComDevice = new SerialPort();
        }

        public void SetRecvListener(RecvListener listener)
        {
            recvListener = listener;
        }

        public bool Open()
        {
            try
            {
                Console.WriteLine("##### open serial port");
                ComDevice.DataReceived += new SerialDataReceivedEventHandler(Com_DataReceived);
                ComDevice.Open();
                if (ComDevice.IsOpen == true)
                {
                    return true;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("未能成功开启串口" + ex.Message);
                
            }

            return false;
        }

        public void Close()
        {
            try
            {
                if (ComDevice.IsOpen)
                {
                    ComDevice.DataReceived -= new SerialDataReceivedEventHandler(Com_DataReceived);
                    ComDevice.Dispose();
                    ComDevice.Close();
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("串口关闭错误" + ex.Message);
            }
        }

        public bool IsOpen() {
            return ComDevice.IsOpen;
        }

        public bool Send(char[] data)
        {
            if (ComDevice.IsOpen)
            {
                try
                {
                    ComDevice.Write(data, 0, data.Length);
                    return true;
                }
                catch (Exception ex)
                {
                    Console.WriteLine("发送失败" + ex.Message);
                }
            }
            else
            {
                Console.WriteLine("串口未开启");
            }
            return false;
        }

        private void Com_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            int length = ComDevice.BytesToRead;
            byte[] ReDatas = new byte[length];
            ComDevice.Read(ReDatas, 0, ReDatas.Length);

            if (recvListener != null)
            {
                recvListener(ReDatas, length);
            }
        }

        //*********** serial property settings *****************/
        public void SetSerialPortName(string portName) {
            ComDevice.PortName = portName;
        }

        public void SetSerialBaudRate(int rate) {
            ComDevice.BaudRate = rate;
        }

        public void SetSerialDataBits(int dataBits) {
            ComDevice.DataBits = dataBits;
        }

        public void SetSerialParity(Parity parity) {
            ComDevice.Parity = parity;
        }

        public void SetSerialStopBits(StopBits stopBits) {
            ComDevice.StopBits = stopBits;
        }
    }
}  


   
  1. 界面代码
    在工程文件中,选中“Form1”然后点击右键“查看代码”,进入到界面代码编辑页面。如下图所示:
    在这里插入图片描述
    在界面代码文件中编写如下代码:
namespace winform_serial_port_gui_tool
{
    public partial class Form1 : Form
    {
        private SerialComm serialComm;
        private string recvCache = "";

        public Form1()
        {
            InitializeComponent();
            serialComm = new SerialComm();
            serialComm.SetRecvListener(RecvListener);
            InitUI();
        }

        private void InitUI() {
            comboBoxSerialPort.Items.AddRange(serialComm.GetSerialDeviceStrList());
            comboBoxSerialBaud.Items.AddRange(serialComm.GetSerialBaudRateStrList());
            comboBoxSerialDataBits.Items.AddRange(serialComm.GetSerialDataBitsStrList());
            comboBoxSerialParity.Items.AddRange(serialComm.GetSerialParityStrList());
            comboBoxSerialStopBits.Items.AddRange(serialComm.GetSerialStopBitsStrList());

            if (comboBoxSerialPort.Items.Count > 0) {
                comboBoxSerialPort.SelectedIndex = 0;
            }
            comboBoxSerialBaud.SelectedIndex = 3;
            comboBoxSerialDataBits.SelectedIndex = 3;
            comboBoxSerialParity.SelectedIndex = 0;
            comboBoxSerialStopBits.SelectedIndex = 1;
        }

        private void DisableSettingsUI() {
            comboBoxSerialPort.Enabled = false;
            comboBoxSerialBaud.Enabled = false;
            comboBoxSerialDataBits.Enabled = false;
            comboBoxSerialParity.Enabled = false;
            comboBoxSerialStopBits.Enabled = false;
        }

        private void EnableSettingsUI() {
            comboBoxSerialPort.Enabled = true;
            comboBoxSerialBaud.Enabled = true;
            comboBoxSerialDataBits.Enabled = true;
            comboBoxSerialParity.Enabled = true;
            comboBoxSerialStopBits.Enabled = true;
        }

        private void SetSerialSettings() {
            serialComm.SetSerialPortName(comboBoxSerialPort.Text);
            serialComm.SetSerialBaudRate(SerialComm.GetBaudRateByIndex(comboBoxSerialBaud.SelectedIndex));
            serialComm.SetSerialDataBits(SerialComm.GetDataBitsByIndex(comboBoxSerialDataBits.SelectedIndex));
            serialComm.SetSerialParity(SerialComm.GetParityByIndex(comboBoxSerialParity.SelectedIndex));
            serialComm.SetSerialStopBits(SerialComm.GetStopBitsByIndex(comboBoxSerialStopBits.SelectedIndex));
        }

        private void buttonSerialOpen_Click(object sender, EventArgs e)
        {
            if (serialComm.IsOpen())
            {
                //do close
                serialComm.Close();
                EnableSettingsUI();
                buttonSerialOpen.Text = "open";
            }
            else
            {
                //do open
                SetSerialSettings();
                serialComm.Open();
                DisableSettingsUI();
                buttonSerialOpen.Text = "close";
            }
        }

        private void buttonSerialSend_Click(object sender, EventArgs e)
        {
            if (!serialComm.IsOpen()) {
                MessageBox.Show("Please open the serial port first !");
                return;
            }

            char[] data = textBoxSerialSend.Text.ToString().ToCharArray();
            serialComm.Send(data);
            textBoxSerialSend.Clear();
        }

        private void RecvListener(byte[] data, int length) {
            this.Invoke( (MethodInvoker)delegate ()
            {
                String temp = System.Text.Encoding.UTF8.GetString(data);
                Console.Out.WriteLine(temp);
                recvCache += temp;
                textBoxSerialRecv.Text = recvCache;
            });
        }
    }
}

五、获取源代码

点击此链接获取源代码

六、效果图

在这里插入图片描述

发布了88 篇原创文章 · 获赞 45 · 访问量 20万+

猜你喜欢

转载自blog.csdn.net/robert_cysy/article/details/104376469