使用Microsoft Visual Studio编写C#上位机(串口助手)

最近跟着刘工写了一套用于单片机与电脑通信的串口助手,此处将自己手敲的代码记录下来,供大家一起学习交流。

一、程序界面

 程序界面

程序界面说明 

 二、代码(Form1.cs)

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.Runtime.InteropServices;

namespace 上位机模板
{
    public partial class Form1 : Form
    {
        [DllImport("kernel32")]
        private static extern long WritePrivateProfileString(string section, string key, string val, string filePath);
        [DllImport("kernel32")]
        private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath);
        string FileName = System.AppDomain.CurrentDomain.BaseDirectory + "Backup.ini";//ini文件名

        StringBuilder BackupBuf = new StringBuilder(100);

        bool Timer3_Flag = false;

        public Form1()
        {
            InitializeComponent();
            serialPort1.Encoding = Encoding.GetEncoding("GB2312");
            //关闭跨线程错误报告
            System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;
        }

        //查找串口,并加到comboBox1中
        private void SearchAndAddSerialToComboBox(SerialPort MyPort, ComboBox MyBox, TextBox MyTextBox)
        {
            string[] ComputerPortName = SerialPort.GetPortNames();
            string BackupPort;

            GetPrivateProfileString("串口1", "端口号", "", BackupBuf, 100, FileName);
            BackupPort = BackupBuf.ToString();

            MyBox.Items.Clear();
            MyBox.Text = "";

            for (byte i = 0; i < ComputerPortName.Length; i++)
            {
                try
                {
                    MyPort.PortName = ComputerPortName[i];
                    MyPort.Open();
                    MyBox.Items.Add(MyPort.PortName);
                    MyPort.Close();

                    if (BackupPort == MyPort.PortName)
                    {
                        MyBox.Text = BackupPort;
                    }

                    if (MyBox.Text == "")
                    {
                        MyBox.Text = MyPort.PortName;
                    }
                }
                catch
                {
                }
            }

            if(MyBox.Text == "")
            {
                MyTextBox.AppendText("[" + DateTime.Now.ToString("HH:mm:ss") + "]" + "->");
                MyTextBox.AppendText("没有检测到串口!\r\n");
            }

            WritePrivateProfileString("串口1", "端口号", MyBox.Text, FileName);
        }

        //CRC校验
        private UInt16 Crc_Check(byte[] Data, byte DataLEN)
        {
            UInt16 CRC = 0xFFFF;

            for (byte i = 0; i < DataLEN; i++)
            {
                CRC ^= Data[i];
                for (byte j = 0; j < 8; j++)
                {
                    if ((CRC & 0x0001) == 0x0001)
                    {
                        CRC = (UInt16)((CRC >> 1) ^ 0xA001);
                    }
                    else
                    {
                        CRC = (UInt16)(CRC >> 1);
                    }
                }
            }
            CRC = (UInt16)((CRC >> 8) + (CRC << 8));

            return CRC;
        }

        //手动扫描按键
        private void button1_Click(object sender, EventArgs e)
        {
            if (serialPort1.IsOpen == true)
            {
                serialPort1.Close();
                button2.BackgroundImage = Properties.Resources.Image_CloseSerial;
                button2.Tag = "OFF";
                //timer1.Stop();

                textBox1.AppendText("[" + DateTime.Now.ToString("HH:mm:ss") + "]" + "->");
                textBox1.AppendText("扫描并添加串口时关闭串口!\r\n");
            }

            SearchAndAddSerialToComboBox(serialPort1, comboBox1, textBox1);
        }

        //串口开关按键
        private void button2_Click(object sender, EventArgs e)
        {
            if (button2.Tag.ToString() == "ON")
            {
                serialPort1.Close();
                button2.BackgroundImage = Properties.Resources.Image_CloseSerial;
                button2.Tag = "OFF";

                textBox1.AppendText("[" + DateTime.Now.ToString("HH:mm:ss") + "]" + "->");
                textBox1.AppendText("手动关闭串口!\r\n");
            }
            else
            {
                try
                {
                    serialPort1.PortName = comboBox1.Text;
                    serialPort1.BaudRate = Convert.ToInt32(comboBox2.Text, 10);
                    serialPort1.Open();
                    button2.BackgroundImage = Properties.Resources.Image_OpenSerial;
                    button2.Tag = "ON";

                    textBox1.AppendText("[" + DateTime.Now.ToString("HH:mm:ss") + "]" + "->");
                    textBox1.AppendText("串口开启成功!\r\n");

                    timer1.Start();
                }
                catch
                {
                    serialPort1.Close();
                    button2.BackgroundImage = Properties.Resources.Image_CloseSerial;
                    button2.Tag = "OFF";

                    textBox1.AppendText("[" + DateTime.Now.ToString("HH:mm:ss") + "]" + "->");
                    textBox1.AppendText("串口开启失败!\r\n");

                    timer1.Stop();
                }
            }

            WritePrivateProfileString("串口1", "端口号", comboBox1.Text, FileName);
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            comboBox2.Text = "115200";
            SearchAndAddSerialToComboBox(serialPort1, comboBox1, textBox1);

            //恢复发送栏
            GetPrivateProfileString("串口1", "发送栏", "", BackupBuf, 100, FileName);
            textBox2.Text = BackupBuf.ToString();
        }

        //下拉框切换串口
        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (serialPort1.IsOpen == true)
            {
                serialPort1.Close();

                try
                {
                    serialPort1.Open();
                    button2.BackgroundImage = Properties.Resources.Image_OpenSerial;
                    button2.Tag = "ON";

                    textBox1.AppendText("[" + DateTime.Now.ToString("HH:mm:ss") + "]" + "->");
                    textBox1.AppendText("串口更换成功!\r\n");
                }
                catch
                {
                    serialPort1.Close();
                    button2.BackgroundImage = Properties.Resources.Image_CloseSerial;
                    button2.Tag = "OFF";

                    textBox1.AppendText("[" + DateTime.Now.ToString("HH:mm:ss") + "]" + "->");
                    textBox1.AppendText("串口更换失败!\r\n");
                }
            }
        }

        //扫描串口定时器
        private void timer1_Tick(object sender, EventArgs e)
        {
            if (serialPort1.IsOpen == false)
            {
                serialPort1.Close();
                button2.BackgroundImage = Properties.Resources.Image_CloseSerial;
                button2.Tag = "OFF";

                SearchAndAddSerialToComboBox(serialPort1, comboBox1, textBox1);
            }
        }

        private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            //接收ASCII格式
            if (checkBox1.Checked == false)
            {
                try
                {
                    textBox1.AppendText("[" + DateTime.Now.ToString("HH:mm:ss") + "]" + "->");
                    string str = serialPort1.ReadExisting();
                    textBox1.AppendText(str);

                    textBox1.AppendText("\r\n");

                    //统计接收字节数
                    UInt32 RBytes = Convert.ToUInt32(textBox4.Text, 10);
                    RBytes += (UInt32)str.Length;
                    textBox4.Text = RBytes.ToString();
                }
                catch
                {
                    textBox1.AppendText("[" + DateTime.Now.ToString("HH:mm:ss") + "]" + "->");
                    textBox1.AppendText("ASCII格式接受错误!\r\n");
                }
            }
            //接收HEX格式
            else
            {
                try
                {
                    if (Timer3_Flag == true)
                    {
                        Timer3_Flag = false;

                        textBox1.AppendText("\r\n");
                        textBox1.AppendText("[" + DateTime.Now.ToString("HH:mm:ss") + "]" + "->");
                    }

                    textBox1.AppendText("[" + DateTime.Now.ToString("HH:mm:ss") + "]" + "->");

                    byte[] data = new byte[serialPort1.BytesToRead];
                    serialPort1.Read(data, 0, data.Length);

                    for (int Member = 0; Member < data.Length; Member++)
                    {
                        string str = Convert.ToString(data[Member], 16).ToUpper();
                        textBox1.AppendText(((str.Length == 1) ? ("0" + str) : str) + " ");
                    }

                    textBox1.AppendText("\r\n");

                    //统计接收字节数
                    UInt32 RBytes = Convert.ToUInt32(textBox4.Text, 10);
                    RBytes += (UInt32)data.Length;
                    textBox4.Text = RBytes.ToString();
                }
                catch
                {
                    textBox1.AppendText("[" + DateTime.Now.ToString("HH:mm:ss") + "]" + "->");
                    textBox1.AppendText("HEX格式接受错误!\r\n");
                }
            }
        }

        //清除接收按键
        private void button3_Click(object sender, EventArgs e)
        {
            textBox1.Clear();
            textBox4.Text = "0";
        }

        //串口发送按键
        private void button4_Click(object sender, EventArgs e)
        {
            byte[] data = new byte[1];

            //发送ASCII格式
            if (checkBox2.Checked == false)
            {
                try
                {
                    //支持中文
                    Encoding Chinese = System.Text.Encoding.GetEncoding("GB2312");
                    byte[] Sendbytes = Chinese.GetBytes(textBox2.Text);

                    for (int Member = 0; Member < Sendbytes.Length; Member++)
                    {
                        data[0] = (byte)Sendbytes[Member];
                        serialPort1.Write(data, 0, 1);
                    }

                    if (checkBox4.Checked == true)
                    {
                        data[0] = 0X0D;
                        serialPort1.Write(data, 0, 1);

                        data[0] = 0X0A;
                        serialPort1.Write(data, 0, 1);
                    }

                    //统计发送字节数
                    UInt32 SBytes = Convert.ToUInt32(textBox3.Text, 10);
                    SBytes += (UInt32)Sendbytes.Length;

                    if (checkBox4.Checked == true)
                    {
                        SBytes += 2;
                    }
                    textBox3.Text = SBytes.ToString();
                }
                catch
                {
                    textBox1.AppendText("\r\n串口发送错误!\r\n");
                    serialPort1.Close();
                    button2.BackgroundImage = Properties.Resources.Image_CloseSerial;
                    button2.Tag = "OFF";
                }
            }
            //发送HEX格式
            else
            {
                string Buf = textBox2.Text.ToUpper();
                Buf = Buf.Replace("0X", "");
                Buf = Buf.Replace(" ", "");
                byte[] Calculate_Crc = new byte[Buf.Length / 2];

                textBox2.Clear();

                try
                {
                    for (int i = 0; i < Buf.Length / 2; i++)
                    {
                        textBox2.AppendText(Buf.Substring(i * 2, 2) + " ");
                        data[0] = Convert.ToByte(Buf.Substring(i * 2, 2), 16);
                        serialPort1.Write(data, 0, 1);
                        Calculate_Crc[i] = data[0];            
                    }

                    //统计发送字节数
                    UInt32 SBytes = Convert.ToUInt32(textBox3.Text, 10);
                    SBytes += (UInt32)(Buf.Length / 2);
                    if (checkBox3.Checked == true)
                    {
                        SBytes += 2;
                    }
                    textBox3.Text = SBytes.ToString();
                }
                catch
                {
                    textBox1.AppendText("\r\n串口发送错误!\r\n");
                    serialPort1.Close();
                    button2.BackgroundImage = Properties.Resources.Image_CloseSerial;
                    button2.Tag = "OFF";
                }
                

                //发送CRC
                if (checkBox3.Checked == true)
                {
                    UInt32 CRC = Crc_Check(Calculate_Crc, (byte)Calculate_Crc.Length);
                    byte CRC_H = (byte)(CRC >> 8);
                    byte CRC_L = (byte)CRC;

                    try
                    {
                        data[0] = CRC_L;
                        serialPort1.Write(data, 0, 1);
                        data[0] = CRC_H;
                        serialPort1.Write(data, 0, 1);
                    }
                    catch
                    {
                        textBox1.AppendText("\r\n串口发送错误!\r\n");
                        serialPort1.Close();
                        button2.BackgroundImage = Properties.Resources.Image_CloseSerial;
                        button2.Tag = "OFF";
                    }
                }

            }

            if (checkBox5.Checked == true)
            {
                textBox2.Clear();
            }
        }

        //清除发送按键
        private void button5_Click(object sender, EventArgs e)
        {
            textBox2.Clear();
        }

        private void checkBox2_CheckedChanged(object sender, EventArgs e)
        {
            if (checkBox2.Checked == true)
            {
                checkBox4.Enabled = false;
                checkBox3.Enabled = true;
            }
            else
            {
                checkBox4.Enabled = true;
                checkBox3.Enabled = false;
            }
        }

        private void textBox2_TextChanged(object sender, EventArgs e)
        {
            WritePrivateProfileString("串口1", "发送栏", textBox2.Text, FileName);
        }

        private void checkBox6_CheckedChanged(object sender, EventArgs e)
        {
            //启动定时发送
            if (checkBox6.Checked == true)
            {
                textBox1.AppendText("[" + DateTime.Now.ToString("HH:mm:ss") + "]" + "->");
                textBox1.AppendText("启动定时发送!\r\n");

                try
                {
                    timer2.Interval = Convert.ToUInt16(comboBox3.Text);
                }
                catch
                {
                    MessageBox.Show("输入时间有误,设定为默认值", "提示");
                    comboBox3.Text = "1000";
                    timer2.Interval = 1000;
                }
                timer2.Start();
            }
            //关闭定时发送
            else
            {
                textBox1.AppendText("[" + DateTime.Now.ToString("HH:mm:ss") + "]" + "->");
                textBox1.AppendText("关闭定时发送!\r\n");

                timer2.Stop();
            }
        }

        //定时发送定时器
        private void timer2_Tick(object sender, EventArgs e)
        {
            button4.PerformClick();
        }

        private void comboBox3_SelectedIndexChanged(object sender, EventArgs e)
        {
            timer2.Interval = Convert.ToUInt16(comboBox3.Text);
        }

        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            //开启断帧
            if (checkBox1.Checked == true)
            {
                comboBox4.Enabled = true;

                timer3.Interval = Convert.ToUInt16(comboBox4.Text);
                timer3.Start();
            }
            //关闭断帧
            else
            {
                comboBox4.Enabled = false;
                timer3.Stop();
            }
        }

        //断帧定时器
        private void timer3_Tick(object sender, EventArgs e)
        {
            Timer3_Flag = true;
        }

        //断帧选项改变
        private void comboBox4_SelectedIndexChanged(object sender, EventArgs e)
        {
            timer3.Interval = Convert.ToUInt16(comboBox4.Text);
        }

        //波特率选项改变
        private void comboBox2_SelectedIndexChanged(object sender, EventArgs e)
        {
            serialPort1.BaudRate = Convert.ToInt32(comboBox2.Text, 10); 
        }
    }
}

 三、备注

此处在Form1的属性中,将AutoSize设为True,AutoScroll设为True,AutoScaleMode设为Font,以应对在不同分辨率显示下的界面失真问题。

  • 7
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值