当前位置: 首页 > news >正文

C#开发记录如何建立虚拟串口,进行串口通信,以及通信模板

记录时间;2024年4月

记录如何开启虚拟串口以及进行基础串口通信。

建立虚拟串口

使用的软件是vspd,建立虚拟串口之后就可以将他们当成实际物理连接的两个串口进行通信。

之后使用我们之前给出的通信模板,建立一个稍微规矩一点的界面。

界面建立

 

 其中添加对用户输入的检查。

配合之前打开串口的逻辑就可以开始串口应用的调试和开发了。

代码

  public partial class Form1 : Form{//串口参数和串口工具类public System.IO.Ports.SerialPort _serialPort = new System.IO.Ports.SerialPort();string[] baud = { "43000", "56000", "57600", "115200", "128000", "230400", "256000", "460800" };private void displaytext(object sender, EventArgs e){string str = _serialPort.ReadExisting();rtxreceive.AppendText(str);}//串口接收事件private void _serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e){//串口接收事件try{//串口接收数据//if(serialPort1.IsOpen){this.Invoke(new EventHandler(displaytext));}}catch (Exception ex){//捕获到异常,创建一个新的对象,之前的不可以再用_serialPort = new System.IO.Ports.SerialPort();//刷新COM口选项comboBox1.Items.Clear();comboBox1.Items.AddRange(System.IO.Ports.SerialPort.GetPortNames());//响铃并显示异常给用户System.Media.SystemSounds.Beep.Play();button4.Text = "打开串口";MessageBox.Show(ex.Message);hintrtx.Text += "\n串口接收失败";comboBox1.Enabled = true;comboBox2.Enabled = true;comboBox3.Enabled = true;comboBox4.Enabled = true;comboBox5.Enabled = true;}}public Form1(){InitializeComponent();}private void button1_Click(object sender, EventArgs e){//检测try{string[] ports = SerialPort.GetPortNames();if (ports.Length == 0){MessageBox.Show("没有找到串口");hintrtx.Text += "没有找到串口";return;}comboBox1.Items.Clear();comboBox1.Items.AddRange(ports);comboBox1.SelectedIndex = 0;comboBox2.SelectedIndex = 0;comboBox3.SelectedIndex = 0;comboBox4.SelectedIndex = 0;comboBox5.SelectedIndex = 0;//检测到串口后,使能串口参数设置comboBox1.Enabled = true;comboBox2.Enabled = true;comboBox3.Enabled = true;comboBox4.Enabled = true;comboBox5.Enabled = true;}catch (Exception ex){MessageBox.Show(ex.Message);}}private void Form1_Load(object sender, EventArgs e){//界面初始化int i;for (i = 300; i <= 38400; i = i * 2){comboBox2.Items.Add(i.ToString());  //添加波特率列表}comboBox2.Items.AddRange(baud);comboBox1.Enabled = false;comboBox2.Enabled = false;comboBox3.Enabled = false;comboBox4.Enabled = false;comboBox5.Enabled = false;hintrtx.Text += "欢迎使用";}private void button4_Click(object sender, EventArgs e){//开启串口try{if (_serialPort.IsOpen){//如果串口已经处于打开状态,则关闭串口_serialPort.Close();button4.Text = "打开串口";hintrtx.Text += "\n串口已经关闭";//关闭串口后,使能串口参数设置comboBox1.Enabled = true;comboBox2.Enabled = true;comboBox3.Enabled = true;comboBox4.Enabled = true;comboBox5.Enabled = true;//取消串口接收事件注册_serialPort.DataReceived -= new SerialDataReceivedEventHandler(_serialPort_DataReceived);return;}else{//串口已经处于关闭状态,则设置好串口属性后打开comboBox1.Enabled = false;comboBox2.Enabled = false;comboBox3.Enabled = false;comboBox4.Enabled = false;comboBox5.Enabled = false;_serialPort.PortName = comboBox1.Text;_serialPort.BaudRate = Convert.ToInt32(comboBox2.Text);_serialPort.DataBits = Convert.ToInt16(comboBox3.Text);_serialPort.Parity = (Parity)Enum.Parse(typeof(Parity), comboBox4.Text);if (comboBox5.Text.Equals("1"))_serialPort.StopBits = System.IO.Ports.StopBits.One;else if (comboBox5.Text.Equals("1.5"))_serialPort.StopBits = System.IO.Ports.StopBits.OnePointFive;else if (comboBox5.Text.Equals("2"))_serialPort.StopBits = System.IO.Ports.StopBits.Two;//_serialPort.StopBits = (StopBits)Enum.Parse(typeof(StopBits), comboBox5.Text);_serialPort.Open();//注册串口接收事件_serialPort.DataReceived += new SerialDataReceivedEventHandler(_serialPort_DataReceived);button4.Text = "关闭串口";hintrtx.Text += "\n串口已经打开";}}catch (Exception ex){MessageBox.Show(ex.Message);hintrtx.Text += "\n串口打开失败";}}private void button3_Click(object sender, EventArgs e){//try{//首先判断串口是否开启if (_serialPort.IsOpen){//串口处于开启状态,将发送区文本发送_serialPort.Write(rtx_send.Text);}}catch (Exception ex){//捕获到异常,创建一个新的对象,之前的不可以再用_serialPort = new System.IO.Ports.SerialPort();//刷新COM口选项comboBox1.Items.Clear();comboBox1.Items.AddRange(System.IO.Ports.SerialPort.GetPortNames());//响铃并显示异常给用户System.Media.SystemSounds.Beep.Play();button4.Text = "打开串口";MessageBox.Show(ex.Message);hintrtx.Text += "\n串口发送失败";comboBox1.Enabled = true;comboBox2.Enabled = true;comboBox3.Enabled = true;comboBox4.Enabled = true;comboBox5.Enabled = true;}}}

代码解释:

扫描串口:

我们使用serialport类进行串口的扫描,能够给到一个串口名称的列表。展示的中间修改页面元素的可用性,允许用户修改串口配置。

private void button1_Click(object sender, EventArgs e){//检测try{string[] ports = SerialPort.GetPortNames();if (ports.Length == 0){MessageBox.Show("没有找到串口");hintrtx.Text += "没有找到串口";return;}comboBox1.Items.Clear();comboBox1.Items.AddRange(ports);comboBox1.SelectedIndex = 0;comboBox2.SelectedIndex = 0;comboBox3.SelectedIndex = 0;comboBox4.SelectedIndex = 0;comboBox5.SelectedIndex = 0;//检测到串口后,使能串口参数设置comboBox1.Enabled = true;comboBox2.Enabled = true;comboBox3.Enabled = true;comboBox4.Enabled = true;comboBox5.Enabled = true;}catch (Exception ex){MessageBox.Show(ex.Message);}}

打开/关闭串口

逻辑非常简单,判断是否已经打开,如果已经打开就关闭。

打开的逻辑是:

读取用户设置之前先锁定配置,防止调试中用户修改。

接着就是打开串口,注册串口接收事件用于执行接收指定的逻辑。

关闭串口更加简单,重新给予用户修改配置的机会,同时关闭串口,取消事件的注册。

事件机制是串口收发的核心:

C#笔记4 详细解释事件及其原型、匿名方法和委托的关系-CSDN博客

c#笔记5 详解事件的内置类型EventHandler、windows事件在winform中的运用_c# eventhandler用法-CSDN博客

 private void button4_Click(object sender, EventArgs e){//开启串口try{if (_serialPort.IsOpen){//如果串口已经处于打开状态,则关闭串口_serialPort.Close();button4.Text = "打开串口";hintrtx.Text += "\n串口已经关闭";//关闭串口后,使能串口参数设置comboBox1.Enabled = true;comboBox2.Enabled = true;comboBox3.Enabled = true;comboBox4.Enabled = true;comboBox5.Enabled = true;//取消串口接收事件注册_serialPort.DataReceived -= new SerialDataReceivedEventHandler(_serialPort_DataReceived);return;}else{//串口已经处于关闭状态,则设置好串口属性后打开comboBox1.Enabled = false;comboBox2.Enabled = false;comboBox3.Enabled = false;comboBox4.Enabled = false;comboBox5.Enabled = false;_serialPort.PortName = comboBox1.Text;_serialPort.BaudRate = Convert.ToInt32(comboBox2.Text);_serialPort.DataBits = Convert.ToInt16(comboBox3.Text);_serialPort.Parity = (Parity)Enum.Parse(typeof(Parity), comboBox4.Text);if (comboBox5.Text.Equals("1"))_serialPort.StopBits = System.IO.Ports.StopBits.One;else if (comboBox5.Text.Equals("1.5"))_serialPort.StopBits = System.IO.Ports.StopBits.OnePointFive;else if (comboBox5.Text.Equals("2"))_serialPort.StopBits = System.IO.Ports.StopBits.Two;//_serialPort.StopBits = (StopBits)Enum.Parse(typeof(StopBits), comboBox5.Text);_serialPort.Open();//注册串口接收事件_serialPort.DataReceived += new SerialDataReceivedEventHandler(_serialPort_DataReceived);button4.Text = "关闭串口";hintrtx.Text += "\n串口已经打开";}}catch (Exception ex){MessageBox.Show(ex.Message);hintrtx.Text += "\n串口打开失败";}}

串口接收事件:

这里主要是做了一个串口的错误处理和调用界面元素显示的方法。从不是创建这个元素的线程调用改变元素的方法需要使用invoke。

//串口接收事件private void _serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e){//串口接收事件try{//串口接收数据//if(serialPort1.IsOpen){this.Invoke(new EventHandler(displaytext));}}catch (Exception ex){//捕获到异常,创建一个新的对象,之前的不可以再用_serialPort = new System.IO.Ports.SerialPort();//刷新COM口选项comboBox1.Items.Clear();comboBox1.Items.AddRange(System.IO.Ports.SerialPort.GetPortNames());//响铃并显示异常给用户System.Media.SystemSounds.Beep.Play();button4.Text = "打开串口";MessageBox.Show(ex.Message);hintrtx.Text += "\n串口接收失败";comboBox1.Enabled = true;comboBox2.Enabled = true;comboBox3.Enabled = true;comboBox4.Enabled = true;comboBox5.Enabled = true;}}

display方法 

这里就可以写你自己的方法了。串口的数据经过怎么处理展示到哪里。 

private void displaytext(object sender, EventArgs e){string str = _serialPort.ReadExisting();rtxreceive.AppendText(str);}

相关文章:

C#开发记录如何建立虚拟串口,进行串口通信,以及通信模板

记录时间;2024年4月 记录如何开启虚拟串口以及进行基础串口通信。 建立虚拟串口 使用的软件是vspd&#xff0c;建立虚拟串口之后就可以将他们当成实际物理连接的两个串口进行通信。 之后使用我们之前给出的通信模板&#xff0c;建立一个稍微规矩一点的界面。 界面建立 其中…...

电源设计的艺术:从底层逻辑到工程实践

在电子工程的世界里&#xff0c;电源设计是核心中的核心。它不仅是电子设备的能量源泉&#xff0c;更是整个系统稳定运行的基石。随着科技的不断进步&#xff0c;电源设计的要求也越来越高&#xff0c;从效率、稳定性到体积、成本&#xff0c;每一个维度都是工程师们不断追求的…...

软媒市场新探索:软文媒体自助发布,开启自助发稿新篇章

在繁华喧嚣的软媒市场中,每一个声音都在竭力呼喊,每一个品牌都在奋力展现。而软文,作为一种温柔而坚韧的营销力量,正逐渐崭露头角。特别是软文媒体自助发布平台的出现,更是为企业提供了一个全新的、高效的自助发稿渠道。 软媒市场自助发布平台,正如其名,是一个让企业能够自主发…...

【Kubernetes】常见面试题汇总(二十七)

目录 77.假设公司希望在不同的云基础架构上运行各种工作负载&#xff0c;从裸机到公共云。公司将如何在不同界面的存在下实现这一目标&#xff1f; 78.什么是 Google 容器引擎&#xff1f; 特别说明&#xff1a; 题目 1-68 属于【Kubernetes】的常规概念题。 题目 69-1…...

基于单片机巡迹避障智能小车系统

文章目录 前言资料获取设计介绍设计程序具体实现截图设计获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师&#xff0c;一名热衷于单片机技术探索与分享的博主、专注于 精通51/STM32/MSP430/AVR等单片机设计 主要对象是咱们…...

Python163邮箱发送:提升发送效率的技巧?

python163邮箱发送邮件教程&#xff1f;python怎么使用163邮箱&#xff1f; Python163邮箱发送作为一种自动化邮件发送方式&#xff0c;越来越受到开发者和企业的青睐。AokSend将探讨如何通过多种技巧提升Python163邮箱发送的效率&#xff0c;从而更好地满足用户需求。 Pytho…...

springboot中的异步任务

在springboot项目中可以通过EnableAsyncAsync的方式简化异步操作&#xff0c;下文使用springboot:3.2.1 源码分析 若一个bean中的公共方法上标注了Async&#xff0c;在系统启动时&#xff0c;会给这个类创建一个代理对象&#xff0c;并将该代理对象作为bean注册到spring容器中 …...

Linux学习笔记8 理解Ubuntu网络管理,做自己网络的主人

本文讲解了Ubuntu下网络由什么管理&#xff0c;介绍了临时ip和路由的设置方法&#xff0c;介绍了静态持久化网络配置的方法以及各网络管理软件之间的关系。 来看看Ubuntu网络管理。 序言 原本学习ubuntu网络管理就是为了检查nginx安装过程中使用wget获取压缩包为什么解析不出…...

理解线程的三大特性:原子性、可见性和有序性

在并发编程中&#xff0c;保护线程安全是一个重要课题。要实现线程安全&#xff0c;我们必须理解并掌握三个核心概念&#xff1a;原子性、可见性和有序性。下面将详细介绍这三个特性及其解决方案。 一、原子性 原子性是指一个操作要么全部完成&#xff0c;要么完全不执行。在多…...

英特尔®以太网网络适配器E810-CQDA1 / E810-CQDA2 网卡 规格书 e810 网卡 规格书 Intel100G E810 网卡 白皮书

英特尔以太网800系列网络适配器 英特尔以太网网络适配器E810-CQDA1 / CQDA2 在10到100Gbps的以太网速度下实现高效的工作负载优化性能 关键特性 •单、双端口QSFP28 •应用设备队列(ADQ) •PCI Express (PCIe) 4.0 x16 •动态设备个性化(DDP) •以太网端口配置工具(EPC…...

好用的idea方法分隔符插件

好用的idea方法分隔符插件...

通过 Xshell 无法连接到 Ubuntu

无法通过 Xshell 连接到 Ubuntu 服务器&#xff0c;通常与 SSH 服务、网络连接、主机防火墙设置问题有关。以下是排查并解决这个问题的步骤&#xff1a; 1. 确保 SSH 服务正在运行 在 Ubuntu 上&#xff0c;SSH 服务必须启动才能连接。如果你有虚拟机或物理机的访问权限&…...

Java面试篇基础部分-Synchronized关键字详解

Synchronized关键字用于对Java对象、方法、代码块等提供线程安全操作。Synchronized属于独占式的悲观锁机制,同时也是可重入锁。我们在使用Synchronized关键字的时候,可以保证同一时刻只有一个线程对该对象进行访问;也就是说它在同一个JVM中是线程安全的。   Java中的每个…...

数据结构之线性表——LeetCode:67. 二进制求和,27. 移除元素,26. 删除有序数组中的重复项

67. 二进制求和 题目描述 67. 二进制求和 给你两个二进制字符串 a 和 b &#xff0c;以二进制字符串的形式返回它们的和。 运行代码&#xff08;javaC) class Solution {public String addBinary(String a, String b) {StringBuilder ansnew StringBuilder();int ca0;for(i…...

SQL_HAVING小例子

例一 求众数的sql语句1&#xff1a; select income,count(*) as cnt from graduates group by income having count(*) > all(select count(*) from graduates group by income);这段SQL语句的作用是从一个名为graduates的表中找出income&#xff08;收入&#xff09;字段…...

Avalonia第三方UI库Semi.Avalonia用法详解

文章目录 简介一、安装Semi Avalonia二、基本项目结构三、使用基本控件1 按钮控件2 输入框控件3 选择框控件四、自定义样式和主题五、使用布局控件六、数据绑定七、事件处理八、使用图标和其他资源九、响应式设计十、交互与导航总结简介 Semi是一个基于Avalonia的UI库,旨在提供…...

宠物智能化听诊器的健康管理!

智能听诊器在宠物健康领域的应用正逐渐普及&#xff0c;它通过创新技术为宠物医疗保健带来革新。以下是智能听诊器如何影响宠物健康管理的概述&#xff1a; 数据分析与机器学习 智能听诊器利用深度学习算法&#xff0c;识别宠物心脏和呼吸模式&#xff0c;提供健康分析和诊断建…...

MyBatis-Plus 实体类注解

MyBatis-Plus 实体类注解详解 MyBatis-Plus 是 MyBatis 的增强版&#xff0c;旨在简化开发者的 CRUD 操作。它通过丰富的特性和注解&#xff0c;简化了数据库与 Java 实体类之间的映射。MyBatis-Plus 提供了一系列的实体类注解&#xff0c;帮助开发者更轻松地映射数据库表、字…...

如何写一个自动化Linux脚本去进行等保测试--引言

#我的师兄喜欢给我的休闲实习生活加活&#xff0c;说是让我在实习期间写一个自动化脚本去进行等保测试。呵呵哒。 怎么办呢&#xff0c;师兄的指令得完成&#xff0c;师兄说让我使用Python完成任务。 设想如下&#xff1a; 1、将Linux指令嵌入到python脚本中 2、调试跑通 …...

美团测开OC!

大家好&#xff0c;我是洋子&#xff0c;最近测试社区里面的一个25届同学参加秋招&#xff0c;已经拿到美团测开offer&#xff0c;今天来分享一下他的求职经历&#xff0c;文末附面经 他求职目前的进展如下&#xff1a; 互联网大厂&#xff1a;字节&#xff0c;阿里&#xff…...

网络六边形受到攻击

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 抽象 现代智能交通系统 &#xff08;ITS&#xff09; 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 &#xff08;…...

Java 语言特性(面试系列2)

一、SQL 基础 1. 复杂查询 &#xff08;1&#xff09;连接查询&#xff08;JOIN&#xff09; 内连接&#xff08;INNER JOIN&#xff09;&#xff1a;返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序

一、开发环境准备 ​​工具安装​​&#xff1a; 下载安装DevEco Studio 4.0&#xff08;支持HarmonyOS 5&#xff09;配置HarmonyOS SDK 5.0确保Node.js版本≥14 ​​项目初始化​​&#xff1a; ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

laravel8+vue3.0+element-plus搭建方法

创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...

Linux nano命令的基本使用

参考资料 GNU nanoを使いこなすnano基础 目录 一. 简介二. 文件打开2.1 普通方式打开文件2.2 只读方式打开文件 三. 文件查看3.1 打开文件时&#xff0c;显示行号3.2 翻页查看 四. 文件编辑4.1 Ctrl K 复制 和 Ctrl U 粘贴4.2 Alt/Esc U 撤回 五. 文件保存与退出5.1 Ctrl …...

iview框架主题色的应用

1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题&#xff0c;无需引入&#xff0c;直接可…...

深入理解Optional:处理空指针异常

1. 使用Optional处理可能为空的集合 在Java开发中&#xff0c;集合判空是一个常见但容易出错的场景。传统方式虽然可行&#xff0c;但存在一些潜在问题&#xff1a; // 传统判空方式 if (!CollectionUtils.isEmpty(userInfoList)) {for (UserInfo userInfo : userInfoList) {…...

深度学习之模型压缩三驾马车:模型剪枝、模型量化、知识蒸馏

一、引言 在深度学习中&#xff0c;我们训练出的神经网络往往非常庞大&#xff08;比如像 ResNet、YOLOv8、Vision Transformer&#xff09;&#xff0c;虽然精度很高&#xff0c;但“太重”了&#xff0c;运行起来很慢&#xff0c;占用内存大&#xff0c;不适合部署到手机、摄…...

Visual Studio Code 扩展

Visual Studio Code 扩展 change-case 大小写转换EmmyLua for VSCode 调试插件Bookmarks 书签 change-case 大小写转换 https://marketplace.visualstudio.com/items?itemNamewmaurer.change-case 选中单词后&#xff0c;命令 changeCase.commands 可预览转换效果 EmmyLua…...

sshd代码修改banner

sshd服务连接之后会收到字符串&#xff1a; SSH-2.0-OpenSSH_9.5 容易被hacker识别此服务为sshd服务。 是否可以通过修改此banner达到让人无法识别此服务的目的呢&#xff1f; 不能。因为这是写的SSH的协议中的。 也就是协议规定了banner必须这么写。 SSH- 开头&#xff0c…...