> 文档中心 > C#编写串口助手

C#编写串口助手


C#编写串口助手

借鉴了很大部分下面文章的内容,我也修改了很多,最后完善成了一个完整的串口助手。
C#编写串口助手
1.UI设置
UI截图

①创建Windows窗口应用程序。

文件—新建—项目,选择Visual C#,选择Windows窗体应用程序,名称:项目名称"调试串口助手",位置:保存项目的路径,解决方案:创建新的解决方案(添加到解决方案),解决方案名称:自动生成与项目名称相同,框架:.NET Framework 4.7,默认勾选为解决方案创建目录,点击确定。
在这里插入图片描述
创建新项目后可以看到Form1.cs[设计],这是自动生成的窗体应用,在这个页面利用左边工具栏和对应UI的属性可以设计UI。
在这里插入图片描述
找到解决中的Form1.cs,右键->查看代码,可以代码文件。

②创建窗体的界面。

Form1窗体添加三个GroupBox控件,Text分别设置为:串口设置、接收数据、发送数据。

Form1窗体添加五个Lable控件,Text分别设置为:串口号:、波特率:、停止位:、奇偶校验:、数据位:。

Form1窗体添加五个ComoBox控件,Name分别设置为:cbxCOMPort、cbxBaudRate、cbxStopBits、cbxParity、cbxDataBits。

Form1窗体添加两个RadioButton控件,Text分别设置为:字符显示、HEX显示,Name分别设置为:rbnChar、rbnHex,

Checked分别为:True、False。

Form1窗体添加八个Button控件,Text分别设置为:检测串口、打开串口、清空数据、发送数据、AT、ATI8、选择文件、发送文件。
注:笔者截图里发送AT命令远不止两个按钮是因为此类命令代码非常相似,于是就只写了两个。

Name分别设置为:btnCheckCom、btnOpenCom、btnClearData、btnSendData。

Form1窗体添加三个TextBox控件,Name分别设置为:tbxRecvData、tbxSendData、filename_test_box,filename_test_box、tbxRecvData和的ReadOnly属性设置为True。

Fomr1窗体的AcceptButton属性设置为btnSendData,在窗体上回车关联到发送数据按钮。
在这里插入图片描述

③代码编写。

代码+注释如下:

//新手可以下载一个vspn创建虚拟串口搭配使用:)using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Windows.Forms;using System.IO.Ports;using System.IO;namespace 调试串口工具{    public partial class Form1 : Form    { bool isHex = false;//十六进制显示标志位 bool isOpen = false;//打开串口标志位 bool isSetProperty = false;//属性设置标志位 bool isfiletranfers = false;//文件传输标志位 SerialPort serialportcom = null; public Form1() {     InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) {     //设置窗口大小     this.MaximizeBox = true;    //影藏最大化按钮     this.MaximumSize = this.Size;    //固定窗口尺寸最大为当前尺寸     this.MinimumSize = this.Size;    //固定窗口尺寸最小为当前尺寸     //Form1.refresh();     //设置波特率     cbxBaudRate.Items.Add("1200");     cbxBaudRate.Items.Add("2400");     cbxBaudRate.Items.Add("4800");     cbxBaudRate.Items.Add("9600");     cbxBaudRate.Items.Add("19200");     cbxBaudRate.Items.Add("38400");     cbxBaudRate.Items.Add("115200");     cbxBaudRate.SelectedIndex = 3;     //列出停止位     cbxStopBits.Items.Add("0");     cbxStopBits.Items.Add("1");     cbxStopBits.Items.Add("1.5");     cbxStopBits.Items.Add("2");     cbxStopBits.SelectedIndex = 1;     //列出数据位     cbxDataBits.Items.Add("8");     cbxDataBits.Items.Add("7");     cbxDataBits.Items.Add("6");     cbxDataBits.Items.Add("5");     cbxDataBits.SelectedIndex = 0;     //列出奇偶检验     cbxParity.Items.Add("无");     cbxParity.Items.Add("奇校验");     cbxParity.Items.Add("偶校验");     cbxParity.SelectedIndex = 0;     //默认接受到的数据用字符显示     rbnChar.Checked = true; } private void btnCheckCom_Click(object sender, EventArgs e) {     bool comExistence = false;//有可用串口标志位     cbxCOMPort.Items.Clear();     //将读取到的串口号写入选项框     foreach (string sPortName in SerialPort.GetPortNames())     {  try  {     cbxCOMPort.Items.Add(sPortName);      comExistence = true;  }  catch (Exception)  {      continue;  }     }     if (comExistence)     {  cbxCOMPort.SelectedIndex = 0;     }     else     {  MessageBox.Show("没有找到可用的串口!", "错误提示");     } } private bool checkPortSetting()//检测串口设置 {     if (cbxCOMPort.Text.Trim() == "") return false;     if (cbxBaudRate.Text.Trim() == "") return false;     if (cbxDataBits.Text.Trim() == "") return false;     if (cbxParity.Text.Trim() == "") return false;     if (cbxStopBits.Text.Trim() == "") return false;     return true; } private bool CheckSendData()//检测发送数据是否输入 {     if (tbxSendData.Text.Trim() == "") return false;     return true; } private bool CheckFileSendData() {     if (filename_test_box.Text.Trim() == "") return false;     return true; }  private void SetPortProperty()//设置串口的属性 {     //创建串口     serialportcom = new SerialPort();     //设置串口名     serialportcom.PortName = cbxCOMPort.Text.Trim();     //设置串口波特率     serialportcom.BaudRate = Convert.ToInt32(cbxBaudRate.Text.Trim());     //设置串口数据位     serialportcom.DataBits = Convert.ToInt32(cbxDataBits.Text.Trim());     //设置串口停止位     if (cbxStopBits.Text.Trim() == "0")     {  serialportcom.StopBits = StopBits.None;     }     if (cbxStopBits.Text.Trim() == "1")     {  serialportcom.StopBits = StopBits.One;     }     if (cbxStopBits.Text.Trim() == "1.5")     {  serialportcom.StopBits = StopBits.OnePointFive;     }     if (cbxStopBits.Text.Trim() == "2")     {  serialportcom.StopBits = StopBits.Two;     }     //设置校验     if (cbxParity.Text.Trim() == "无")     {  serialportcom.Parity = Parity.None;     }     if (cbxParity.Text.Trim() == "奇校验")     {  serialportcom.Parity = Parity.Odd;     }     if (cbxParity.Text.Trim() == "偶校验")     {  serialportcom.Parity = Parity.Even;     }     serialportcom.ReadTimeout = 100000;//设置超时读取时间     serialportcom.RtsEnable = true;     serialportcom.DataReceived += new SerialDataReceivedEventHandler(serialportcom_DataReceived);//接受数据事件监听     if (rbnHex.Checked)     {  isHex = true;     }     else     {  isHex = false;     } } private void btnOpenCom_Click(object sender, EventArgs e) {     if (isOpen == false)     {  if (!checkPortSetting())//检测串口设置  {      MessageBox.Show("串口未设置", "错误提示");      return;  }  if (!isSetProperty)  {      SetPortProperty();      isSetProperty = true;  }  try  {      serialportcom.Open();      isOpen = true;      btnOpenCom.Text = "关闭串口";      //串口打开后,相关的串口设置按钮不再可用      cbxCOMPort.Enabled = false;      cbxBaudRate.Enabled = false;      cbxDataBits.Enabled = false;      cbxStopBits.Enabled = false;      cbxParity.Enabled = false;      rbnChar.Enabled = false;      rbnHex.Enabled = false;      btnCheckCom.Enabled = false;  }  catch (Exception)  {      isSetProperty = false;//串口设置标志位设置为false      isOpen = false; //串口打开标志位设置为false      MessageBox.Show("串口无效或被占用", "错误提示");//打开失败提示消息框  }     }     else//之前串口是打开的,则执行else语句块     {  try  {      serialportcom.Close();//关闭串口      isOpen = false;    //串口打开标志位设置为false      btnOpenCom.Text = "打开串口";    //btnOpenCom的文本设置为“打开串口”      cbxCOMPort.Enabled = true;    //串口号使能      cbxBaudRate.Enabled = true;    //波特率      cbxDataBits.Enabled = true;    //数据位      cbxStopBits.Enabled = true;    //停止位      cbxParity.Enabled = true;    //校验      rbnChar.Enabled = true;    //字符型      rbnHex.Enabled = true;    //Hex型      btnCheckCom.Enabled = true;//检测串口  }  catch (Exception)  {      MessageBox.Show("关闭串口时发生错误", "错误提示");    //关闭失败提示消息框  }     } } private void button2_Click(object sender, EventArgs e)//选择文件时间监听 {     //新建一个文件对话框     OpenFileDialog pOpen = new OpenFileDialog();//创建文件变量     //设置对话框标题     pOpen.Title = "打开想要传输的文件";     //设置打开文件类型     pOpen.Filter = "所有文件(*.*)|*.*";     //监测文件是否存在     pOpen.CheckFileExists = true;     //文件打开后执行以下程序     if (pOpen.ShowDialog() == DialogResult.OK)     {  filename_test_box.Text = pOpen.FileName;  isfiletranfers = true;     } } private void button1_Click(object sender, EventArgs e)//发送文件 {     if (isOpen)     {  try  {      string filenameee = filename_test_box.Text;//获取文件名      FileStream fs = File.OpenRead(@filenameee);//新建文件流      byte[] filedata = new byte[fs.Length];//创建文件内容大小的字节空间      fs.Read(filedata, 0, filedata.Length);//将文件内容写入字节空间      string writest = Encoding.Default.GetString(filedata);      filedata = Encoding.Default.GetBytes(writest);      serialportcom.Write(filedata, 0, filedata.Length);//传输字节数组//判断文件传输完毕,文件传输标志位变为false      if (serialportcom.BytesToRead == 0)      {   isfiletranfers = false;      }  }  catch  {      MessageBox.Show("发送数据时发生错误!", "错误提示");      return;  }     }     else     {  MessageBox.Show("串口未打开", "错误提示");     }     if (!CheckFileSendData())     {  MessageBox.Show("请输入要发送的数据", "错误提示");     } } private void btnSendData_Click(object sender, EventArgs e) {     if (isOpen)    //串口打开状态     {  try  {      Encoding sendData = System.Text.Encoding.GetEncoding(936);//使用合适字符编码,936表示GB2312      byte[] bytesSD = Encoding.Default.GetBytes(tbxSendData.Text+"\r\n");//创建字节空间,并写入待传输数据      tbxRecvData.Text += tbxSendData.Text + "\r\n";      serialportcom.Write(bytesSD, 0, bytesSD.Length);    //串口发送数据      tbxRecvData.Text += "发送成功" + "\r\n";  }  catch  {      MessageBox.Show("发送数据时发生错误!", "错误提示");      return;  }     }     else     {  MessageBox.Show("串口未打开", "错误提示");     }     if (!CheckSendData())     {  MessageBox.Show("请输入要发送的数据", "错误提示");     } } private void serialportcom_DataReceived(object sender, SerialDataReceivedEventArgs e) {     System.Threading.Thread.Sleep(100); //延时100ms,等待接收完数据     //MessageBox.Show("收到数据");     this.Invoke((EventHandler)(delegate    //this.Invoke是跨线程访问ui的方法,也是文本的范例     {  try  {      if (isHex == false)      {   tbxRecvData.Text += "正在接收数据...." + "\r\n";   byte[] a = new byte[serialportcom.BytesToRead];//创建一个缓冲区数据大小的字节空间   serialportcom.Read(a, 0, a.Length);    //读取缓冲区的数据,并将其写入a的空间中   string recvstring = Encoding.Default.GetString(a);//解码出a中的字符信息   tbxRecvData.Text += recvstring + "\r\n";      }      else      {   Byte[] ReceivedData = new Byte[serialportcom.BytesToRead];    //定义并初始化字符数组,sp.ByteToRead串口读字符串长度   serialportcom.Read(ReceivedData, 0, ReceivedData.Length);    //字符数组读取串口数据   String RecvDataText = null;    //定义字符串   for (int i = 0; i < ReceivedData.Length; i++)   {RecvDataText += ("0X" + ReceivedData[i].ToString("X2") + " ");    //串口接收字符数组,字符依次转换为字符串,0XxxRecvDataText +="\r\n";   //X2:X是十六进制,2是两位。(A X2--0X0A,A X---0XA)   }   tbxRecvData.Text += RecvDataText;     //转换后的字符串显示到tbxRecvData上面      }  }  catch (Exception)  {      MessageBox.Show("数据接受失败");  }  serialportcom.DiscardInBuffer();    //清除串口接收缓冲区数据     })); } private void btnClearData_Click_1(object sender, EventArgs e)//清空数据 {     tbxRecvData.Text = "";     tbxSendData.Text = "";     filename_test_box.Text = ""; } private void btnAT1_Click(object sender, EventArgs e) {     Encoding sendData = System.Text.Encoding.GetEncoding(936);//使用合适字符编码,936表示GB2312     byte[] bytesSD = Encoding.Default.GetBytes("AT" + "\r\n");//创建字节空间,并写入待传输数据     tbxRecvData.Text += btnAT1.Text + "\r\n";     serialportcom.Write(bytesSD, 0, bytesSD.Length);    //串口发送数据     tbxRecvData.Text += "发送成功" + "\r\n"; } private void btnAT2_Click(object sender, EventArgs e) {     Encoding sendData = System.Text.Encoding.GetEncoding(936);//使用合适字符编码,936表示GB2312     byte[] bytesSD = Encoding.Default.GetBytes("ATI8" + "\r\n");//创建字节空间,并写入待传输数据     tbxRecvData.Text += btnAT2.Text + "\r\n";     serialportcom.Write(bytesSD, 0, bytesSD.Length);    //串口发送数据     tbxRecvData.Text += "发送成功" + "\r\n"; }    }}