学习有几天时间了,跟着大神的指导和手册以及万能的度娘。下面记录下串口调试助手的开发,还并不是很完善,但是基本功能还是有的。一下就不一步步记录开发过程了,贴上代码,以及重点和需要注意的地方。
最终代码如下:
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; namespace Lesson5 { public partial class Form1 : Form { public Form1() { InitializeComponent(); System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false; } private void Form1_Load(object sender, EventArgs e) { SearchAndAddSerialToComboBox(serialPort1, comboBox1); /*****************非常重要************************/ serialPort1.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);//必须手动添加事件处理程序 } //串口接收函数封装 private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)//串口数据接收事件 { if (!checkBox1.Checked)//如果没有勾选,字符模式 { string str = serialPort1.ReadExisting();//字符串方式读 textBox1.AppendText(str);//添加内容 } else//接收模式为数值接收 { byte data; data = (byte)serialPort1.ReadByte();//此处需要强制类型转换,将(int)类型数据转换为(byte类型数据,不必考虑是否会丢失数据 string str = Convert.ToString(data, 16).ToUpper();//转换为大写十六进制字符串 textBox1.AppendText("0x" + (str.Length == 1 ? "0" + str : str) + " ");//空位补“0” } } //扫描串口函数封装 private void SearchAndAddSerialToComboBox(SerialPort MyPort, ComboBox MyBox) { //将可用端口号添加到ComboBox string Buffer; //缓存 MyBox.Items.Clear(); //清空ComboBox内容 for (int i = 1; i < 20; i++) //循环这里只扫描1-19 { try //核心原理是依靠try和catch完成遍历 { Buffer = "COM" + i.ToString(); MyPort.PortName = Buffer; MyPort.Open(); //如果失败,后面的代码不会执行 // MyString[count] = Buffer; MyBox.Items.Add(Buffer); //打开成功,添加至下俩列表 MyPort.Close(); //关闭 } catch//出错了什么也不做继续循环 { } } } //扫描串口按钮 private void button3_Click(object sender, EventArgs e) { SearchAndAddSerialToComboBox(serialPort1, comboBox1); //设计上根据使用到的串口和下拉框决定传入参数 } //清空接收按钮 private void button5_Click(object sender, EventArgs e) { textBox1.Text = ""; } //清空发送按钮 private void button4_Click(object sender, EventArgs e) { textBox2.Text = ""; } //打开关闭串口按钮 private void button1_Click(object sender, EventArgs e) { if (serialPort1.IsOpen) //串口打开就关闭 { try { serialPort1.Close(); } catch { } //确保万无一失 button1.ForeColor = Color.Black; //button1.BackColor = Color.Black; button1.Text = "打开串口"; } else { try { serialPort1.PortName = comboBox1.Text; //端口号 serialPort1.BaudRate = Convert.ToInt32(comboBox2.Text, 10);//十进制数据转换 serialPort1.Open(); //打开端口 button1.ForeColor = Color.Red; //button1.BackColor = Color.Red; button1.Text = "关闭串口"; } catch { MessageBox.Show("串口打开失败", "错误"); } } } //发送按钮 private void button2_Click(object sender, EventArgs e) { byte[] Data = new byte[1];//定义一个变量 //判断串口是否打开,如果打开执行下一步操作 //如果发送的数据不是空的 if (serialPort1.IsOpen && textBox2.Text != "") { if (!checkBox1.Checked)//如果发送模式是字符模式 { try { serialPort1.WriteLine(textBox2.Text);//写数据 } catch (Exception err) { MessageBox.Show("串口数据写入错误", "错误");//出错提示 serialPort1.Close(); } } else { //总长度除以2得到有多少对字符 for (int i = 0; i < textBox2.Text.Length / 2; i++) { //每次取两位字符组成一个16进制 Data[0] = Convert.ToByte(textBox2.Text.Substring(i * 2, 2), 16); serialPort1.Write(Data, 0, 1);//循环发送(如果输入字符为0A0BB,则只发送0A,0B) } if (textBox2.Text.Length % 2 != 0)//剩下一位单独处理 { Data[0] = Convert.ToByte(textBox2.Text.Substring(textBox2.Text.Length - 1, 1), 16);//单独发送B(0B) serialPort1.Write(Data, 0, 1);//发送 } } } } } }
代码基本上都有注释,仅供参考。
最终界面功能调试如下图:
界面比较简单,实现功能如下:
1、串口扫描。
2、打开、关闭串口。
3、16进制及字符型数据的发送和接收。
4、发送区域和接受区域清空按钮。
5、波特率是在textbox中集合中加的几个常用的波特率,这个添加起来也很简单。
6、在打开软件自行扫描到串口后暂时没办法让其直接显示有效的串口号,需要手动选择。
7、波特率在打开软件里面没有自动加上一个波特率,这个比较好修改。
不足之处:
1、字符型数据默认是开启了回车换行,不添加回车换行还需要在代码上稍作修改。
2、串口扫描功能在打开软件的时候会自动执行,不过热插拔扫描的话还是需要一个按键,暂时还没能力集成到下拉框中。
注意的问题及新知识点:
1、打开和关闭串口有颜色变化,在串口关闭的状态文本显示黑色的“打开串口”,打开后显示红色的“关闭串口”,这是比较使用及人性化的设计。
2、添加了checkbox选择显示16进制或者字符,发送也是一样可以选择发送字符或者16进制数据。
3、接收文本框和发送文本框都有滚动条,这个在文本框的属性里面选择滚动条的垂直模式即可。
4、在开始调试的时候报了一个错误,找这个问题找了很久,最终在度娘上找到答案,同时感谢解决我这个问题的贴子。我这里再记上一笔,希望能帮到更多的人。
上图是在调试之前遇到的一个问题。产生这个错误的原因是少了一行代码:
System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;
这个是窗口初始化紧接着需要添加的。添加之后就没有问题了。代码懂得不多,C#是门简单强大的语言,但是最终的目的还是编写一个合适的上位机软件,所以目前就不深究C#本身,先以最快最有效的方式达到目的再说,以后再慢慢深究。
以上是及上一贴后学习到并开发的内容。
By Urien 2018年2月15日 10:55:06