上面是制作出来的助手软件样式,所有代码放在下面,可以直接复制粘贴使用,里面的每行代码我都有注释,会有两个引用文件,可以私信我获取。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace text
{
public partial class From1 : Form
{
public From1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
portNumber.SelectedIndex = 1;
baudRate.SelectedIndex = 5;
checkBit.SelectedIndex = 0;
dataBits.SelectedIndex = 3;
stopBit.SelectedIndex = 0;
Console.WriteLine("\\0");
}
SerialPort serialPort = new SerialPort();
//串口信息配置
public void SetSerialPort()
{
//获取当前计算机所有的串行端口名
string[] serialProtArray = SerialPort.GetPortNames();
//端口名,如COM1
if (portNumber.Text !="") {
serialPort.PortName = portNumber.Text;
}
//波特率
if (baudRate.Text != "")
{
serialPort.BaudRate = int.Parse(baudRate.Text);
}
//奇偶校验
if (checkBit.Text == "无NONE")
{
serialPort.Parity = Parity.None;
}else if (checkBit.Text == "奇ODD")
{
serialPort.Parity = Parity.Odd;
}else if (checkBit.Text == "偶EVEN")
{
serialPort.Parity = Parity.Even;
}
//数据位
if (dataBits.Text !="")
{
serialPort.DataBits = int.Parse(dataBits.Text);
}
//停止位
if (stopBit.Text =="1")
{
serialPort.StopBits = StopBits.One;
}else if (stopBit.Text == "2")
{
serialPort.StopBits = StopBits.Two;
}
}
//打开串口
public void Open()
{
//更改串口信息
SetSerialPort();
if (portNumber.Text !="" && checkBit.Text !="" && dataBits.Text != "" && baudRate.Text != "" && dataBits.Text != "" && stopBit.Text != "")
{
//打开串口
serialPort.Open();
//Console.WriteLine("串口打开啦");
serialPort.DataReceived += SerialPort_DataReceived; //引入接收消息事件
state.Text = "打开";
}
}
//关闭串口
public void Close1()
{
serialPort.Close();
state.Text = "关闭";
}
//接收消息事件
private List<byte> reciveBuffer = new List<byte>(); //接收数据缓存(以字节方式缓存)
private int reciveCount = 0; //接收数据计数
private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
if (isRxShow == false) { return; } //暂停按钮切换
CheckForIllegalCrossThreadCalls = false; //解决跨线程问题
byte[] dataTemp = new byte[serialPort.BytesToRead]; //读取有效数据 BytesToRead
serialPort.Read(dataTemp,0,dataTemp.Length); //从第0位开始读取接收到的数据长度
reciveBuffer.AddRange(dataTemp); //缓存读取的数据并将所有数据拼接显示在页面上
reciveCount += dataTemp.Length; //接收计数
//异步线程更新
this.Invoke(new EventHandler(delegate
{
//接收计数
acceptNumber.Text = reciveCount.ToString(); //页面显示接收计数
//判断传输数据格式
if (!sixteen1.Checked)
{
//2.编码格式选择
string str = Encoding.GetEncoding("gb2312").GetString(dataTemp); //未选中十六进制时,转换为字符串显示
//3.0x00 -> \0 结束 不会显示
str=str.Replace("\0", "\\0"); //显示内容包含\0无法解析,转换成\\0之后就会解析成\0
textBox1.AppendText(str); //将收到的数据拼接在一起显示在页面上面
}
else
{
//十六进制状态数据显示
textBox1.AppendText(Transform.ToHexString(dataTemp," ")); //选中十六进制时,接收框的数据转换为十六进制显示
}
}));
}
//打开关闭串口按钮
private void openOrClose_Click(object sender, EventArgs e)
{
if (serialPort.IsOpen == false)
{
Open();
openOrClose.Text = "关闭串口"; //打开关闭按钮切换
}
else
{
if (animationSend.Checked == true)
{
MessageBox.Show("请先关闭自动发送"); //如果打开串口期间自动发送选中不允许关闭串口
}
else
{
Close1();
openOrClose.Text = "打开串口";
}
}
}
//选择路径按钮
private void changePath_Click(object sender, EventArgs e)
{
if (serialPort.IsOpen == false)
{
MessageBox.Show("请先打开串口!");
}
else
{
dialog.Multiselect = true; // 是否选择多个文件
dialog.Title = "请选择文件夹"; //选择文件框头部提示
dialog.Filter = "所有文件(*.*)|*.*"; //文件类型
if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
pathInp.Text = dialog.FileName; //文件路径
}
}
}
//手动清空按钮
private void handEmpty_Click(object sender, EventArgs e)
{
if (serialPort.IsOpen == false)
{
MessageBox.Show("请先打开串口!");
}
else
{
textBox1.Text = ""; //清空接收区内容
reciveBuffer.Clear(); //清空接收缓存区数据
reciveCount = 0; //清空接收总数
acceptNumber.Text = "0"; //清空接收计数
}
}
//暂停按钮
private bool isRxShow = true; //暂停按钮切换
private void pause_Click(object sender, EventArgs e)
{
if (serialPort.IsOpen == false)
{
MessageBox.Show("请先打开串口!");
}
else
{
//暂停按钮切换
if (isRxShow == true)
{
pause.Text = "取消暂停";
isRxShow = false;
}
else
{
isRxShow = true;
pause.Text = "暂停";
}
}
}
//保存数据按钮
private void saveData_Click(object sender, EventArgs e)
{
if (serialPort.IsOpen == false)
{
MessageBox.Show("请先打开串口!");
}
else
{
if (textBox1.Text == "")
{
MessageBox.Show("保存的数据不能为空");
}
else
{
File.WriteAllText(pathInp.Text,textBox1.Text); //保存当前接收框数据到选中的文件中
}
}
}
//打开文件按钮
OpenFileDialog dialog = new OpenFileDialog(); //导入文件打开控件
private void openFile_Click(object sender, EventArgs e)
{
if (serialPort.IsOpen == false)
{
MessageBox.Show("请先打开串口!");
}
else
{
dialog.Multiselect = true; // 是否选择多个文件
dialog.Title = "请选择文件夹"; //文件打开框头部提示
dialog.Filter = "所有文件(*.*)|*.*"; //文件格式选择
if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
filePath.Text = dialog.FileName; //文件路径显示在页面上
}
}
}
//手动发送按钮
private List<byte> sendBuffer = new List<byte>(); //发送数据缓存
private int sendCount = 0; //发送数据总数
private void sendData()
{
serialPort.Write(sendBuffer.ToArray(),0,sendBuffer.Count); //发送数据缓存区的数据
sendCount += sendBuffer.Count; //发送数据总数显示
sendNumber.Text = sendCount.ToString(); //发送数据转换成字符串显示在页面上
}
private void handSend_Click(object sender, EventArgs e)
{
if (serialPort.IsOpen == false)
{
MessageBox.Show("请先打开串口!");
}
else
{
if (textBox2.Text !="")
{
Console.WriteLine(Transform.ToHexString(sendBuffer.ToArray()));
sendData();//调用发送方法
}else
{
MessageBox.Show("发送数据不能为空!");
}
}
}
//清空发送按钮
private void clearSend_Click(object sender, EventArgs e)
{
if (serialPort.IsOpen == false)
{
MessageBox.Show("请先打开串口!");
}
else
{
textBox2.Text = ""; //清空发送区内容
sendBuffer.Clear(); //清空发送区缓存
sendCount = 0; //清空发送总数
sendNumber.Text = "0"; //发送总数显示清零
}
}
//发送文件按钮
private void sendFile_Click(object sender, EventArgs e)
{
if (serialPort.IsOpen == false)
{
MessageBox.Show("请先打开串口!");
}
else
{
if (filePath.Text == "")
{
MessageBox.Show("请最少选择一个文件");
}
else
{
string str = System.IO.File.ReadAllText(filePath.Text); //读取文件内容并发送
//byte[] byteArray = System.Text.Encoding.Default.GetBytes(str);
//str = Encoding.GetEncoding("gb2312").GetString(byteArray).Replace("\0", "\\0");
//Console.WriteLine(str);
serialPort.Write(str);
}
}
}
//接收配置十六进制选择转换数据
private void sixteen1_CheckedChanged(object sender, EventArgs e)
{
if(serialPort.IsOpen == false)
{
MessageBox.Show("请先打开串口!");
//sixteen1.Checked = false;
}
else
{
if (textBox1.Text == "") return;
if (sixteen1.Checked)
{
textBox1.Text = Transform.ToHexString(reciveBuffer.ToArray(), " "); //选中状态下接收区数据转换成十六进制显示
}
else
{
textBox1.Text = Encoding.GetEncoding("gb2312").GetString(reciveBuffer.ToArray()).Replace("\0", "\\0"); //非选中状态下接收区数据使用gb2312编码格式将接收区内容显示为普通字符串
}
}
}
//接收配置自动清空按钮
private void animationClear1_CheckedChanged(object sender, EventArgs e)
{
if (serialPort.IsOpen == false)
{
//animationClear1.Checked = false;
MessageBox.Show("请先打开串口!");
}
else
{
if (animationClear1.Checked)
{
timer1.Start(); //启动定时器
}
else
{
timer1.Stop(); //关闭定时器
}
}
}
private void timer1_Tick(object sender, EventArgs e)
{
//接受数据大于4096时自动清空接收区
if (textBox1.Text.Length >4096)
{
textBox1.Text = "";
reciveBuffer.Clear();
acceptNumber.Text = "";
}
}
//发送框操作
//光标离开发送框后检验数据格式是否正确
private void textBox2_Leave(object sender, EventArgs e)
{
//发送框失去焦点时判断十六进制框是否选中状态
if (sixteen2.CheckState == CheckState.Checked)
{
//数据发送时判断输入框是否是十六进制格式
if ( DataEncoding.IsHexString(textBox2.Text.Replace(" ","")))
{
//是十六进制格式
sendBuffer.Clear(); //清空发送缓存区(初始化)
sendBuffer.AddRange(Transform.ToBytes(textBox2.Text.Replace(" ", ""))); //将发送区内容转化成字节存到发送缓存区
}
else
{
MessageBox.Show("请输入正确的十六进制数据!");
textBox2.Select(); //光标聚焦到发送输入框
}
}
else
{
sendBuffer.Clear(); //清空发送缓存区(初始化)
sendBuffer.AddRange(Encoding.GetEncoding("gb2312").GetBytes(textBox2.Text)); //将发送内容利用gb2312编码格式转化为普通字符串缓存到发送缓存区
}
}
private void textBox2_TextChanged(object sender, EventArgs e)
{
//数据切换时会出现问题,0x00转换
}
//发送配置十六进制切换按钮
private void sixteen2_CheckedChanged(object sender, EventArgs e)
{
if (serialPort.IsOpen == false)
{
MessageBox.Show("请先打开串口!");
//sixteen2.Checked = false;
}
else
{
//如果发送框为空,直接跳出
if (textBox2.Text == "") { return; }
if (sixteen2.Checked == true)
{
textBox2.Text = Transform.ToHexString(sendBuffer.ToArray(), " "); //如果选中,将发送缓存区的数据转换成十六进制 后面空格代表每个字符以空格隔开,并赋给发送框
}
else
{
textBox2.Text = Encoding.GetEncoding("gb2312").GetString(sendBuffer.ToArray()).Replace("\0", "\\0");//未选中,将缓存区内容转化为普通字符串赋给发送框
}
}
}
//自动发送选框
private void animationSend_CheckedChanged(object sender, EventArgs e)
{
if (serialPort.IsOpen == false)
{
animationSend.Checked = false;
MessageBox.Show("请先打开串口!");
}
else
{
if (animationSend.Checked)
{
if (textBox2.Text == "")
{
MessageBox.Show("发送数据不能为空!");
animationSend.Checked = false;
}
else
{
timer2.Interval = int.Parse(time.Text); //自动发送周期
timer2.Start();//调用定时器
}
}
else
{
timer2.Stop();//关闭定时器
}
}
}
private void timer2_Tick(object sender, EventArgs e)
{
sendData(); //调用发送事件
}
}
}
以上是个人见解,如有不对之处,望各位大佬指出。