上位机软件-串口助手-带登陆界面

前言

这是我在大三的时候写的一个串口助手,觉得挺好用的就分享给大家。如果有什么bug的话,希望大家多多包涵,毕竟对于C#语言我只是新手。

制作串口助手

串口助手选用Visual C#开发语言和Visual Studio 2012开发平台进行开发,实现的主要功能如下:

  1. 需要用户名和密码才能登录软件——可以保障用户的隐私
  2. 可用串口扫描——精确且快速的找到可以打开的串口号
  3. 保存和读取数据——可以对数据进行保存和读取,方便后期查看
  4. 显示接收数据的时间——用户可以知道数据到来的时间
  5. 定时发送——用户可以设定在几秒甚至几小时后发送控制命令

成品图如下
上位机软件-串口助手-带登陆界面_第1张图片

登陆界面的源码如下

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace SerialCommunicate
{
     
    public partial class login : Form
    {
     
        public login()
        {
     
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
     
            if (textBox1.Text == "刘小纯" && textBox2.Text == "3118003167")
            {
     
                MessageBox.Show("欢迎登录系统!", "提示");
                this.Hide();
                Form1 form1 = new Form1();
                form1.Show();
            }
            else if(textBox1.Text == "刘小纯" && textBox2.Text != "3118003167")
            {
     
                MessageBox.Show("密码错误!", "提示");
            }
            else if (textBox1.Text != "刘小纯")
            {
     
                MessageBox.Show("该用户不存在!", "提示");
            }
        }

        private void label3_Click(object sender, EventArgs e)
        {
     

        }
    }
}

主页面源码如下

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using System.IO.Ports;  //导入串口的命名空间
using System.IO;
//using System.Text.RegularExpressions;
//using System.Threading.Tasks;
//using System.Collections;

namespace SerialCommunicate
{
     
    public partial class Form1 : Form
    {
     
        public Form1()
        {
     
            InitializeComponent();
            serialPort1.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);      //串口数据接收事件
            serialPort1.Encoding = Encoding.GetEncoding("GB2312");                                  //串口接收编码
            System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;                   //
        }
        //List receivedDatas = new List();  //接收数据泛型数据

        /*窗体创建初始化函数*/
        private void Form1_Load(object sender, EventArgs e)   //窗口弹出触发
        {
     
            ovalShape1.FillColor = Color.Gray;    //小圆圈状态为灰色
            SearchAndAddSerialToComboBox(serialPort1, comboBox1);  //可用串口扫描
            comboBox2.Text = "115200";//默认波特率选择    
            comboBox4.Text = "8";//默认数据位
            comboBox5.Text = "无";//默认校验位
            comboBox3.Text = "1";//默认停止位
        }

        /*点击打开串口按键触发*/
        private void button1_Click(object sender, EventArgs e)      
        {
     
            try
            {
     
                serialPort1.PortName = comboBox1.Text;                 //端口号           
                serialPort1.BaudRate = Convert.ToInt32(comboBox2.Text);//波特率 
                serialPort1.DataBits = Convert.ToInt32(comboBox4.Text.Trim()); //设置数据位,默认为8
                switch (comboBox5.Text.Trim())  //设置奇偶校验位,默认为无
                {
     
                    case "无":
                        serialPort1.Parity = Parity.None; break;
                    case "奇校验":
                        serialPort1.Parity = Parity.Odd; break;
                    case "偶校验":
                        serialPort1.Parity = Parity.Even; break;
                    default:
                        serialPort1.Parity = Parity.None; break;
                }
                switch(comboBox3.Text .Trim () )                       //设置停止位,默认为1
                {
     
                    case "1":
                    serialPort1.StopBits = StopBits .One ;break ;                   
                     case "1.5":
                    serialPort1.StopBits = StopBits .OnePointFive ;break ;
                    case "2":
                     serialPort1.StopBits  = StopBits .Two ;  break;                  
                    default:
                     serialPort1.StopBits  = StopBits .None ; break;   
                }
                           
                 serialPort1.ReadTimeout = 5000;   //设置超时时间为5S
                Control.CheckForIllegalCrossThreadCalls = false;// 这个类中我们不检查跨线程的调用是否合法
                //定义.DataReceived事件的委托,当串口收到数据后触发事件,
                //serialPort1.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived); //加了会使自动换行和显示时间出Bug
             
                serialPort1.Open();                //打开串口
                button1.Enabled = false;           //打开串口的按键不能使用
                button2.Enabled = true;            //关闭串口的按键可以使用
                ovalShape1.FillColor = Color.Red;   //串口状态指示灯为红色
            }
            catch                                  //出错处理
            {
     
                MessageBox.Show("串口打开错误或波特率设置有误", "小纯提示");  //弹出系统提示框
            }
        }

        /*点击关闭串口触发*/
        private void button2_Click(object sender, EventArgs e)   
        {
     
            try
            {
     
                serialPort1.Close();             //关闭串口        
                button1.Enabled = true;         //打开串口按键可用
                button2.Enabled = false;        //关闭串口按键不可用
                ovalShape1.FillColor = Color.Gray;  //串口状态指示灯变为灰色
                comboBox2.DropDownStyle = ComboBoxStyle.DropDownList;  //当点击关闭串口时,将波特率下拉列表设置为不可编辑
            }
            catch
            {
     
                MessageBox.Show("关闭串口错误!", "小纯提示");
            }
        }

        /*定义一个扫描可用串口的函数*/
        private void SearchAndAddSerialToComboBox(SerialPort MyPort, ComboBox MyBox)
        {
                                                                    //将可用端口号添加到ComboBox
            string Buffer;                                              //缓存
            MyBox.Items.Clear();                                        //清空ComboBox内容
            for (int i = 1; i < 20; i++)                                //循环
            {
     
                try                                      //核心原理是依靠try和catch完成遍历,即是从COM1到COM19逐个打开试试,
                                                         //如果能打开,就把这个串口号添加到串口的下拉列表中,后关闭串口,让用户打开
                {
     
                    Buffer = "COM" + i.ToString();
                    MyPort.PortName = Buffer;
                    MyPort.Open();                                      //如果失败,后面的代码不会执行
                    MyBox.Items.Add(Buffer);                            //打开成功,添加至下拉列表
                    MyPort.Close();                                     //关闭串口

                }
                catch
                {
     
                    //不添加出错处理,因为这个程序就是为了试错
                }
            }
        }


        /*串口接收事件*/
        private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)         
        {
     
            if (!radioButton3.Checked)     //接收模式为ASCII(字符)
            {
     

                if (checkBox3.Checked)    //显示时间的校验框被选中
                {
     
                    textBox1.AppendText(System.DateTime.Now.ToString("HH:mm:ss")+"\r\n");  //在接收数据的前面一行追加显示时间

                }
                textBox1.AppendText(serialPort1.ReadExisting());   //串口类会自动处理汉字,所以不需要特别转换,textBox1是输出框
       
             
                if (checkBox2.Checked)     //自动换行的校验框被选中
                    try
                    {
     
                       textBox1.AppendText(Environment.NewLine);  //接收自动换行
                    }
                    catch 
                    {
     
                    }
            }

            else      //接收模式为Hex(数值)
            {
     
                byte[] data = new byte[serialPort1.BytesToRead];    //定义缓冲区,大小为:serialPort1.BytesToRead,因为串口事件触发时有可能收到不止一个字节
                serialPort1.Read(data, 0, data.Length);           //从串口中读取数据

                /*函数原型:foreach(Type t in arry);  Type:需要遍历每一的对象的类型,t:每一个对象,arry:需要遍历的数组*/

                foreach (byte Member in data)                      //遍历用法
                {
     
                  
                    string str = Convert.ToString(Member, 16).ToUpper();  //将Member这个数转化为字符串,并且大写
                    textBox1.AppendText("0x" + (str.Length == 1 ? "0" + str : str) + " ");//如果str的长度为1的就在其前面添加0如0x0A
                }
                if (checkBox3.Checked)   //显示时间的校验框被选中
                {
     
                    textBox1.AppendText("\r\n"+System.DateTime.Now.ToString("HH:mm:ss"));
                }
               
                if (checkBox2.Checked)     //自动换行的校验框被选中
                    try
                    {
     
                        textBox1.AppendText(Environment.NewLine);
                      
                    }
                    catch {
      }
            }
        }

       
        /*发送按键触发*/
        private void button3_Click(object sender, EventArgs e)
        {
     
            byte[] Data = new byte[1];      //定义一个单字节的数组,用来发数据     
            if (serialPort1.IsOpen)        //判断串口是否打开
            {
     
                if (textBox2.Text != "")    //判断输入框的内容是否为空
                {
     
                    if (!radioButton1.Checked)   //发送模式为ASCII(字符)
                    {
     
                        try
                        {
     
                            serialPort1.Write(textBox2.Text);   //将指定的字符串写入串口
                            //serialPort1.WriteLine();       //字符串写入
                        }
                        catch
                        {
     
                            MessageBox.Show("串口数据写入错误", "小纯提示");
                        }
                    }

                    else                        //发送模式为HEX(数值)
                    {
     
                        try                  //如果此时用户输入字符串中含有非法字符(字母,汉字,符号等等,try,catch块可以捕捉并提示)
                        {
     

                            /*将用户输入的数字比如1234,转化为0x12,0x34*/
                            for (int i = 0; i < (textBox2.Text.Length - textBox2.Text.Length % 2) / 2; i++)//转换偶数个
                            {
     
                                Data[0] = Convert.ToByte(textBox2.Text.Substring(i * 2, 2), 16);   //转换(一次处理两个数字?)
                                serialPort1.Write(Data, 0, 1);      //将转化好的一个字节写入串口
                            }
                            if (textBox2.Text.Length % 2 != 0)  //如果数据的长度为奇数,需要单独处理最后一位
                            {
     
                                Data[0] = Convert.ToByte(textBox2.Text.Substring(textBox2.Text.Length - 1, 1), 16);//单独处理最后一个字符
                                serialPort1.Write(Data, 0, 1);         //写入
                            }  
                        }
                        catch
                        {
     
                            MessageBox.Show("数据转换错误,请输入数字。", "小纯提示");
                        }
                    }
                }
            }
        }

        /*扫描按键触发*/
        private void button5_Click(object sender, EventArgs e)
        {
     
            SearchAndAddSerialToComboBox(serialPort1, comboBox1);       //扫描并将可用串口添加至下拉列表
        }

        /*清空按键触发*/
        private void button4_Click(object sender, EventArgs e)
        {
     
            textBox1.Text = "";
        }

        /*定时发送校验框被选中*/
        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
     
            if (checkBox1.Checked)   //定时发送校验框被选中
            {
     
                try
                {
     
                    //选择自动发送
                    numericUpDown1.Enabled = false;     //启动定时发送后不能修改定时时间
                    timer1.Interval = (int)numericUpDown1.Value;// * 1000;  //设置定时器中断时间,*1000将单位转化为秒
                    timer1.Start();                     //启动定时器
                }
                catch {
      }

            }
            else        //定时发送校验框不被选中
            {
     
                try
                {
     
                    //选择不自动发送
                    numericUpDown1.Enabled = true;   //  //停止定时发送后能修改定时时间
                    timer1.Stop();                 //停止定时
                }
                catch
                {
     
                    timer1.Stop();           //出错的话再次停止定时
                    MessageBox.Show("停止自动发送错误", "小纯提示");
                }
            }

        }

        /*定时时间到,定时发送数据*/
        private void timer1_Tick(object sender, EventArgs e)
        {
     

            button3_Click(button3, new EventArgs());  //调用发送按钮的回调函数
        }

        /*清空发送框*/
        private void button6_Click_1(object sender, EventArgs e)  
        {
     
            textBox2.Clear();
        }


        /*点击波特率设置下列表*/
        private void comboBox2_SelectedIndexChanged(object sender, EventArgs e) 
        {
     

            if (comboBox2.Text.Equals("custom"))      //当选择custom项时列表属性发生改变
            {
     
                try
                {
     
                    // comboBox2.DropDownStyle = ComboBoxStyle.DropDown;
                    comboBox2.DropDownStyle = ComboBoxStyle.Simple;     //将属性更改为可以编辑

                }
                catch
                {
     

                    MessageBox.Show("设置波特率时错误!", "小纯提示");
                }
            }
        }

        /*点击保存数据按钮*/
        private void button7_Click(object sender, EventArgs e) 
        {
     
            /*saveFileDialog1 为保存文件的对话框,StreamWriter是专门用来处理文本文化的类,可以方便的向文本文件中写入字符串*/
            saveFileDialog1 = new SaveFileDialog();                 //初始化此类的新实例
            saveFileDialog1.Filter = "(*.txt)|*.txt";               //只允许保存为TXT文本
           // try
          //  {
     
                if (saveFileDialog1.ShowDialog() == DialogResult.OK)    //页面弹出判断框是否点击确定按钮
                {
     
                    StreamWriter streamWriter = new StreamWriter(saveFileDialog1.FileName, false);
                    streamWriter.Write(this.textBox1.Text);//将输出框的字符串写入TXT文本
                    streamWriter.Close(); //关闭流
                }
           // }

           // catch { MessageBox.Show("先打开串口!", "小纯提示"); }
        }

        /*点击读入文件按钮*/
        private void button8_Click(object sender, EventArgs e)  
        {
     
            OpenFileDialog openFileDialog1 = new OpenFileDialog();
            openFileDialog1.Filter = "All files(*.*)|*.*|txt file (*.txt)|*.txt";
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
     
                string logpath = openFileDialog1.FileName;
                using (StreamReader sr = new StreamReader(logpath, Encoding.GetEncoding("gb2312")))
                {
     
                    string oneLineInfo = string.Empty;  //读取到的每行内容
                    while (sr.EndOfStream != true)
                    {
     
                        oneLineInfo = oneLineInfo + "\r\n" + sr.ReadLine();//按行读取
                    }
                    sr.Close();
                    textBox1.Text = oneLineInfo;
                }
            } 
        }
    }
}

登陆界面与主页面的切换

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;

namespace SerialCommunicate
{
     
    static class Program
    {
     
        /// 
        /// 应用程序的主入口点。
        /// 
        [STAThread]
        static void Main()
        {
     
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            //Application.Run(new Form1());   
            Application.Run(new login());  //若不需要登陆界面就把这个注释掉,取消上面的注释
        }
    }
}

你可能感兴趣的:(串口助手,c#,windows)