串口助手|上位机软件-串口助手-带登陆界面
前言: 这是我在大三的时候写的一个串口助手,觉得挺好用的就分享给大家。如果有什么bug的话,希望大家多多包涵,毕竟对于C#语言我只是新手。
制作串口助手 串口助手选用Visual C#开发语言和Visual Studio 2012开发平台进行开发,实现的主要功能如下:
- 需要用户名和密码才能登录软件——可以保障用户的隐私
- 可用串口扫描——精确且快速的找到可以打开的串口号
- 保存和读取数据——可以对数据进行保存和读取,方便后期查看
- 显示接收数据的时间——用户可以知道数据到来的时间
- 定时发送——用户可以设定在几秒甚至几小时后发送控制命令
文章图片
登陆界面的源码如下:
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;
namespace SerialCommunicate
{public partial class login : Form
{public login()
{InitializeComponent();
}private void button1_Click(object sender, EventArgs e)
{if (textBox1.Text == "刘小纯" && textBox2.Text == "3118003167")
{MessageBox.Show("欢迎登录系统!", "提示");
this.Hide();
Form1 form1 = new Form1();
form1.Show();
}
else if(textBox1.Text == "刘小纯" && textBox2.Text != "3118003167")
{MessageBox.Show("密码错误!", "提示");
}
else if (textBox1.Text != "刘小纯")
{MessageBox.Show("该用户不存在!", "提示");
}
}private void label3_Click(object sender, EventArgs e)
{}
}
}
主页面源码如下:
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.IO;
//using System.Text.RegularExpressions;
//using System.Threading.Tasks;
//using System.Collections;
namespace SerialCommunicate
{public partial class Form1 : Form
{public Form1()
{InitializeComponent();
serialPort1.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
//串口数据接收事件
serialPort1.Encoding = Encoding.GetEncoding("GB2312");
//串口接收编码
System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;
//
}
//List receivedDatas = new List();
//接收数据泛型数据/*窗体创建初始化函数*/
private void Form1_Load(object sender, EventArgs e)//窗口弹出触发
{ovalShape1.FillColor = Color.Gray;
//小圆圈状态为灰色
SearchAndAddSerialToComboBox(serialPort1, comboBox1);
//可用串口扫描
comboBox2.Text = "115200";
//默认波特率选择
comboBox4.Text = "8";
//默认数据位
comboBox5.Text = "无";
//默认校验位
comboBox3.Text = "1";
//默认停止位
}/*点击打开串口按键触发*/
private void button1_Click(object sender, EventArgs e)
{try
{serialPort1.PortName = comboBox1.Text;
//端口号
serialPort1.BaudRate = Convert.ToInt32(comboBox2.Text);
//波特率
serialPort1.DataBits = Convert.ToInt32(comboBox4.Text.Trim());
//设置数据位,默认为8
switch (comboBox5.Text.Trim())//设置奇偶校验位,默认为无
{case "无":
serialPort1.Parity = Parity.None;
break;
case "奇校验":
serialPort1.Parity = Parity.Odd;
break;
case "偶校验":
serialPort1.Parity = Parity.Even;
break;
default:
serialPort1.Parity = Parity.None;
break;
}
switch(comboBox3.Text .Trim () )//设置停止位,默认为1
{case "1":
serialPort1.StopBits = StopBits .One ;
break ;
case "1.5":
serialPort1.StopBits = StopBits .OnePointFive ;
break ;
case "2":
serialPort1.StopBits= StopBits .Two ;
break;
default:
serialPort1.StopBits= StopBits .None ;
break;
}serialPort1.ReadTimeout = 5000;
//设置超时时间为5S
Control.CheckForIllegalCrossThreadCalls = false;
// 这个类中我们不检查跨线程的调用是否合法
//定义.DataReceived事件的委托,当串口收到数据后触发事件,
//serialPort1.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
//加了会使自动换行和显示时间出BugserialPort1.Open();
//打开串口
button1.Enabled = false;
//打开串口的按键不能使用
button2.Enabled = true;
//关闭串口的按键可以使用
ovalShape1.FillColor = Color.Red;
//串口状态指示灯为红色
}
catch//出错处理
{MessageBox.Show("串口打开错误或波特率设置有误", "小纯提示");
//弹出系统提示框
}
}/*点击关闭串口触发*/
private void button2_Click(object sender, EventArgs e)
{try
{serialPort1.Close();
//关闭串口
button1.Enabled = true;
//打开串口按键可用
button2.Enabled = false;
//关闭串口按键不可用
ovalShape1.FillColor = Color.Gray;
//串口状态指示灯变为灰色
comboBox2.DropDownStyle = ComboBoxStyle.DropDownList;
//当点击关闭串口时,将波特率下拉列表设置为不可编辑
}
catch
{MessageBox.Show("关闭串口错误!", "小纯提示");
}
}/*定义一个扫描可用串口的函数*/
private void SearchAndAddSerialToComboBox(SerialPort MyPort, ComboBox MyBox)
{
//将可用端口号添加到ComboBox
string Buffer;
//缓存
MyBox.Items.Clear();
//清空ComboBox内容
for (int i = 1;
i < 20;
i++)//循环
{try//核心原理是依靠try和catch完成遍历,即是从COM1到COM19逐个打开试试,
//如果能打开,就把这个串口号添加到串口的下拉列表中,后关闭串口,让用户打开
{Buffer = "COM" + i.ToString();
MyPort.PortName = Buffer;
MyPort.Open();
//如果失败,后面的代码不会执行
MyBox.Items.Add(Buffer);
//打开成功,添加至下拉列表
MyPort.Close();
//关闭串口}
catch
{//不添加出错处理,因为这个程序就是为了试错
}
}
}/*串口接收事件*/
private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{if (!radioButton3.Checked)//接收模式为ASCII(字符)
{if (checkBox3.Checked)//显示时间的校验框被选中
{textBox1.AppendText(System.DateTime.Now.ToString("HH:mm:ss")+"\r\n");
//在接收数据的前面一行追加显示时间}
textBox1.AppendText(serialPort1.ReadExisting());
//串口类会自动处理汉字,所以不需要特别转换,textBox1是输出框if (checkBox2.Checked)//自动换行的校验框被选中
try
{textBox1.AppendText(Environment.NewLine);
//接收自动换行
}
catch
{}
}else//接收模式为Hex(数值)
{byte[] data = https://www.it610.com/article/new byte[serialPort1.BytesToRead];
//定义缓冲区,大小为:serialPort1.BytesToRead,因为串口事件触发时有可能收到不止一个字节
serialPort1.Read(data, 0, data.Length);
//从串口中读取数据/*函数原型:foreach(Type t in arry);
Type:需要遍历每一的对象的类型,t:每一个对象,arry:需要遍历的数组*/foreach (byte Member in data)//遍历用法
{string str = Convert.ToString(Member, 16).ToUpper();
//将Member这个数转化为字符串,并且大写
textBox1.AppendText("0x" + (str.Length == 1 ? "0" + str : str) + " ");
//如果str的长度为1的就在其前面添加0如0x0A
}
if (checkBox3.Checked)//显示时间的校验框被选中
{textBox1.AppendText("\r\n"+System.DateTime.Now.ToString("HH:mm:ss"));
}if (checkBox2.Checked)//自动换行的校验框被选中
try
{textBox1.AppendText(Environment.NewLine);
}
catch {
}
}
}/*发送按键触发*/
private void button3_Click(object sender, EventArgs e)
{byte[] Data = https://www.it610.com/article/new byte[1];
//定义一个单字节的数组,用来发数据
if (serialPort1.IsOpen)//判断串口是否打开
{if (textBox2.Text !="")//判断输入框的内容是否为空
{if (!radioButton1.Checked)//发送模式为ASCII(字符)
{try
{serialPort1.Write(textBox2.Text);
//将指定的字符串写入串口
//serialPort1.WriteLine();
//字符串写入
}
catch
{MessageBox.Show("串口数据写入错误", "小纯提示");
}
}else//发送模式为HEX(数值)
{try//如果此时用户输入字符串中含有非法字符(字母,汉字,符号等等,try,catch块可以捕捉并提示)
{/*将用户输入的数字比如1234,转化为0x12,0x34*/
for (int i = 0;
i < (textBox2.Text.Length - textBox2.Text.Length % 2) / 2;
i++)//转换偶数个
{Data[0] = Convert.ToByte(textBox2.Text.Substring(i * 2, 2), 16);
//转换(一次处理两个数字?)
serialPort1.Write(Data, 0, 1);
//将转化好的一个字节写入串口
}
if (textBox2.Text.Length % 2 != 0)//如果数据的长度为奇数,需要单独处理最后一位
{Data[0] = Convert.ToByte(textBox2.Text.Substring(textBox2.Text.Length - 1, 1), 16);
//单独处理最后一个字符
serialPort1.Write(Data, 0, 1);
//写入
}
}
catch
{MessageBox.Show("数据转换错误,请输入数字。", "小纯提示");
}
}
}
}
}/*扫描按键触发*/
private void button5_Click(object sender, EventArgs e)
{SearchAndAddSerialToComboBox(serialPort1, comboBox1);
//扫描并将可用串口添加至下拉列表
}/*清空按键触发*/
private void button4_Click(object sender, EventArgs e)
{textBox1.Text = "";
}/*定时发送校验框被选中*/
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{if (checkBox1.Checked)//定时发送校验框被选中
{try
{//选择自动发送
numericUpDown1.Enabled = false;
//启动定时发送后不能修改定时时间
timer1.Interval = (int)numericUpDown1.Value;
// * 1000;
//设置定时器中断时间,*1000将单位转化为秒
timer1.Start();
//启动定时器
}
catch {
}}
else//定时发送校验框不被选中
{try
{//选择不自动发送
numericUpDown1.Enabled = true;
////停止定时发送后能修改定时时间
timer1.Stop();
//停止定时
}
catch
{timer1.Stop();
//出错的话再次停止定时
MessageBox.Show("停止自动发送错误", "小纯提示");
}
}}/*定时时间到,定时发送数据*/
private void timer1_Tick(object sender, EventArgs e)
{button3_Click(button3, new EventArgs());
//调用发送按钮的回调函数
}/*清空发送框*/
private void button6_Click_1(object sender, EventArgs e)
{textBox2.Clear();
}/*点击波特率设置下列表*/
private void comboBox2_SelectedIndexChanged(object sender, EventArgs e)
{if (comboBox2.Text.Equals("custom"))//当选择custom项时列表属性发生改变
{try
{// comboBox2.DropDownStyle = ComboBoxStyle.DropDown;
comboBox2.DropDownStyle = ComboBoxStyle.Simple;
//将属性更改为可以编辑}
catch
{MessageBox.Show("设置波特率时错误!", "小纯提示");
}
}
}/*点击保存数据按钮*/
private void button7_Click(object sender, EventArgs e)
{/*saveFileDialog1 为保存文件的对话框,StreamWriter是专门用来处理文本文化的类,可以方便的向文本文件中写入字符串*/
saveFileDialog1 = new SaveFileDialog();
//初始化此类的新实例
saveFileDialog1.Filter = "(*.txt)|*.txt";
//只允许保存为TXT文本
// try
//{if (saveFileDialog1.ShowDialog() == DialogResult.OK)//页面弹出判断框是否点击确定按钮
{StreamWriter streamWriter = new StreamWriter(saveFileDialog1.FileName, false);
streamWriter.Write(this.textBox1.Text);
//将输出框的字符串写入TXT文本
streamWriter.Close();
//关闭流
}
// }// catch { MessageBox.Show("先打开串口!", "小纯提示");
}
}/*点击读入文件按钮*/
private void button8_Click(object sender, EventArgs e)
{OpenFileDialog openFileDialog1 = new OpenFileDialog();
openFileDialog1.Filter = "All files(*.*)|*.*|txt file (*.txt)|*.txt";
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{string logpath = openFileDialog1.FileName;
using (StreamReader sr = new StreamReader(logpath, Encoding.GetEncoding("gb2312")))
{string oneLineInfo = string.Empty;
//读取到的每行内容
while (sr.EndOfStream != true)
{oneLineInfo = oneLineInfo + "\r\n" + sr.ReadLine();
//按行读取
}
sr.Close();
textBox1.Text = oneLineInfo;
}
}
}
}
}
【串口助手|上位机软件-串口助手-带登陆界面】登陆界面与主页面的切换:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
namespace SerialCommunicate
{static class Program
{///
/// 应用程序的主入口点。
///
[STAThread]
static void Main()
{Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
//Application.Run(new Form1());
Application.Run(new login());
//若不需要登陆界面就把这个注释掉,取消上面的注释
}
}
}
推荐阅读
- 驱动调试小结
- USB转串口|USB转四串口芯片CH9344
- 小程序商家怎么用小程序数据助手
- Android通过JNI操作串口
- Java|Java串口通信(RXTX)
- RXTX|Java调用RXTX库与Arduino进行串口通讯需注意的编程问题
- Android通过JNI操作串口《一》
- java串口通信rxtx-2.1-7-bins-r2方式
- qq手机助手电脑版|qq手机助手电脑版 v5.1.2 官方版
- 众为兴机械手与上位机交互调试