C# 学习笔记(13)自己的串口助手
C# 学习笔记(13)自己的串口助手
UI界面
界面部分参考野火串口助手,自己拖控件拖一个即可
功能实现
扫描串口
- 方法一 使用串口自带的get函数
比较简单实用
SerialPort.GetPortNames();
- 方法二 扫描设备管理器
如果开发特定设备具有特定串口名,可以扫描设备管理器获取串口全名,筛选含有特定名称的串口
/// <summary>
/// 获取COM口 从设备管理器获取COM口详细信息,筛选后返回符合要求的COM口(筛选包涵 str 字符串的COM口)
/// </summary>
/// <returns></returns>
public string[] GetComName()
{List<string> coms = new List<string>();string str = "COM"; //筛选关键字 可自行修改try{//搜索设备管理器中的所有条目using (ManagementObjectSearcher searcher = new ManagementObjectSearcher("select * from Win32_PnPEntity")){var hardInfos = searcher.Get();foreach (var hardInfo in hardInfos){if (hardInfo.Properties["Name"].Value != null){if (hardInfo.Properties["Name"].Value.ToString().Contains("(COM")){coms.Add(hardInfo.Properties["Name"].Value.ToString());}}}searcher.Dispose();}List<string> strs = new List<string>();foreach (string portName in coms){if (portName.Contains(str)){strs.Add(portName.Substring(portName.IndexOf("(COM")).Replace('(', ' ').Replace(')', ' ').Trim());}}return strs.ToArray();}catch{return null;}
}
串口热插拔
当使用串口时,如果串口断开连接,立即关闭串口,当有新的串口插入,刷新串口列表
public const int WM_DEVICE_CHANGE = 0x219; //设备改变 public const int DBT_DEVICEARRIVAL = 0x8000; //设备插入public const int DBT_DEVICE_REMOVE_COMPLETE = 0x8004; //设备移除/// <summary>/// USB热插拔支持/// </summary>/// <param name="m"></param>protected override void WndProc(ref Message m){switch (m.WParam.ToInt32()) //判断消息类型{case DBT_DEVICEARRIVAL:{if (serialPortCOM.IsOpen){}else{this.BeginInvoke(new Action(() => {UpdateSerialName(cmbSerialName, GetComName(), cmbSerialName.Text);}));}}break;case DBT_DEVICE_REMOVE_COMPLETE:{if (serialPortCOM.IsOpen){}else{this.BeginInvoke(new Action(() => { CloseSerialPort(); UpdateSerialName(cmbSerialName, GetComName(), cmbSerialName.Text); }));}}break;}base.WndProc(ref m);}
接收显示
/// <summary>
/// 串口接收回调函数
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void serialPortCOM_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{//50ms处理一次串口接收Thread.Sleep(50);if(!serialPortCOM.IsOpen){return;}Byte[] recvByteTemp = new Byte[serialPortCOM.BytesToRead];serialPortCOM.Read(recvByteTemp, 0, recvByteTemp.Length);//异步处理 防止UI界面卡死this.BeginInvoke(new Action<byte[]>((byte[] data)=> { DisplayRxInfo(data); }), recvByteTemp);
}/// <summary>
/// 接收处理
/// </summary>
/// <param name="data">串口接收字节数据</param>
private void DisplayRxInfo(byte[] data)
{try{if (ckbStopDisPlay.Checked){//停止显示return;}string str = "";if (ckbRxHex.Checked){//十六进制显示str = MyConver.ByteToHex(data);if (ckbTimeStamp.Checked){//时间戳str = str.Replace("0A", "0A \r\n[" + DateTime.Now.Millisecond.ToString() + "]->>>");}}else{str = RxEncoding.GetString(data);if (ckbTimeStamp.Checked){//时间戳str = str.Replace("\n", "\n[" + DateTime.Now.Millisecond.ToString() + "]->>>");}}if (ckbAutoClear.Checked && txbRx.TextLength > 4096){//自动清除txbRx.Text = "";}txbRx.AppendText(str);if (ckbSaveRxFile.Checked){//将接收信息写入文件File.AppendAllText(CurrentFilePath, str);}RxCounter += data.Length;}catch{}
}
进制转换
public static class MyConver
{/// <summary>/// 字节数组转16进制字符串/// </summary>/// <param name="data"></param>/// <returns></returns>public static string ByteToHex(byte[] data){StringBuilder stringBuilder = new StringBuilder(1024);for (int i = 0; i < data.Length; i++){stringBuilder.Append(data[i].ToString("X2") + " ");}return stringBuilder.ToString();}/// <summary>/// hex string字节数组转byte/// </summary>/// <param name="str"></param>/// <returns></returns>public static byte[] HexToByte(string str){str = str.Replace(" ", "");if (str.Length % 2 != 0){str = str.Insert(str.Length - 1, "0");}byte[] bytesHex = new byte[str.Length / 2];try{for (int i = 0; i < str.Length / 2; i++){bytesHex[i] = Convert.ToByte(str.Substring(2 * i, 2), 16);}}catch{}return bytesHex;}
}
保存配置信息
c# 提供了setting文件,可以十分方便的保存配置信息
- 保存时一定要记得使用 Properties.Settings.Default.Save();保存
/// <summary>
/// 加载参数
/// </summary>
private void LoadParam()
{UpdateSerialName(cmbSerialName, GetComName(), Properties.Settings.Default.serialPortName);//UpdateSerialName(cmbSerialName, SerialPort.GetPortNames(), Properties.Settings.Default.serialPortName);cmbBaudRate.Text = Properties.Settings.Default.serialPortBaud;cmbParity.SelectedIndex = cmbParity.Items.IndexOf(Properties.Settings.Default.serialPortParity);cmbDataBits.Text = Properties.Settings.Default.serialPortDataBits;cmbStopBits.Text = Properties.Settings.Default.serialPortStopBits;ckbStopDisPlay.Checked = Properties.Settings.Default.ckbStopDisPlay;ckbAutoClear.Checked = Properties.Settings.Default.ckbAutoClear;ckbRxHex.Checked = Properties.Settings.Default.ckbRxHex;ckbSaveRxFile.Checked = Properties.Settings.Default.ckbSaveRxFile;ckbTimeStamp.Checked = Properties.Settings.Default.ckbTimeStamp;ckbRxWordWrap.Checked = Properties.Settings.Default.ckbRxWordWrap;ckbRxUTF8.Checked = Properties.Settings.Default.ckbRxUTF8;ckbAutoTx.Checked = Properties.Settings.Default.ckbAutoTx;ckbTxWordWrap.Checked = Properties.Settings.Default.ckbTxWordWrap;ckbTxUTF8.Checked = Properties.Settings.Default.ckbTxUTF8;txbTxAutoTime.Text = Properties.Settings.Default.txbTxAutoTime;
}/// <summary>
/// 保存参数
/// </summary>
private void SaveParam()
{Properties.Settings.Default.serialPortName = cmbSerialName.Text;Properties.Settings.Default.serialPortBaud = cmbBaudRate.Text;Properties.Settings.Default.serialPortParity = cmbParity.Text;Properties.Settings.Default.serialPortDataBits = cmbDataBits.Text;Properties.Settings.Default.serialPortStopBits = cmbStopBits.Text;Properties.Settings.Default.ckbStopDisPlay = ckbStopDisPlay.Checked;Properties.Settings.Default.ckbAutoClear = ckbAutoClear.Checked;Properties.Settings.Default.ckbRxHex = ckbRxHex.Checked;Properties.Settings.Default.ckbSaveRxFile = ckbSaveRxFile.Checked;Properties.Settings.Default.ckbTimeStamp = ckbTimeStamp.Checked;Properties.Settings.Default.ckbRxWordWrap = ckbRxWordWrap.Checked;Properties.Settings.Default.ckbRxUTF8 = ckbRxUTF8.Checked;Properties.Settings.Default.ckbAutoTx = ckbAutoTx.Checked;Properties.Settings.Default.ckbTxWordWrap = ckbTxWordWrap.Checked;Properties.Settings.Default.ckbTxUTF8 = ckbTxUTF8.Checked;Properties.Settings.Default.txbTxAutoTime = txbTxAutoTime.Text;Properties.Settings.Default.Save();
}
历史路径
/// <summary>
/// 记录历史文件信息
/// </summary>
/// <param name="path"></param>
private void SaveFilePath(params string[] path)
{List<string> strList = new List<string>();strList.Add(Properties.Settings.Default.logPath1);strList.Add(Properties.Settings.Default.logPath2);strList.Add(Properties.Settings.Default.logPath3);strList.Add(Properties.Settings.Default.logPath4);strList.Add(Properties.Settings.Default.logPath5);foreach (var item in path){if (!string.IsNullOrWhiteSpace(item)){strList.Remove(item);strList.Insert(0, item);}}///* 保存当前路径 */Properties.Settings.Default.logPath1 = strList[0];Properties.Settings.Default.logPath2 = strList[1];Properties.Settings.Default.logPath3 = strList[2];Properties.Settings.Default.logPath4 = strList[3];Properties.Settings.Default.logPath5 = strList[4];Properties.Settings.Default.Save();/* 历史文件菜单 */toolStripMenuItem2.Text = strList[0];toolStripMenuItem3.Text = strList[1];toolStripMenuItem4.Text = strList[2];toolStripMenuItem5.Text = strList[3];toolStripMenuItem6.Text = strList[4];
}
窗口拖拽
- 开启控件拖拽
- 添加事件
/// <summary>
/// 发送文本框 文件拖拽支持
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void txbTx_DragDrop(object sender, DragEventArgs e)
{e.Effect = DragDropEffects.None;txbTx.Text = "";string path = ((string[])e.Data.GetData(DataFormats.FileDrop))[0];txbTx.Text = OpenFile(path);
}/// <summary>
/// 发送文本框 文件拖拽支持
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void txbTx_DragEnter(object sender, DragEventArgs e)
{if (e.Data.GetDataPresent(DataFormats.FileDrop)){string[] path = (string[])e.Data.GetData(DataFormats.FileDrop);if(path.Length == 1 && path[0].Contains(".")){//改变鼠标样式e.Effect = DragDropEffects.Copy;}else{e.Effect = DragDropEffects.None;} }
}
源码 https://github.com/mian2018/CSharp_COM
C# 学习笔记(13)自己的串口助手相关推荐
- OpenHarmony学习笔记——Hi3861+ASR-01的语音识别助手
文章目录 前言 Hi3861的UART与PWM简介 UART简介 PWM ASR-01离线语音识别 天问官方介绍 硬件连接 软件部分 ASR-01代码 Hi3861端代码 初始化资源 串口指令识别 效 ...
- mybatis学习笔记(13)-延迟加载
2019独角兽企业重金招聘Python工程师标准>>> mybatis学习笔记(13)-延迟加载 标签: mybatis [TOC] resultMap可以实现高级映射(使用asso ...
- opencv进阶学习笔记13:图像形态学操作大全(膨胀,腐蚀,开闭,黑帽,顶帽,梯度)python版
基础版学习笔记: python3+opencv学习笔记汇总目录(适合基础入门学习) 进阶版笔记目录链接: python+opencv进阶版学习笔记目录(适合有一定基础) 基础版形态学: opencv学 ...
- Linux学习笔记13
Linux学习笔记13 Linux学习笔记13 配置Nagios 基本介绍 Nagios安装 - 服务端 Nagios安装 - 客户端 监控中心添加被监控主机 配置文件的简单说明 继续添加需要服务端通 ...
- Hadoop学习笔记—13.分布式集群中节点的动态添加与下架
Hadoop学习笔记-13.分布式集群中节点的动态添加与下架 开篇:在本笔记系列的第一篇中,我们介绍了如何搭建伪分布与分布模式的Hadoop集群.现在,我们来了解一下在一个Hadoop分布式集群中,如 ...
- 台大李宏毅Machine Learning 2017Fall学习笔记 (13)Semi-supervised Learning
台大李宏毅Machine Learning 2017Fall学习笔记 (13)Semi-supervised Learning 本博客参考整理自: http://blog.csdn.net/xzy_t ...
- java 量化指标_量化投资学习笔记13——各种指标的绘图、计算及交易策略
<量化投资:以python为工具>第五部分笔记 先来画k线图,要注意finance模块已经从matplotlib库中去除,现在要用mpl_finance库,单独安装. 其中有candles ...
- 【计算机网络学习笔记13】交换技术(下)
[计算机网络学习笔记13]交换技术(下) 一.生成树的诞生和发展 1. 环路问题 两个网桥之间的连接网线如果只有一根,而这根网线或者接口有问题,网络就会出现单点故障.所以为了提高可靠性,网桥在互连时一 ...
- R语言小白学习笔记13—基本统计
R语言小白学习笔记13-基本统计 笔记链接 学习笔记13-基本统计 13.1 概括性统计量 13.2 相关系数和协方差 13.3 t-检验 13.3.1 单样本t检验 13.3.2 两样本t检验 13 ...
- Excel VBA 学习笔记13:单元格的格式
Excel VBA 学习笔记13:单元格的格式 NumberFormat 属性 (Excel) vba excel 单元格格式设置 Excel VBA 单元格格式 python解决SNIMissing ...
最新文章
- 使用require.js和backbone实现简单单页应用实践
- 无效0_一场时代的变革,一场与时间的较量,“0”无效载体、“0”空气氧化、“0”细菌生存。...
- java中pack函数_java - Java函数pack(),JFrame大小 - 堆栈内存溢出
- 数学狂想曲(五)——概率分布(2), 自相关互相关卷积
- 提升代码可读性的 10 个技巧
- Python生成大量随机人员信息
- –is-dba_查询存储–每个DBA的下一代工具
- Java 中nextLine()方法没有执行直接跳过解决办法
- Graduation Speech 毕业典礼致辞__转载
- windows系统c语言编译环境,在Windows平台搭建C语言开发环境
- php之使用file_get_contents对百度orc进行文字识别(二维码识别同理)--base64编码方式(解决image format error)
- 最新可使用在线音乐网站+多解析源码
- Autodesk AutoCAD 2018 for Mac 汉化破解版安装教程
- 易班登陆接口接入实例
- linux幻灯片制作软件,Marp(代码制作幻灯片软件)
- 朴素贝叶斯凉鞋问题推导
- OpenLayers教程:图形绘制之绘制几何图形
- 手把手带你开发一个批量下载资源的谷歌浏览器扩展
- Ubuntu Linux 系统 键盘错乱 ,按键与输出不一致
- 软件调试系列:软件崩溃篇之内存异常崩溃