C#编写串口助手

2年前基础语言41522
C#编写串口助手 摸鱼累人 于2022-06-13 17:38:08发布 2903 收藏 37 文章标签: c# ui 开发语言 C#编写串口助手

借鉴了很大部分下面文章的内容,我也修改了很多,最后完善成了一个完整的串口助手。 C#编写串口助手 1.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") + " "); //串口接收字符数组,字符依次转换为字符串,0Xxx RecvDataText +="\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"; } } }

相关文章

滤波笔记一:卡尔曼滤波(Kalman Filtering)详解

滤波笔记一:卡尔曼滤波(Kalman Filtering)详解...

机器学习强基计划4-4:详解半朴素贝叶斯分类AODE原理(附Python实现)

机器学习强基计划4-4:详解半朴素贝叶斯分类AODE原理(附Python实现)...

一条sql语句在MySQL的执行流程

一条sql语句在MySQL的执行流程...

wget 的安装与使用(Windows)

wget 的安装与使用(Windows)...

SpringBoot 整合 Elasticsearch (超详细)

SpringBoot 整合 Elasticsearch (超详细)...

【JavaScript】JS实用案例分享:DOM节点转JSON数据 | 标签输入框

【JavaScript】JS实用案例分享:DOM节点转JSON数据 | 标签输入框...