软件功能:
使用C#实现PC串口通讯
支持定时发送
支持16进制(hex) ASCII UTF-8 Unicode 四种编码格式
支持配置文件的保存和读取
可以可以显示发送历史
可以统计总的发送字节数和接受字节数
软件界面:
C#源码:
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;using System.IO.Ports;using System.Threading;using System.IO;using System.Xml.Serialization; namespace 串口调试工具{ ???public partial class Form1 : Form ???{ ???????private SerialPort sp = new SerialPort();//链接对象 ???????Config config = new Config();//配置文件 ????????public Form1() ???????{ ???????????InitializeComponent(); ???????} ????????private void Form1_Load(object sender, EventArgs e) ???????{ ???????????//获取串口列表 ???????????string[] comList = SerialPort.GetPortNames(); ???????????if (comList.Length == 0) ???????????{ ???????????????MessageBox.Show("无可用串口"); ???????????????return; ???????????} ???????????foreach (var com in comList) ???????????{ ???????????????cmbComList.Items.Add(com); ???????????} ?????????????//添加波特率 ???????????int[] baudRate = { 300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 43000, 56000, 57600, 115200 }; ???????????foreach (var br in baudRate) ???????????{ ???????????????cmbBautRade.Items.Add(br); ???????????} ????????????//添加数据位 ???????????int[] dataBits = { 8, 7, 6, 5 }; ???????????foreach (var db in dataBits) ???????????{ ???????????????cmbDataBits.Items.Add(db); ???????????} ????????????//添加停止位 ???????????int[] stopBits = { 1, 2, 3 }; ???????????foreach (var sb in stopBits) ???????????{ ???????????????cmbStopBits.Items.Add(sb); ???????????} ????????????//添加检验方式 ???????????string[] parity = { "None", "Even", "Mark", "Odd", "Space" }; ???????????foreach (var p in parity) ???????????{ ???????????????cmbParity.Items.Add(p); ???????????} ????????????//添加常用编码 ???????????string[] encode = { "ASCII","UTF-8","Unicode","Hex"}; ???????????foreach (var en in encode) ???????????{ ???????????????cmbEncodeSend.Items.Add(en); ???????????????cmbEncodeRec.Items.Add(en); ???????????} ????????????//加载配置文件 ???????????LoadConfig(); ???????} ????????private void LoadConfig() ???????{ ???????????//把配置信息赋值给控件默认值 ???????????cmbComList.SelectedItem = config.PortName; ???????????if (cmbComList.SelectedIndex == -1) cmbComList.SelectedIndex = 0; ???????????cmbBautRade.SelectedItem = config.BautRade; ???????????cmbDataBits.SelectedItem = config.DataBits; ???????????cmbStopBits.SelectedItem = config.StopBits; ???????????cmbParity.SelectedItem = config.Parity; ???????????cmbEncodeRec.SelectedItem = config.EncodeRec; ???????????cmbEncodeSend.SelectedItem = config.EncodeSend; ????????????//激活打开按钮 ???????????this.btnOpen.Enabled = true; ???????} ????????private void btnOpen_Click(object sender, EventArgs e) ???????{ ???????????if (((Button)sender).Text == "打开串口") ???????????{ ???????????????//赋值给串口 ???????????????sp.PortName = cmbComList.SelectedItem.ToString(); ???????????????sp.Parity=(Parity)Enum.Parse(typeof(Parity),cmbParity.SelectedItem.ToString()); ???????????????sp.BaudRate = Convert.ToInt32(cmbBautRade.SelectedItem.ToString()); ???????????????sp.StopBits = (StopBits)Convert.ToInt32(cmbStopBits.SelectedItem.ToString()); ???????????????sp.DataBits = Convert.ToInt32(cmbDataBits.SelectedItem.ToString()); ????????????????try ???????????????{ ???????????????????sp.Open(); ????????????????????//修改控件状态 ???????????????????this.btnOpen.Text = "关闭串口"; ???????????????????foreach (Control ctr in groupBox1.Controls) ???????????????????{ ???????????????????????//把下拉框全部禁用 ???????????????????????ctr.Enabled = false; ???????????????????} ????????????????????//开启新线程,监听收取内容 ???????????????????Thread thread = new Thread(receive); ???????????????????thread.Start(); ???????????????} ???????????????catch (Exception ex) ???????????????{ ???????????????????MessageBox.Show(ex.Message); ???????????????} ???????????} ???????????else ???????????{ ???????????????if (this.btnAutoSend.Text == "停止发送") ???????????????{ ???????????????????MessageBox.Show("当前定时发送中,请先停止定时发送任务."); ???????????????????return; ???????????????} ????????????????sp.Close(); ????????????????//修改控件状态 ???????????????this.btnOpen.Text = "打开串口"; ???????????????foreach (Control ctr in this.groupBox1.Controls) ???????????????{ ???????????????????ctr.Enabled = true; ???????????????} ???????????} ???????} ????????private void Form1_FormClosed(object sender, FormClosedEventArgs e) ???????{ ???????????//窗体关闭时关闭端口 ???????????sp.Close(); ???????} ????????private void btnSend_Click(object sender, EventArgs e) ???????{ ???????????Send(); ???????} ????????private void btnAutoSend_Click(object sender, EventArgs e) ???????{ ???????????if (this.btnAutoSend.Text == "定时发送") ???????????{ ???????????????//根据打开按钮状态初步检查端口是否已经打开 ???????????????if (this.btnOpen.Text == "打开串口") return; ????????????????System.Text.RegularExpressions.Regex reg1 = new System.Text.RegularExpressions.Regex(@"^[0-9]\d*$"); ???????????????if (reg1.IsMatch(txtTime.Text.ToString())) ???????????????{ ???????????????????//激活Timer定时器 ???????????????????this.timer1.Interval = Convert.ToInt32(txtTime.Text.ToString()); ???????????????????this.timer1.Start(); ????????????????????//修改控件状态 ???????????????????this.btnAutoSend.Text = "停止发送"; ???????????????????this.btnSend.Enabled = false; ????????????????} ???????????????else ???????????????{ ???????????????????MessageBox.Show("发送间隔应为正整数"); ???????????????????txtTime.Text = "1000"; ???????????????} ???????????} ???????????else ???????????{ ???????????????this.btnAutoSend.Text = "定时发送"; ???????????????this.btnSend.Enabled = true; ???????????????this.timer1.Stop(); ???????????} ???????} ????????private void Send() ???????{ ???????????if (sp.IsOpen) ???????????{ ???????????????//获取字节 ???????????????byte[] buffer = Encode(); ???????????????if (buffer.Length == 0) return; ????????????????try ???????????????{ ???????????????????sp.Write(buffer, 0, buffer.Length); ???????????????} ???????????????catch (Exception ex) ???????????????{ ???????????????????MessageBox.Show(ex.Message); ???????????????} ????????????????//添加发送历史 ???????????????this.txtHistory.AppendText(string.Format("[{0}] {1} \r\n", DateTime.Now.ToString("HH:mm:ss.ff"), txtSend.Text)); ???????????????//统计发送字节 ???????????????this.labSendCount.Text = (Convert.ToInt32(labSendCount.Text) + buffer.Length).ToString(); ???????????} ???????????else ???????????{ ???????????????this.timer1.Stop(); ???????????????MessageBox.Show("串口尚未打开"); ???????????????this.btnAutoSend.Text = "定时发送"; ???????????} ???????} ????????private void timer1_Tick(object sender, EventArgs e) ???????{ ???????????//定时发送 ???????????Send(); ???????} ????????//字节反编码 ???????private byte[] Encode() ???????{ ???????????byte[] buffer = null; ????????????switch (this.cmbEncodeSend.SelectedItem.ToString()) ???????????{ ???????????????case "Unicode": ???????????????????buffer = Encoding.Unicode.GetBytes(txtSend.Text); ????????????????????break; ???????????????case "UTF-8": ???????????????????buffer = Encoding.UTF8.GetBytes(txtSend.Text); ???????????????????break; ???????????????case "ASCII": ???????????????????buffer = Encoding.ASCII.GetBytes(txtSend.Text); ???????????????????break; ???????????????case "Hex": ???????????????????buffer = strToToHexByte(txtSend.Text); ???????????????????break; ???????????} ????????????return buffer; ???????} ???????//编码 ???????private string UnEncode(byte[] buffer) ???????{ ???????????string str = string.Empty; ????????????switch (this.cmbEncodeSend.SelectedItem.ToString()) ???????????{ ???????????????case "Unicode": ???????????????????str = new UnicodeEncoding().GetString(buffer); ???????????????????break; ???????????????case "UTF-8": ???????????????????str = new UTF8Encoding().GetString(buffer); ???????????????????break; ???????????????case "ASCII": ???????????????????str = new ASCIIEncoding().GetString(buffer); ???????????????????break; ???????????????case "Hex": ???????????????????str = byteToHexStr(buffer); ???????????????????break; ???????????} ????????????return str; ???????} ???????/// <summary> ???????/// 字节数组转16进制字符串 ???????/// </summary> ???????/// <param name="bytes"></param> ???????/// <returns></returns> ???????public static string byteToHexStr(byte[] bytes) ???????{ ???????????string returnStr = ""; ???????????if (bytes != null) ???????????{ ???????????????for (int i = 0; i < bytes.Length; i++) ???????????????{ ???????????????????returnStr += bytes[i].ToString("X2"); ???????????????} ???????????} ???????????return returnStr; ???????} ???????/// <summary> ???????/// 字符串转16进制字节数组 ???????/// </summary> ???????/// <param name="hexString"></param> ???????/// <returns></returns> ???????private static byte[] strToToHexByte(string hexString) ???????{ ???????????hexString = hexString.Replace(" ", ""); ???????????if ((hexString.Length % 2) != 0) ???????????????hexString += " "; ???????????byte[] returnBytes = new byte[hexString.Length / 2]; ???????????for (int i = 0; i < returnBytes.Length; i++) ???????????????returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16); ???????????return returnBytes; ???????} ????????private void receive() ???????{ ???????????//接收信息 先判断是否为打开状态 ???????????while (sp.IsOpen) ???????????{ ???????????????if (sp.BytesToRead == 0) continue; ????????????????//准备接收 ???????????????byte[] buffer = new byte[sp.BytesToRead]; ???????????????try ???????????????{ ???????????????????//接受动作 ???????????????????sp.Read(buffer, 0, buffer.Length); ????????????????} ???????????????catch (Exception ex) ???????????????{ ???????????????????MessageBox.Show(ex.Message); ???????????????} ????????????????//更新UI信息 ???????????????this.Invoke((Action)delegate ???????????????{ ???????????????????this.txtRec.AppendText(UnEncode(buffer)); ???????????????????//是否自动换行 ???????????????????if(cbLine.Checked) ???????????????????????this.txtRec.AppendText("\r\n"); ????????????????????//接收统计信息 ???????????????????this.labRecCount.Text = (Convert.ToInt32(this.labRecCount.Text) + buffer.Length).ToString(); ???????????????}); ???????????} ???????} ????????private void button1_Click(object sender, EventArgs e) ???????{ ???????????//清空发送历史 ???????????this.txtHistory.Clear(); ???????} ????????private void button2_Click(object sender, EventArgs e) ???????{ ???????????//清空接收 ???????????this.txtRec.Clear(); ???????} ????????private void btnLoad_Click(object sender, EventArgs e) ???????{ ???????????//读取xml文件 序列化对象 ???????????OpenFileDialog ofd = new OpenFileDialog(); ???????????ofd.Filter = "XML(*.xml)|"; ???????????if (ofd.ShowDialog() == DialogResult.OK) ???????????{ ???????????????string filePath = ofd.FileName; ???????????????if (File.Exists(filePath)) ???????????????{ ???????????????????try ???????????????????{ ???????????????????????var mySerializer = new XmlSerializer(typeof(Config)); ???????????????????????using (var sr = new StreamReader(new FileStream(filePath, FileMode.Open, FileAccess.Read))) ???????????????????????{ ???????????????????????????config = (Config)mySerializer.Deserialize(sr); ???????????????????????} ???????????????????????LoadConfig(); ???????????????????} ???????????????????catch (Exception ee) ???????????????????{ ???????????????????????MessageBox.Show(ee.Message); ???????????????????} ???????????????} ???????????????else ???????????????{ ???????????????????MessageBox.Show("文件不存在"); ???????????????} ???????????} ???????} ????????private void btnSave_Click(object sender, EventArgs e) ???????{ ????????????FolderBrowserDialog fbd = new FolderBrowserDialog(); ???????????????????????if (fbd.ShowDialog() == DialogResult.OK) ???????????{ ???????????????//给对象赋值并序列化保存 ???????????????config.PortName = cmbComList.SelectedItem.ToString(); ???????????????config.Parity = cmbParity.SelectedItem.ToString(); ???????????????config.BautRade = Convert.ToInt32(cmbBautRade.SelectedItem.ToString()); ???????????????config.StopBits = Convert.ToInt32(cmbStopBits.SelectedItem.ToString()); ???????????????config.DataBits = Convert.ToInt32(cmbDataBits.SelectedItem.ToString()); ????????????????XmlSerializer xmlFormat=new XmlSerializer(typeof(Config)); ???????????????string filePath = fbd.SelectedPath + "\\PortConfig.xml"; ???????????????using (Stream stream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None)) ???????????????{ ???????????????????xmlFormat.Serialize(stream, config); ???????????????} ???????????????MessageBox.Show("成功保存到路径:"+filePath); ???????????} ???????} ????????private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) ???????{ ???????????System.Diagnostics.Process.Start("http://www.chengchenxu.com"); ?????????} ???}}
软件下载:
串口调试工具.rar
源码工程文件:
串口调试工具.rar
虚拟端口软件下载:
VirtualSerialPortDriver.rar
未实现的功能:
16进制校验功能,即发送16进制格式的时候检查输入值是否为正确的16进制数字
接受文件的完整性校验功能,有时候一条信息会分两次接受完整
本文为博主原创,转载请保留出处:
http://www.chengchenxu.com/Article/30/
C.Net串口工具源码 串口调试工具 支持16进制发送 可以定时自动发送
原文地址:https://www.cnblogs.com/chengchenxu/p/8591718.html