Winform串口编程---接收数据demo(VSPD虚拟串口)
参考地址:https://blog.csdn.net/memgxingfeixiang/article/details/52513970
https://blog.csdn.net/kevin_iot/article/details/53926599
一、需求概述
应用场景:winform中能接收到串口发送的数据。
所需软件: Configure Virtual Serial Port Driver(虚拟串口模拟软件)、串口调试助手。
二、效果展示(很简陋,捂脸中......)

说明:cmbPort是电脑上所有串口的列表,txtReciveData是每次该串口接收的数据,btnOpenOrClose按钮是控制打开/关闭串口。
三、具体实现:
(1)先在Load事件里将comPort控件绑定电脑串口列表,代码如下:
#region 初始化电脑上的串口列表
foreach (string sPort in SerialPort.GetPortNames())
{
cmbPort.Items.Add(sPort);
} //串口设置默认选项
if (cmbPort.Items.Count>)
{
cmbPort.SelectedIndex = ;
}
#endregion
(2)编写btnOpenOrClose点击事件
/// <summary>
/// 打开/关闭串口
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnOpenOrClose_Click(object sender, EventArgs e)
{
try
{
if (btnOpenOrClose.Text == "打开串口")
{
btnOpenOrClose.Text = "关闭串口";
//设置串口的基本属性
serialPort.PortName = cmbPort.SelectedItem.ToString();
serialPort.BaudRate = ;
serialPort.Parity = Parity.None;
serialPort.DataBits = ;
serialPort.StopBits = StopBits.One;
serialPort.Open();
}
else
{
btnOpenOrClose.Text = "打开串口";
serialPort.Close();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "错误提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
}
(3)编写接收串口数据方法
void Comm_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
try
{
Byte[] InputBuf = new Byte[];
serialPort.Read(InputBuf, , serialPort.BytesToRead); ASCIIEncoding encoding = new ASCIIEncoding();
data = encoding.GetString(InputBuf);
new Thread(SetReceiveData).Start();
//直接调用会报错-------从不是创建控件”txtContent”的线程访问它
//SetReceiveData();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "错误提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
}
接收数据成功,调用下面的方法,将发送的数据显示到文本框中。
/// <summary>
/// (将接收的数据显示到文本框中)不懂这一块的实现逻辑,需要加深理解线程的相关概念
/// </summary>
public void SetReceiveData()
{
lock (this) Invoke(new MethodInvoker(delegate () { this.txtReciveData.Text = data; })); }
在load事件中将订阅该事件
//为串口加上数据接收事件
serialPort.DataReceived += new SerialDataReceivedEventHandler(Comm_DataReceived);
四:模拟串口发送数据
(1)打开vspd软件,虚拟出两个COM1和COM2两个串口

(2)打开串口调试助手,一个是COM1,另外一个是COM2,将两个串口的波特率设置为一样。

测试一下,两个串口是否能正常通讯。

(3)关掉其中的一个串口调试助手,留下COM2的串口调试助手,我们在程序中用COM1口接收数据。(winform中要先点击“打开串口”按钮)

五、完整代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Ports;
using System.Threading; namespace ComDataTest
{
public partial class ComData : Form
{
private SerialPort serialPort=new SerialPort();
string data = string.Empty;
public ComData()
{
InitializeComponent();
} private void ComData_Load(object sender, EventArgs e)
{
#region 初始化电脑上的串口列表
foreach (string sPort in SerialPort.GetPortNames())
{
cmbPort.Items.Add(sPort);
} //串口设置默认选项
if (cmbPort.Items.Count>)
{
cmbPort.SelectedIndex = ;
}
#endregion //为串口加上数据接收事件
serialPort.DataReceived += new SerialDataReceivedEventHandler(Comm_DataReceived);
} /// <summary>
/// 打开/关闭串口
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnOpenOrClose_Click(object sender, EventArgs e)
{
try
{
if (btnOpenOrClose.Text == "打开串口")
{
btnOpenOrClose.Text = "关闭串口";
//设置串口的基本属性
serialPort.PortName = cmbPort.SelectedItem.ToString();
serialPort.BaudRate = ;
serialPort.Parity = Parity.None;
serialPort.DataBits = ;
serialPort.StopBits = StopBits.One;
serialPort.Open();
}
else
{
btnOpenOrClose.Text = "打开串口";
serialPort.Close();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "错误提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
} /// <summary>
/// (将接收的数据显示到文本框中)不懂这一块的实现逻辑,需要加深理解线程的相关概念
/// </summary>
public void SetReceiveData()
{
lock (this) Invoke(new MethodInvoker(delegate () { this.txtReciveData.Text = data; })); } void Comm_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
try
{
Byte[] InputBuf = new Byte[];
serialPort.Read(InputBuf, , serialPort.BytesToRead); ASCIIEncoding encoding = new ASCIIEncoding();
data = encoding.GetString(InputBuf);
new Thread(SetReceiveData).Start();
//直接调用会报错-------从不是创建控件”txtContent”的线程访问它
//SetReceiveData();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "错误提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
}
}
}
六、写在后面的话:
初次接触串口编程,作为码农多年,确实有些汗颜。从最初下载vspd和串口调试软件,根本不知如何用,到慢慢的了解一些,会简单的一些操作,着实也费了一点时间。目前对于串口编程,还是有一些云里雾里,似乎缺少一根主线把他们串起来一般,还是需要再进行摸索和探究,继续加油~
Winform串口编程---接收数据demo(VSPD虚拟串口)的更多相关文章
- Qt串口通信接收数据不完整的解决方法
在使用串口接收数据时,当数据量大的时候会出现数据接收不完整的情况.因为串口数据获取函数readAll()由readyRead()信号触发,但readyRead()信号在串口读到起始标志时立即发送,并不 ...
- Qt串口通信接收数据不完整的解决方法(传输图片)
在使用串口接收数据时,当数据量大的时候会出现数据接收不完整的情况.因为串口数据获取函数readAll()由readyRead()信号触发,但readyRead()信号在串口读到起始标志时立即发送,并不 ...
- c# 串口发送接收数据
/********************** 串口数据接收事件 *****************************/ private void SerialPort_DataReceived ...
- Linux/windows com串口 java 接收数据 并解析 web程序
1.首先应公司要求再 com 口本来使用 .net 由于 .net 适用 linux 太麻烦 改为java 准备工作 准备 RXTXconmm.jar(版本很重要) 因为版本问题我搞了一天. 主要讲述 ...
- <QT障碍之路>qt中使用串口类接收数据不完整
问题:当用QT中的serial->readAll()的时候,不会把全部的数据一次性都读取出来,而是阶段性的.原因是因为当串口有信号时候,readyRead()信号就会被抛出,那么一帧完整的数据帧 ...
- STM32串口DMA接收数据错位——暴力解决方法
背景:两片STM32通过串口通信,为了减小CPU负担,采用DMA进行通信,发送端为STM32F103C8T6,接收端为STM32F407VET6.在调试的过程中发现,一直出现数据错位的问题,接收端尝试 ...
- 【转】虚拟串口VSPM解决串口编程问题
通过串口调试软件 UartAssist.exe 和虚拟串口软件 VSPM,可以解决串口编程时没用硬件调试的问题,通过VSPM虚拟出串口设备,让程序发送信息到 VSPM 设备后通过 UartAssist ...
- STM32之串口DMA接收不定长数据
STM32之串口DMA接收不定长数据 引言 在使用stm32或者其他单片机的时候,会经常使用到串口通讯,那么如何有效地接收数据呢?假如这段数据是不定长的有如何高效接收呢? 同学A:数据来了就会进入串口 ...
- C#串口编程测试收发
原文:http://www.cnblogs.com/vsdot/archive/2013/04/23/3263348.html 基本传递方法:RS232传输要有1位起始位,8位数据位.1位校验位( ...
随机推荐
- 《linux就该这么学》课堂笔记17 分离解析、DHCP、电子邮件系统
1.动态主机配置协议(DHCP,Dynamic Host Configuration Protocol) 自动管理局域网内主机的IP地址.子网掩码.网关地址及DNS地址等参数,可以有效地提升IP地址的 ...
- Redis开启远程访问及密码
一.开启远程访问 1.开放端口 firewall-cmd --zone=public --add-port=6379 firewall-cmd --zone=public --add-port=637 ...
- Ubuntu 出现access denied by server while mounting
3516cv500板端nfst调试时如此配置 虚拟机: #vi /etc/exports 添加 /home/"待分享文件路径" *(rw,sync,no_root_squas ...
- mdk编译器学习笔记(1)——序
这两天,学习了keil-mdk编译器的特性,这基本上独立于c语言语法,平时基本上都在强调c语言的学习,但是编译器的学习我们也要注重,类似于gcc一样,不也有很多网上的资料,讲述gcc的特性和用法吗.作 ...
- java spring框架的定时任务
由于测试的原因,最近有接触java spring @Scheduled的定时任务,当时还以为配置起来表达式和crontab是完全一样的,没想到还有些许不一样. 在spring中,一个cron表达式至 ...
- Rotor里的异常处理
我看到了一些关于Rotor(和CLR)中使用的异常处理机制的问题.下面是关于Rotor异常处理的另一个注意事项列表.目的是帮助Rotor开发人员调试和理解CLR中的异常. 异常生成和抛出 此步骤在很大 ...
- tornado表单和模板
模板渲染,指定模板路径: app = tornado.web.Application( handlers=[(r'/my', Myrequest),('/myweb',MywebRequest)], ...
- 阿里云物联网平台: Android 连接阿里云物联网平台
说明 这节是是为下一节做铺垫的 只要是按照我提供的学习路线一节一节的认认真真学过来的,这节就十分的简单 有了前两节的基础,这节呢咱让Android 连接阿里云物联网平台 使用这节的代码 https: ...
- localStorage二次封装-----设置过期时间
export default{ set(key,data,time){ let obj={ data=data, ctime:(new Date()).getTime(),//时间戳,同Date.no ...
- 【LG3322】[SDOI2015]排序
[LG3322][SDOI2015]排序 题面 洛谷 题解 交换顺序显然不影响答案,所以每种本质不同的方案就给答案贡献次数的阶乘. 从小往大的交换每次至多\(4\)中决策,复杂度\(O(4^n)\). ...