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

这篇具有很好参考价值的文章主要介绍了使用Microsoft Visual Studio编写C#上位机(串口助手)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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

一、程序界面

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

 程序界面

使用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,以应对在不同分辨率显示下的界面失真问题。文章来源地址https://www.toymoban.com/news/detail-514385.html

到了这里,关于使用Microsoft Visual Studio编写C#上位机(串口助手)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【C#】【winform】Microsoft Visual Studio Installer Project 打包应用程序全部过程

    提示:只针对扩展包来完成打包的工作过程。 在做完C#和winform的开发,完成之后,需要做一些打包的工具,在这个过程中遇到一些问题,所以记录下我的操作过程和遇到的异常情况。 支持快速打包的插件扩展 在扩展—搜搜 Microsoft Visual Studio Installer Project,安装,然后等待下

    2024年02月07日
    浏览(46)
  • asp.net酒店管理系统VS开发sqlserver数据库web结构c#编程Microsoft Visual Studio

    一、源码特点         asp.net酒店管理系统是一套完善的web设计管理系统,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为vs2010,数据库为sqlserver2008,使用c#语言开发 asp.net 酒店管理系统1 二、功能介绍 后台主要功能: (1)用户管理:对用户信息进行添

    2024年02月07日
    浏览(41)
  • asp.net文档管理系统VS开发sqlserver数据库web结构c#编程Microsoft Visual Studio

    一、源码特点         asp.net文档管理系统是一套完善的web设计管理系统,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为vs2010,数据库为sqlserver2008,使用c#语言开发 asp.net文档管理系统 二、功能介绍 (1)用户管理:对用户信息进行添加、删除、修改和

    2024年02月08日
    浏览(32)
  • asp.net归宿管理系统VS开发sqlserver数据库web结构c#编程Microsoft Visual Studio

    一、源码特点         asp.net归宿管理系统 是一套完善的web设计管理系统,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为vs2010,数据库为sqlserver2008,使用c#语言开发 asp.net归宿管理系统VS开发sqlserver数据库w 二、功能介绍 一、定时打卡(采用RFID卡)

    2024年02月09日
    浏览(47)
  • asp.net高校食谱管理系统VS开发sqlserver数据库web结构c#编程Microsoft Visual Studio

    一、源码特点         asp.net高校食谱管理系统 是一套完善的web设计管理系统,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为vs2010,数据库为sqlserver2008,使用c#语言 开发 asp.net高校食谱管理系统VS开发sqlserver数据 二、功能介绍 (1)用户管理:对用户信

    2024年02月09日
    浏览(31)
  • asp.net卷烟物价管理系统VS开发sqlserver数据库web结构c#编程Microsoft Visual Studio

    一、源码特点         asp.net卷烟物价管理系统 是一套完善的web设计管理系统,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为vs2010,数据库为sqlserver2008,使用c#语言开发 asp.net卷烟物价管理系统VS开发sqlserver数 二、功能介绍 (1)用户管理:对用户信息

    2024年02月11日
    浏览(31)
  • asp.net旅游交流管理信息系统VS开发sqlserver数据库web结构c#编程Microsoft Visual Studio

    一、源码特点         asp.net 旅游交流管理信息系统是一套完善的web设计管理系统,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为vs2010,数据库为sqlserver2008,使用c# 语言开发 asp.net旅游交流网站1 应用技术:asp.net c#+sqlserver 开发工具:vs2010  +sqlser

    2024年02月07日
    浏览(35)
  • asp.net教师调课系统VS开发sqlserver数据库web结构c#编程Microsoft Visual Studio

    一、源码特点         asp.net教师调课管理系统 是一套完善的web设计管理系统,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为vs2010,数据库为sqlserver2008,使用c#语言开发 asp.net教师调课系统VS开发sqlserver数据库w 二、功能介绍 教师调课系统要满足以下

    2024年02月09日
    浏览(37)
  • asp.net个人信息管理系统VS开发sqlserver数据库web结构c#编程Microsoft Visual Studio

    一、源码特点         asp.net个人信息管理系统 是一套完善的web设计管理系统,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为vs2010,数据库为sqlserver2008,使用c#语言 开发 asp.net个人信息管理系统VS开发sqlserver数 二、功能介绍 (1)用户管理:对用户信息

    2024年02月05日
    浏览(41)
  • asp.net审计项目管理系统VS开发sqlserver数据库web结构c#编程Microsoft Visual Studio

    一、源码特点         asp.net审计项目管理系统 是一套完善的web设计管理系统,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为vs2010,数据库为sqlserver2008,使用c#语言 开发 二、功能介绍 (1)科室管理:对科室信息进行添加、删除、修改和查看 (2)权限管

    2024年02月11日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包