C# 之 串口数据侦听的实现
当需要编程操纵硬件时会遇到过这样的问题,就是通过串口来接收硬件发来的数据,或是通过串口向硬件发送某种格式的命令。在C#平台上,可以通过 System.IO.Ports 命名空间下的SerialPort 类来实现。
下面是我做过的一个简单的示例,首先获取本机关联的串行端口列表,然后获取配置文件中配置的COM端口,检查是否在本机串行端口列表中,若在列表中则进一步实例化串口对象,并为串口对象指定数据接收事件来实现监听,示例代码如下:
using System.IO.Ports; namespace SerialTest { public class SerialTest { #region 串口监听 private SerialPort serialPort = null; /// <summary> /// 开启串口监听 /// </summary> private void StartSerialPortMonitor() { List<string> comList = GetComlist(false); //首先获取本机关联的串行端口列表 if (comList.Count == 0) { DialogForm.Show("提示信息", "当前设备不存在串行端口!"); System.Environment.Exit(0); //彻底退出应用程序 } else { string targetCOMPort = ConfigurationManager.AppSettings["COMPort"].ToString(); //判断串口列表中是否存在目标串行端口 if (!comList.Contains(targetCOMPort)) { DialogForm.Show("提示信息", "当前设备不存在配置的串行端口!"); System.Environment.Exit(0); //彻底退出应用程序 } serialPort = new SerialPort(); //设置参数 serialPort.PortName = ConfigurationManager.AppSettings["COMPort"].ToString(); //通信端口 serialPort.BaudRate = Int32.Parse(ConfigurationManager.AppSettings["BaudRate"].ToString()); //串行波特率 serialPort.DataBits = 8; //每个字节的标准数据位长度 serialPort.StopBits = StopBits.One; //设置每个字节的标准停止位数 serialPort.Parity = Parity.None; //设置奇偶校验检查协议 serialPort.ReadTimeout = 3000; //单位毫秒 serialPort.WriteTimeout = 3000; //单位毫秒 //串口控件成员变量,字面意思为接收字节阀值, //串口对象在收到这样长度的数据之后会触发事件处理函数 //一般都设为1 serialPort.ReceivedBytesThreshold = 1; serialPort.DataReceived += new SerialDataReceivedEventHandler(CommDataReceived); //设置数据接收事件(监听) try { serialPort.Open(); //打开串口 } catch (Exception ex) { DialogForm.Show("提示信息", "串行端口打开失败!具体原因:" + ex.Message); System.Environment.Exit(0); //彻底退出应用程序 } } } /// <summary> /// 串口数据处理函数 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> public void CommDataReceived(Object sender, SerialDataReceivedEventArgs e) { try { //Comm.BytesToRead中为要读入的字节长度 int len = serialPort.BytesToRead; Byte[] readBuffer = new Byte[len]; serialPort.Read(readBuffer, 0, len); //将数据读入缓存 //处理readBuffer中的数据,自定义处理过程 string msg = encoding.GetString(readBuffer, 0, len); //获取出入库产品编号 DialogForm.Show("接收到的信息", msg); } catch(Exception ex) { DialogForm.Show("提示信息", "接收返回消息异常!具体原因:" + ex.Message); } } /// <summary> /// 关闭串口 /// </summary> private void Stop() { serialPort.Close(); } /// <summary> /// 获取本机串口列表 /// </summary> /// <param name="isUseReg"></param> /// <returns></returns> private List<string> GetComlist(bool isUseReg) { List<string> list = new List<string>(); try { if (isUseReg) { RegistryKey RootKey = Registry.LocalMachine; RegistryKey Comkey = RootKey.OpenSubKey(@"HARDWARE\DEVICEMAP\SERIALCOMM"); String[] ComNames = Comkey.GetValueNames(); foreach (String ComNamekey in ComNames) { string TemS = Comkey.GetValue(ComNamekey).ToString(); list.Add(TemS); } } else { foreach (string com in SerialPort.GetPortNames()) //自动获取串行口名称 list.Add(com); } } catch { DialogForm.Show("提示信息", "串行端口检查异常!"); System.Environment.Exit(0); //彻底退出应用程序 } return list; } #endregion 串口监听 } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构